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