parseFilter parses a path filter contained within [brackets].
(path string)
| 316 | |
| 317 | // parseFilter parses a path filter contained within [brackets]. |
| 318 | func (c *compiler) parseFilter(path string) filter { |
| 319 | if len(path) == 0 { |
| 320 | c.err = ErrPath("path contains an empty filter expression.") |
| 321 | return nil |
| 322 | } |
| 323 | |
| 324 | // Filter contains [@attr='val'], [@attr="val"], [fn()='val'], |
| 325 | // [fn()="val"], [tag='val'] or [tag="val"]? |
| 326 | eqindex := strings.IndexByte(path, '=') |
| 327 | if eqindex == 0 { |
| 328 | c.err = ErrPath("path contains a filter expression with no key.") |
| 329 | return nil |
| 330 | } |
| 331 | if eqindex > 0 && eqindex+1 < len(path) { |
| 332 | quote := path[eqindex+1] |
| 333 | if quote == '\'' || quote == '"' { |
| 334 | rindex := nextIndex(path, quote, eqindex+2) |
| 335 | if rindex != len(path)-1 { |
| 336 | c.err = ErrPath("path has mismatched filter quotes.") |
| 337 | return nil |
| 338 | } |
| 339 | |
| 340 | key := path[:eqindex] |
| 341 | value := path[eqindex+2 : rindex] |
| 342 | |
| 343 | switch { |
| 344 | case key[0] == '@': |
| 345 | if len(key) == 1 { |
| 346 | c.err = ErrPath("path contains a filter expression with no key.") |
| 347 | return nil |
| 348 | } |
| 349 | return newFilterAttrVal(key[1:], value) |
| 350 | case strings.HasSuffix(key, "()"): |
| 351 | name := key[:len(key)-2] |
| 352 | if fn, ok := fnTable[name]; ok { |
| 353 | return newFilterFuncVal(fn, value) |
| 354 | } |
| 355 | c.err = ErrPath("path has unknown function " + name) |
| 356 | return nil |
| 357 | default: |
| 358 | return newFilterChildText(key, value) |
| 359 | } |
| 360 | } |
| 361 | } |
| 362 | |
| 363 | // Filter contains [@attr], [N], [tag] or [fn()] |
| 364 | switch { |
| 365 | case path[0] == '@': |
| 366 | return newFilterAttr(path[1:]) |
| 367 | case strings.HasSuffix(path, "()"): |
| 368 | name := path[:len(path)-2] |
| 369 | if fn, ok := fnTable[name]; ok { |
| 370 | return newFilterFunc(fn) |
| 371 | } |
| 372 | c.err = ErrPath("path has unknown function " + name) |
| 373 | return nil |
| 374 | case isInteger(path): |
| 375 | pos, _ := strconv.Atoi(path) |
no test coverage detected