parseArgs parses a collection of comma-separated arguments into an Args struct.
(line []byte)
| 838 | // parseArgs parses a collection of comma-separated arguments into an Args |
| 839 | // struct. |
| 840 | func parseArgs(line []byte) (Args, error) { |
| 841 | const maxDepth = 6 // 5 from traceback.go, +1 for top level |
| 842 | var stack [maxDepth]*Args |
| 843 | var args Args |
| 844 | depth := 0 |
| 845 | stack[depth] = &args |
| 846 | for _, s := range bytes.Split(line, commaSpace) { |
| 847 | opened, a, closed := trimCurlyBrackets(s) |
| 848 | for i := 0; i < opened; i++ { |
| 849 | cur := stack[depth] |
| 850 | cur.Values = append(cur.Values, Arg{}) |
| 851 | next := &cur.Values[len(cur.Values)-1] |
| 852 | next.IsAggregate = true |
| 853 | depth++ |
| 854 | if depth >= maxDepth { |
| 855 | return Args{}, fmt.Errorf("nested aggregate-typed arguments exceeded depth limit") |
| 856 | } |
| 857 | stack[depth] = &next.Fields |
| 858 | } |
| 859 | if len(a) > 0 { |
| 860 | cur := stack[depth] |
| 861 | switch { |
| 862 | case bytes.Equal(a, threeDots): |
| 863 | cur.Elided = true |
| 864 | case bytes.Equal(a, underscore): |
| 865 | arg := Arg{IsOffsetTooLarge: true} |
| 866 | cur.Values = append(cur.Values, arg) |
| 867 | default: |
| 868 | inaccurate := bytes.HasSuffix(a, inaccurateQuestionMark) |
| 869 | if inaccurate { |
| 870 | a = a[:len(a)-len(inaccurateQuestionMark)] |
| 871 | } |
| 872 | |
| 873 | v, err := strconv.ParseUint(unsafeString(a), 0, 64) |
| 874 | if err != nil { |
| 875 | return Args{}, errors.New("failed to parse int") |
| 876 | } |
| 877 | // Assume the stack was generated with the same bitness (32 vs 64) as |
| 878 | // the code processing it. |
| 879 | arg := Arg{Value: v, IsPtr: v > pointerFloor && v < pointerCeiling, IsInaccurate: inaccurate} |
| 880 | cur.Values = append(cur.Values, arg) |
| 881 | } |
| 882 | } |
| 883 | for i := 0; i < closed; i++ { |
| 884 | stack[depth] = nil |
| 885 | depth-- |
| 886 | if depth < 0 { |
| 887 | return Args{}, errors.New("unmatched closing curly bracket") |
| 888 | } |
| 889 | } |
| 890 | } |
| 891 | if depth != 0 { |
| 892 | return Args{}, errors.New("unmatched opening curly bracket") |
| 893 | } |
| 894 | return args, nil |
| 895 | } |
| 896 | |
| 897 | // parseFile only return an error if also processing a Call. |
no test coverage detected
searching dependent graphs…