1 /*
2 * Copyright (C) 2011 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 #include <stdio.h>
17 #include <stdlib.h>
18 #include "errors.h"
19 #include "EntryPoint.h"
20 #include "strUtils.h"
21 #include "ApiGen.h"
22 #include "TypeFactory.h"
23
24 const std::string SPEC_EXTENSION = std::string(".in");
25 const std::string ATTRIB_EXTENSION = std::string(".attrib");
26 const std::string TYPES_EXTENTION = std::string(".types");
27
28
usage(const char * filename)29 void usage(const char *filename)
30 {
31 fprintf(stderr, "Usage: %s [options] <base name>\n", filename);
32 fprintf(stderr, "\t-h: This message\n");
33 fprintf(stderr, "\t-E <dir>: generate encoder into dir\n");
34 fprintf(stderr, "\t-D <dir>: generate decoder into dir\n");
35 fprintf(stderr, "\t-i: input dir, local directory by default\n");
36 fprintf(stderr, "\t-T : generate attribute template into the input directory\n\t\tno other files are generated\n");
37 fprintf(stderr, "\t-W : generate wrapper into dir\n");
38 }
39
main(int argc,char * argv[])40 int main(int argc, char *argv[])
41 {
42 std::string encoderDir = "";
43 std::string decoderDir = "";
44 std::string wrapperDir = "";
45 std::string inDir = ".";
46 bool generateAttributesTemplate = false;
47
48 int c;
49 while((c = getopt(argc, argv, "TE:D:i:hW:")) != -1) {
50 switch(c) {
51 case 'W':
52 wrapperDir = std::string(optarg);
53 break;
54 case 'T':
55 generateAttributesTemplate = true;
56 break;
57 case 'h':
58 usage(argv[0]);
59 exit(0);
60 break;
61 case 'E':
62 encoderDir = std::string(optarg);
63 break;
64 case 'D':
65 decoderDir = std::string(optarg);
66 break;
67 case 'i':
68 inDir = std::string(optarg);
69 break;
70 case ':':
71 fprintf(stderr, "Missing argument !!\n");
72 // fall through
73 default:
74 usage(argv[0]);
75 exit(0);
76 }
77 }
78
79 if (optind >= argc) {
80 fprintf(stderr, "Usage: %s [options] <base name> \n", argv[0]);
81 return BAD_USAGE;
82 }
83
84 if (encoderDir.size() == 0 &&
85 decoderDir.size() == 0 &&
86 generateAttributesTemplate == false &&
87 wrapperDir.size() == 0) {
88 fprintf(stderr, "No output specified - aborting\n");
89 return BAD_USAGE;
90 }
91
92 std::string baseName = std::string(argv[optind]);
93 ApiGen apiEntries(baseName);
94
95 // init types;
96 std::string typesFilename = inDir + "/" + baseName + TYPES_EXTENTION;
97
98 if (TypeFactory::instance()->initFromFile(typesFilename) < 0) {
99 fprintf(stderr, "missing or error reading types file: %s...ignored\n", typesFilename.c_str());
100 }
101
102 std::string filename = inDir + "/" + baseName + SPEC_EXTENSION;
103 if (apiEntries.readSpec(filename) < 0) {
104 perror(filename.c_str());
105 return BAD_SPEC_FILE;
106 }
107
108
109 if (generateAttributesTemplate) {
110 apiEntries.genAttributesTemplate(inDir + "/" + baseName + ATTRIB_EXTENSION);
111 exit(0);
112 }
113
114 std::string attribFileName = inDir + "/" + baseName + ATTRIB_EXTENSION;
115 if (apiEntries.readAttributes(attribFileName) < 0) {
116 perror(attribFileName.c_str());
117 fprintf(stderr, "failed to parse attributes\n");
118 exit(1);
119 }
120
121 if (encoderDir.size() != 0) {
122
123 apiEntries.genOpcodes(encoderDir + "/" + baseName + "_opcodes.h");
124 apiEntries.genContext(encoderDir + "/" + baseName + "_client_context.h", ApiGen::CLIENT_SIDE);
125 apiEntries.genContextImpl(encoderDir + "/" + baseName + "_client_context.cpp", ApiGen::CLIENT_SIDE);
126
127 apiEntries.genProcTypes(encoderDir + "/" + baseName + "_client_proc.h", ApiGen::CLIENT_SIDE);
128 apiEntries.genFuncTable(encoderDir + "/" + baseName + "_ftable.h", ApiGen::CLIENT_SIDE);
129
130 apiEntries.genEntryPoints(encoderDir + "/" + baseName + "_entry.cpp", ApiGen::CLIENT_SIDE);
131 apiEntries.genEncoderHeader(encoderDir + "/" + baseName + "_enc.h");
132 apiEntries.genEncoderImpl(encoderDir + "/" + baseName + "_enc.cpp");
133 }
134
135 if (decoderDir.size() != 0) {
136 apiEntries.genOpcodes(decoderDir + "/" + baseName + "_opcodes.h");
137 apiEntries.genProcTypes(decoderDir + "/" + baseName + "_server_proc.h", ApiGen::SERVER_SIDE);
138 apiEntries.genContext(decoderDir + "/" + baseName + "_server_context.h", ApiGen::SERVER_SIDE);
139 apiEntries.genContextImpl(decoderDir + "/" + baseName + "_server_context.cpp", ApiGen::SERVER_SIDE);
140 apiEntries.genDecoderHeader(decoderDir + "/" + baseName + "_dec.h");
141 apiEntries.genDecoderImpl(decoderDir + "/" + baseName + "_dec.cpp");
142 }
143
144 if (wrapperDir.size() != 0) {
145 apiEntries.genProcTypes(wrapperDir + "/" + baseName + "_wrapper_proc.h", ApiGen::WRAPPER_SIDE);
146 apiEntries.genContext(wrapperDir + "/" + baseName + "_wrapper_context.h", ApiGen::WRAPPER_SIDE);
147 apiEntries.genContextImpl(wrapperDir + "/" + baseName + "_wrapper_context.cpp", ApiGen::WRAPPER_SIDE);
148 apiEntries.genEntryPoints(wrapperDir + "/" + baseName + "_wrapper_entry.cpp", ApiGen::WRAPPER_SIDE);
149 }
150
151 #ifdef DEBUG_DUMP
152 int withPointers = 0;
153 printf("%d functions found\n", int(apiEntries.size()));
154 for (int i = 0; i < apiEntries.size(); i++) {
155 if (apiEntries[i].hasPointers()) {
156 withPointers++;
157 apiEntries[i].print();
158 }
159 }
160 fprintf(stdout, "%d entries has poitners\n", withPointers);
161 #endif
162
163 }
164
165