vendor/github.com/pelletier/go-toml/parser.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
child 256 6d9efbef00a9
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
    75 		return p.parseGroup
    75 		return p.parseGroup
    76 	case tokenKey:
    76 	case tokenKey:
    77 		return p.parseAssign
    77 		return p.parseAssign
    78 	case tokenEOF:
    78 	case tokenEOF:
    79 		return nil
    79 		return nil
       
    80 	case tokenError:
       
    81 		p.raiseError(tok, "parsing error: %s", tok.String())
    80 	default:
    82 	default:
    81 		p.raiseError(tok, "unexpected token")
    83 		p.raiseError(tok, "unexpected token %s", tok.typ)
    82 	}
    84 	}
    83 	return nil
    85 	return nil
    84 }
    86 }
    85 
    87 
    86 func (p *tomlParser) parseGroupArray() tomlParserStateFn {
    88 func (p *tomlParser) parseGroupArray() tomlParserStateFn {
   163 
   165 
   164 func (p *tomlParser) parseAssign() tomlParserStateFn {
   166 func (p *tomlParser) parseAssign() tomlParserStateFn {
   165 	key := p.getToken()
   167 	key := p.getToken()
   166 	p.assume(tokenEqual)
   168 	p.assume(tokenEqual)
   167 
   169 
       
   170 	parsedKey, err := parseKey(key.val)
       
   171 	if err != nil {
       
   172 		p.raiseError(key, "invalid key: %s", err.Error())
       
   173 	}
       
   174 
   168 	value := p.parseRvalue()
   175 	value := p.parseRvalue()
   169 	var tableKey []string
   176 	var tableKey []string
   170 	if len(p.currentTable) > 0 {
   177 	if len(p.currentTable) > 0 {
   171 		tableKey = p.currentTable
   178 		tableKey = p.currentTable
   172 	} else {
   179 	} else {
   173 		tableKey = []string{}
   180 		tableKey = []string{}
   174 	}
   181 	}
       
   182 
       
   183 	prefixKey := parsedKey[0 : len(parsedKey)-1]
       
   184 	tableKey = append(tableKey, prefixKey...)
   175 
   185 
   176 	// find the table to assign, looking out for arrays of tables
   186 	// find the table to assign, looking out for arrays of tables
   177 	var targetNode *Tree
   187 	var targetNode *Tree
   178 	switch node := p.tree.GetPath(tableKey).(type) {
   188 	switch node := p.tree.GetPath(tableKey).(type) {
   179 	case []*Tree:
   189 	case []*Tree:
   180 		targetNode = node[len(node)-1]
   190 		targetNode = node[len(node)-1]
   181 	case *Tree:
   191 	case *Tree:
   182 		targetNode = node
   192 		targetNode = node
       
   193 	case nil:
       
   194 		// create intermediate
       
   195 		if err := p.tree.createSubTree(tableKey, key.Position); err != nil {
       
   196 			p.raiseError(key, "could not create intermediate group: %s", err)
       
   197 		}
       
   198 		targetNode = p.tree.GetPath(tableKey).(*Tree)
   183 	default:
   199 	default:
   184 		p.raiseError(key, "Unknown table type for path: %s",
   200 		p.raiseError(key, "Unknown table type for path: %s",
   185 			strings.Join(tableKey, "."))
   201 			strings.Join(tableKey, "."))
   186 	}
   202 	}
   187 
   203 
   188 	// assign value to the found table
   204 	// assign value to the found table
   189 	keyVals := []string{key.val}
   205 	keyVal := parsedKey[len(parsedKey)-1]
   190 	if len(keyVals) != 1 {
       
   191 		p.raiseError(key, "Invalid key")
       
   192 	}
       
   193 	keyVal := keyVals[0]
       
   194 	localKey := []string{keyVal}
   206 	localKey := []string{keyVal}
   195 	finalKey := append(tableKey, keyVal)
   207 	finalKey := append(tableKey, keyVal)
   196 	if targetNode.GetPath(localKey) != nil {
   208 	if targetNode.GetPath(localKey) != nil {
   197 		p.raiseError(key, "The following key was defined twice: %s",
   209 		p.raiseError(key, "The following key was defined twice: %s",
   198 			strings.Join(finalKey, "."))
   210 			strings.Join(finalKey, "."))
   299 		if err != nil {
   311 		if err != nil {
   300 			p.raiseError(tok, "%s", err)
   312 			p.raiseError(tok, "%s", err)
   301 		}
   313 		}
   302 		return val
   314 		return val
   303 	case tokenDate:
   315 	case tokenDate:
   304 		val, err := time.ParseInLocation(time.RFC3339Nano, tok.val, time.UTC)
   316 		layout := time.RFC3339Nano
       
   317 		if !strings.Contains(tok.val, "T") {
       
   318 			layout = strings.Replace(layout, "T", " ", 1)
       
   319 		}
       
   320 		val, err := time.ParseInLocation(layout, tok.val, time.UTC)
       
   321 		if err != nil {
       
   322 			p.raiseError(tok, "%s", err)
       
   323 		}
       
   324 		return val
       
   325 	case tokenLocalDate:
       
   326 		v := strings.Replace(tok.val, " ", "T", -1)
       
   327 		isDateTime := false
       
   328 		isTime := false
       
   329 		for _, c := range v {
       
   330 			if c == 'T' || c == 't' {
       
   331 				isDateTime = true
       
   332 				break
       
   333 			}
       
   334 			if c == ':' {
       
   335 				isTime = true
       
   336 				break
       
   337 			}
       
   338 		}
       
   339 
       
   340 		var val interface{}
       
   341 		var err error
       
   342 
       
   343 		if isDateTime {
       
   344 			val, err = ParseLocalDateTime(v)
       
   345 		} else if isTime {
       
   346 			val, err = ParseLocalTime(v)
       
   347 		} else {
       
   348 			val, err = ParseLocalDate(v)
       
   349 		}
       
   350 
   305 		if err != nil {
   351 		if err != nil {
   306 			p.raiseError(tok, "%s", err)
   352 			p.raiseError(tok, "%s", err)
   307 		}
   353 		}
   308 		return val
   354 		return val
   309 	case tokenLeftBracket:
   355 	case tokenLeftBracket:
   336 		}
   382 		}
   337 		switch follow.typ {
   383 		switch follow.typ {
   338 		case tokenRightCurlyBrace:
   384 		case tokenRightCurlyBrace:
   339 			p.getToken()
   385 			p.getToken()
   340 			break Loop
   386 			break Loop
   341 		case tokenKey:
   387 		case tokenKey, tokenInteger, tokenString:
   342 			if !tokenIsComma(previous) && previous != nil {
   388 			if !tokenIsComma(previous) && previous != nil {
   343 				p.raiseError(follow, "comma expected between fields in inline table")
   389 				p.raiseError(follow, "comma expected between fields in inline table")
   344 			}
   390 			}
   345 			key := p.getToken()
   391 			key := p.getToken()
   346 			p.assume(tokenEqual)
   392 			p.assume(tokenEqual)
       
   393 
       
   394 			parsedKey, err := parseKey(key.val)
       
   395 			if err != nil {
       
   396 				p.raiseError(key, "invalid key: %s", err)
       
   397 			}
       
   398 
   347 			value := p.parseRvalue()
   399 			value := p.parseRvalue()
   348 			tree.Set(key.val, value)
   400 			tree.SetPath(parsedKey, value)
   349 		case tokenComma:
   401 		case tokenComma:
   350 			if previous == nil {
       
   351 				p.raiseError(follow, "inline table cannot start with a comma")
       
   352 			}
       
   353 			if tokenIsComma(previous) {
   402 			if tokenIsComma(previous) {
   354 				p.raiseError(follow, "need field between two commas in inline table")
   403 				p.raiseError(follow, "need field between two commas in inline table")
   355 			}
   404 			}
   356 			p.getToken()
   405 			p.getToken()
   357 		default:
   406 		default: