1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import java.util.*;
18
19public class CFunc {
20
21    String original;
22
23    CType ftype;
24    String fname;
25
26    List<String> argNames = new ArrayList<String>();
27    List<CType> argTypes = new ArrayList<CType>();
28
29    boolean hasPointerArg = false;
30    boolean hasTypedPointerArg = false;
31
32    public CFunc(String original) {
33        this.original = original;
34    }
35
36    public String getOriginal() {
37        return original;
38    }
39
40    public void setName(String fname) {
41        this.fname = fname;
42    }
43
44    public String getName() {
45        return fname;
46    }
47
48    public void setType(CType ftype) {
49        this.ftype = ftype;
50    }
51
52    public CType getType() {
53        return ftype;
54    }
55
56    public void addArgument(String argName, CType argType) {
57        argNames.add(argName);
58        argTypes.add(argType);
59
60        if (argType.isPointer()) {
61            hasPointerArg = true;
62        }
63        if (argType.isTypedPointer()) {
64            hasTypedPointerArg = true;
65        }
66    }
67
68    public int getNumArgs() {
69        return argNames.size();
70    }
71
72    public int getArgIndex(String name) {
73        int len = argNames.size();
74        for (int i = 0; i < len; i++) {
75            if (name.equals(argNames.get(i))) {
76                return i;
77            }
78        }
79        return -1;
80    }
81
82    public String getArgName(int index) {
83        return argNames.get(index);
84    }
85
86    public CType getArgType(int index) {
87        return argTypes.get(index);
88    }
89
90    public boolean hasPointerArg() {
91        return hasPointerArg;
92    }
93
94    public boolean hasTypedPointerArg() {
95        return hasTypedPointerArg;
96    }
97
98    @Override
99    public String toString() {
100        String s =  "Function " + fname + " returns " + ftype + ": ";
101        for (int i = 0; i < argNames.size(); i++) {
102            if (i > 0) {
103                s += ", ";
104            }
105            s += argTypes.get(i) + " " + argNames.get(i);
106        }
107        return s;
108    }
109
110    public static CFunc parseCFunc(String s) {
111        CFunc cfunc = new CFunc(s);
112        String[] tokens = s.split("\\s");
113
114        int i = 0;
115        CType ftype = new CType();
116        String ftypeName = tokens[i++];
117        if (ftypeName.equals("const")) {
118            ftype.setIsConst(true);
119            ftypeName = tokens[i++];
120        }
121        ftype.setBaseType(ftypeName);
122
123        String fname = tokens[i++];
124        if (fname.equals("*")) {
125            ftype.setIsPointer(true);
126            fname = tokens[i++];
127        }
128
129        cfunc.setName(fname);
130        cfunc.setType(ftype);
131
132        while (i < tokens.length) {
133            String tok = tokens[i++];
134
135            if (tok.equals("(")) {
136                continue;
137            }
138            if (tok.equals(")")) {
139                break;
140            }
141
142            CType argType = new CType();
143
144            String argTypeName = tok;
145            String argName = "";
146
147            if (argTypeName.equals("const")) {
148                argType.setIsConst(true);
149                argTypeName = tokens[i++];
150            }
151            argType.setBaseType(argTypeName);
152
153            if (argTypeName.equals("void")) {
154                break;
155            }
156
157            argName = tokens[i++];
158            if (argName.startsWith("*")) {
159                argType.setIsPointer(true);
160                argName = argName.substring(1, argName.length());
161            }
162            if (argName.endsWith(",")) {
163                argName = argName.substring(0, argName.length() - 1);
164            }
165
166            cfunc.addArgument(argName, argType);
167        }
168
169        return cfunc;
170    }
171}
172