Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenspec2def.c
Go to the documentation of this file.
00001 #include <stdio.h> 00002 #include <stdlib.h> 00003 #include <ctype.h> 00004 #include <string.h> 00005 00006 #ifdef _MSC_VER 00007 #define strcasecmp _stricmp 00008 #endif 00009 00010 typedef struct 00011 { 00012 char *pcName; 00013 size_t nNameLength; 00014 char *pcRedirection; 00015 int nRedirectionLength; 00016 int nCallingConvention; 00017 int nOrdinal; 00018 int nStackBytes; 00019 int nArgCount; 00020 int anArgs[30]; 00021 unsigned int uFlags; 00022 int nNumber; 00023 } EXPORT; 00024 00025 enum _ARCH 00026 { 00027 ARCH_X86, 00028 ARCH_AMD64, 00029 ARCH_IA64, 00030 ARCH_ARM, 00031 ARCH_PPC 00032 }; 00033 00034 typedef int (*PFNOUTLINE)(FILE *, EXPORT *); 00035 int gbKillAt = 0; 00036 int gbMSComp = 0; 00037 int gbImportLib = 0; 00038 int no_redirections = 0; 00039 int giArch = ARCH_X86; 00040 char *pszArchString = "i386"; 00041 char *pszArchString2; 00042 char *pszDllName = 0; 00043 char *gpszUnderscore = ""; 00044 00045 enum 00046 { 00047 FL_PRIVATE = 1, 00048 FL_STUB = 2, 00049 FL_NONAME = 4, 00050 }; 00051 00052 enum 00053 { 00054 CC_STDCALL, 00055 CC_CDECL, 00056 CC_FASTCALL, 00057 CC_THISCALL, 00058 CC_EXTERN, 00059 CC_STUB, 00060 }; 00061 00062 enum 00063 { 00064 ARG_LONG, 00065 ARG_PTR, 00066 ARG_STR, 00067 ARG_WSTR, 00068 ARG_DBL, 00069 ARG_INT64, 00070 ARG_FLOAT 00071 }; 00072 00073 char* astrCallingConventions[] = 00074 { 00075 "STDCALL", 00076 "CDECL", 00077 "FASTCALL", 00078 "THISCALL", 00079 "EXTERN" 00080 }; 00081 00082 static 00083 int 00084 IsSeparator(char chr) 00085 { 00086 return ((chr <= ',' && chr != '$') || 00087 (chr >= ':' && chr < '?') ); 00088 } 00089 00090 int 00091 CompareToken(const char *token, const char *comparand) 00092 { 00093 while (*comparand) 00094 { 00095 if (*token != *comparand) return 0; 00096 token++; 00097 comparand++; 00098 } 00099 if (!IsSeparator(*token)) return 0; 00100 return 1; 00101 } 00102 00103 int 00104 ScanToken(const char *token, char chr) 00105 { 00106 while (!IsSeparator(*token)) 00107 { 00108 if (*token++ == chr) return 1; 00109 } 00110 return 0; 00111 } 00112 00113 char * 00114 NextLine(char *pc) 00115 { 00116 while (*pc != 0) 00117 { 00118 if (pc[0] == '\n' && pc[1] == '\r') return pc + 2; 00119 else if (pc[0] == '\n') return pc + 1; 00120 pc++; 00121 } 00122 return pc; 00123 } 00124 00125 int 00126 TokenLength(char *pc) 00127 { 00128 int length = 0; 00129 00130 while (!IsSeparator(*pc++)) length++; 00131 00132 return length; 00133 } 00134 00135 char * 00136 NextToken(char *pc) 00137 { 00138 /* Skip token */ 00139 while (!IsSeparator(*pc)) pc++; 00140 00141 /* Skip white spaces */ 00142 while (*pc == ' ' || *pc == '\t') pc++; 00143 00144 /* Check for end of line */ 00145 if (*pc == '\n' || *pc == '\r' || *pc == 0) return 0; 00146 00147 /* Check for comment */ 00148 if (*pc == '#' || *pc == ';') return 0; 00149 00150 return pc; 00151 } 00152 00153 void 00154 OutputHeader_stub(FILE *file) 00155 { 00156 fprintf(file, "/* This file is autogenerated, do not edit. */\n\n" 00157 "#include <stubs.h>\n\n"); 00158 } 00159 00160 int 00161 OutputLine_stub(FILE *file, EXPORT *pexp) 00162 { 00163 int i; 00164 00165 if (pexp->nCallingConvention != CC_STUB && 00166 (pexp->uFlags & FL_STUB) == 0) return 0; 00167 00168 fprintf(file, "int "); 00169 if ((giArch == ARCH_X86) && 00170 pexp->nCallingConvention == CC_STDCALL) 00171 { 00172 fprintf(file, "__stdcall "); 00173 } 00174 00175 /* Check for C++ */ 00176 if (pexp->pcName[0] == '?') 00177 { 00178 fprintf(file, "stub_function%d(", pexp->nNumber); 00179 } 00180 else 00181 { 00182 fprintf(file, "%.*s(", pexp->nNameLength, pexp->pcName); 00183 } 00184 00185 for (i = 0; i < pexp->nArgCount; i++) 00186 { 00187 if (i != 0) fprintf(file, ", "); 00188 switch (pexp->anArgs[i]) 00189 { 00190 case ARG_LONG: fprintf(file, "long"); break; 00191 case ARG_PTR: fprintf(file, "void*"); break; 00192 case ARG_STR: fprintf(file, "char*"); break; 00193 case ARG_WSTR: fprintf(file, "wchar_t*"); break; 00194 case ARG_DBL: case ARG_INT64 : fprintf(file, "__int64"); break; 00195 case ARG_FLOAT: fprintf(file, "float"); break; 00196 } 00197 fprintf(file, " a%d", i); 00198 } 00199 fprintf(file, ")\n{\n\tDPRINT1(\"WARNING: calling stub %.*s(", 00200 pexp->nNameLength, pexp->pcName); 00201 00202 for (i = 0; i < pexp->nArgCount; i++) 00203 { 00204 if (i != 0) fprintf(file, ","); 00205 switch (pexp->anArgs[i]) 00206 { 00207 case ARG_LONG: fprintf(file, "0x%%lx"); break; 00208 case ARG_PTR: fprintf(file, "0x%%p"); break; 00209 case ARG_STR: fprintf(file, "'%%s'"); break; 00210 case ARG_WSTR: fprintf(file, "'%%ws'"); break; 00211 case ARG_DBL: fprintf(file, "%%f"); break; 00212 case ARG_INT64: fprintf(file, "%%\"PRix64\""); break; 00213 case ARG_FLOAT: fprintf(file, "%%f"); break; 00214 } 00215 } 00216 fprintf(file, ")\\n\""); 00217 00218 for (i = 0; i < pexp->nArgCount; i++) 00219 { 00220 fprintf(file, ", "); 00221 switch (pexp->anArgs[i]) 00222 { 00223 case ARG_LONG: fprintf(file, "(long)a%d", i); break; 00224 case ARG_PTR: fprintf(file, "(void*)a%d", i); break; 00225 case ARG_STR: fprintf(file, "(char*)a%d", i); break; 00226 case ARG_WSTR: fprintf(file, "(wchar_t*)a%d", i); break; 00227 case ARG_DBL: fprintf(file, "(double)a%d", i); break; 00228 case ARG_INT64: fprintf(file, "(__int64)a%d", i); break; 00229 case ARG_FLOAT: fprintf(file, "(float)a%d", i); break; 00230 } 00231 } 00232 fprintf(file, ");\n"); 00233 00234 if (pexp->nCallingConvention == CC_STUB) 00235 { 00236 fprintf(file, "\t__wine_spec_unimplemented_stub(\"%s\", __FUNCTION__);\n", pszDllName); 00237 } 00238 00239 fprintf(file, "\treturn 0;\n}\n\n"); 00240 00241 return 1; 00242 } 00243 00244 void 00245 OutputHeader_asmstub(FILE *file, char *libname) 00246 { 00247 fprintf(file, "; File generated automatically, do not edit! \n\n"); 00248 00249 if (giArch == ARCH_X86) 00250 fprintf(file, ".586\n.model flat\n"); 00251 00252 fprintf(file, ".code\n"); 00253 } 00254 00255 int 00256 OutputLine_asmstub(FILE *fileDest, EXPORT *pexp) 00257 { 00258 /* Handle autoname */ 00259 if (pexp->nNameLength == 1 && pexp->pcName[0] == '@') 00260 { 00261 fprintf(fileDest, "PUBLIC %sordinal%d\n%sordinal%d: nop\n", 00262 gpszUnderscore, pexp->nOrdinal, gpszUnderscore, pexp->nOrdinal); 00263 } 00264 else if (giArch != ARCH_X86) 00265 { 00266 fprintf(fileDest, "PUBLIC _stub_%.*s\n_stub_%.*s: nop\n", 00267 pexp->nNameLength, pexp->pcName, 00268 pexp->nNameLength, pexp->pcName); 00269 } 00270 else if (pexp->nCallingConvention == CC_STDCALL) 00271 { 00272 fprintf(fileDest, "PUBLIC __stub_%.*s@%d\n__stub_%.*s@%d: nop\n", 00273 pexp->nNameLength, pexp->pcName, pexp->nStackBytes, 00274 pexp->nNameLength, pexp->pcName, pexp->nStackBytes); 00275 } 00276 else if (pexp->nCallingConvention == CC_FASTCALL) 00277 { 00278 fprintf(fileDest, "PUBLIC @_stub_%.*s@%d\n@_stub_%.*s@%d: nop\n", 00279 pexp->nNameLength, pexp->pcName, pexp->nStackBytes, 00280 pexp->nNameLength, pexp->pcName, pexp->nStackBytes); 00281 } 00282 else if (pexp->nCallingConvention == CC_CDECL || 00283 pexp->nCallingConvention == CC_STUB) 00284 { 00285 fprintf(fileDest, "PUBLIC __stub_%.*s\n__stub_%.*s: nop\n", 00286 pexp->nNameLength, pexp->pcName, 00287 pexp->nNameLength, pexp->pcName); 00288 } 00289 else if (pexp->nCallingConvention == CC_EXTERN) 00290 { 00291 fprintf(fileDest, "PUBLIC __stub_%.*s\n__stub_%.*s:\n", 00292 pexp->nNameLength, pexp->pcName, 00293 pexp->nNameLength, pexp->pcName); 00294 } 00295 00296 return 1; 00297 } 00298 00299 void 00300 OutputHeader_def(FILE *file, char *libname) 00301 { 00302 fprintf(file, 00303 "; File generated automatically, do not edit!\n\n" 00304 "LIBRARY %s\n\n" 00305 "EXPORTS\n", 00306 libname); 00307 } 00308 00309 void 00310 PrintName(FILE *fileDest, EXPORT *pexp, char *pszPrefix, int fRedir, int fDeco) 00311 { 00312 char *pcName = fRedir ? pexp->pcRedirection : pexp->pcName; 00313 size_t nNameLength = fRedir ? pexp->nRedirectionLength : pexp->nNameLength; 00314 00315 /* Handle autoname */ 00316 if (nNameLength == 1 && pcName[0] == '@') 00317 { 00318 fprintf(fileDest, "ordinal%d", pexp->nOrdinal); 00319 } 00320 else 00321 { 00322 if (fDeco && pexp->nCallingConvention == CC_FASTCALL) 00323 fprintf(fileDest, "@"); 00324 fprintf(fileDest, "%s%.*s", pszPrefix, nNameLength, pcName); 00325 if ((pexp->nCallingConvention == CC_STDCALL || 00326 pexp->nCallingConvention == CC_FASTCALL) && fDeco) 00327 { 00328 fprintf(fileDest, "@%d", pexp->nStackBytes); 00329 } 00330 } 00331 } 00332 00333 int 00334 OutputLine_def(FILE *fileDest, EXPORT *pexp) 00335 { 00336 fprintf(fileDest, " "); 00337 00338 PrintName(fileDest, pexp, "", 0, (giArch == ARCH_X86) && !gbKillAt); 00339 00340 if (gbImportLib) 00341 { 00342 fprintf(fileDest, "="); 00343 PrintName(fileDest, pexp, "_stub_", 0, 0); 00344 } 00345 else if (pexp->pcRedirection) 00346 { 00347 if (gbMSComp && (pexp->pcName[0] == '?')) 00348 { 00349 /* ignore c++ redirection, since link doesn't like that! */ 00350 } 00351 else 00352 { 00353 int fDeco; 00354 00355 fDeco = ((giArch == ARCH_X86) && !ScanToken(pexp->pcRedirection, '.')); 00356 fprintf(fileDest, "="); 00357 PrintName(fileDest, pexp, "", 1, fDeco && !gbMSComp); 00358 } 00359 } 00360 else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) && 00361 (pexp->pcName[0] == '?')) 00362 { 00363 /* C++ stubs are forwarded to C stubs */ 00364 fprintf(fileDest, "="); 00365 fprintf(fileDest, "stub_function%d", pexp->nNumber); 00366 } 00367 else if ((giArch == ARCH_X86) && gbKillAt && !gbMSComp && 00368 (pexp->nCallingConvention == CC_STDCALL || 00369 pexp->nCallingConvention == CC_FASTCALL)) 00370 { 00371 fprintf(fileDest, "="); 00372 PrintName(fileDest, pexp, "", 0, 1); 00373 } 00374 00375 if (pexp->nOrdinal != -1) 00376 { 00377 fprintf(fileDest, " @%d", pexp->nOrdinal); 00378 } 00379 00380 if (pexp->nCallingConvention == CC_EXTERN) 00381 { 00382 fprintf(fileDest, " DATA"); 00383 } 00384 00385 if (pexp->uFlags & FL_PRIVATE) 00386 { 00387 fprintf(fileDest, " PRIVATE"); 00388 } 00389 00390 if (pexp->uFlags & FL_NONAME) 00391 { 00392 fprintf(fileDest, " NONAME"); 00393 } 00394 00395 fprintf(fileDest, "\n"); 00396 00397 return 1; 00398 } 00399 00400 int 00401 ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine) 00402 { 00403 char *pc, *pcLine; 00404 int nLine; 00405 EXPORT exp; 00406 int included; 00407 00408 //fprintf(stderr, "info: line %d, pcStart:'%.30s'\n", nLine, pcStart); 00409 00410 /* Loop all lines */ 00411 nLine = 1; 00412 exp.nNumber = 0; 00413 for (pcLine = pcStart; *pcLine; pcLine = NextLine(pcLine), nLine++) 00414 { 00415 pc = pcLine; 00416 00417 exp.nArgCount = 0; 00418 exp.uFlags = 0; 00419 exp.nNumber++; 00420 00421 //fprintf(stderr, "info: line %d, token:'%d, %.20s'\n", 00422 // nLine, TokenLength(pcLine), pcLine); 00423 00424 /* Skip white spaces */ 00425 while (*pc == ' ' || *pc == '\t') pc++; 00426 00427 /* Skip empty lines, stop at EOF */ 00428 if (*pc == ';' || *pc <= '#') continue; 00429 if (*pc == 0) return 0; 00430 00431 //fprintf(stderr, "info: line %d, token:'%.*s'\n", 00432 // nLine, TokenLength(pc), pc); 00433 00434 /* Now we should get either an ordinal or @ */ 00435 if (*pc == '@') exp.nOrdinal = -1; 00436 else exp.nOrdinal = atol(pc); 00437 00438 /* Go to next token (type) */ 00439 if (!(pc = NextToken(pc))) 00440 { 00441 fprintf(stderr, "error: line %d, unexpected end of line\n", nLine); 00442 return -10; 00443 } 00444 00445 //fprintf(stderr, "info: Token:'%.10s'\n", pc); 00446 00447 /* Now we should get the type */ 00448 if (CompareToken(pc, "stdcall")) 00449 { 00450 exp.nCallingConvention = CC_STDCALL; 00451 } 00452 else if (CompareToken(pc, "cdecl") || 00453 CompareToken(pc, "varargs")) 00454 { 00455 exp.nCallingConvention = CC_CDECL; 00456 } 00457 else if (CompareToken(pc, "fastcall")) 00458 { 00459 exp.nCallingConvention = CC_FASTCALL; 00460 } 00461 else if (CompareToken(pc, "thiscall")) 00462 { 00463 exp.nCallingConvention = CC_THISCALL; 00464 } 00465 else if (CompareToken(pc, "extern")) 00466 { 00467 exp.nCallingConvention = CC_EXTERN; 00468 } 00469 else if (CompareToken(pc, "stub")) 00470 { 00471 exp.nCallingConvention = CC_STUB; 00472 } 00473 else 00474 { 00475 fprintf(stderr, "error: line %d, expected type, got '%.*s' %d\n", 00476 nLine, TokenLength(pc), pc, *pc); 00477 return -11; 00478 } 00479 00480 //fprintf(stderr, "info: nCallingConvention: %d\n", exp.nCallingConvention); 00481 00482 /* Go to next token (options or name) */ 00483 if (!(pc = NextToken(pc))) 00484 { 00485 fprintf(stderr, "fail2\n"); 00486 return -12; 00487 } 00488 00489 /* Handle options */ 00490 included = 1; 00491 while (*pc == '-') 00492 { 00493 if (CompareToken(pc, "-arch")) 00494 { 00495 /* Default to not included */ 00496 included = 0; 00497 pc += 5; 00498 00499 /* Look if we are included */ 00500 while (*pc == '=' || *pc == ',') 00501 { 00502 pc++; 00503 if (CompareToken(pc, pszArchString) || 00504 CompareToken(pc, pszArchString2)) 00505 { 00506 included = 1; 00507 } 00508 00509 /* Skip to next arch or end */ 00510 while (*pc > ',') pc++; 00511 } 00512 } 00513 else if (CompareToken(pc, "-i386")) 00514 { 00515 if (giArch != ARCH_X86) included = 0; 00516 } 00517 else if (CompareToken(pc, "-private")) 00518 { 00519 exp.uFlags |= FL_PRIVATE; 00520 } 00521 else if (CompareToken(pc, "-noname") || 00522 CompareToken(pc, "-ordinal")) 00523 { 00524 exp.uFlags |= FL_NONAME; 00525 } 00526 else if (CompareToken(pc, "-stub")) 00527 { 00528 exp.uFlags |= FL_STUB; 00529 } 00530 else if (CompareToken(pc, "-norelay") || 00531 CompareToken(pc, "-register") || 00532 CompareToken(pc, "-ret64")) 00533 { 00534 /* silently ignore these */ 00535 } 00536 else 00537 { 00538 fprintf(stderr, "info: ignored option: '%.*s'\n", 00539 TokenLength(pc), pc); 00540 } 00541 00542 /* Go to next token */ 00543 pc = NextToken(pc); 00544 } 00545 00546 //fprintf(stderr, "info: Name:'%.10s'\n", pc); 00547 00548 /* If arch didn't match ours, skip this entry */ 00549 if (!included) continue; 00550 00551 /* Get name */ 00552 exp.pcName = pc; 00553 exp.nNameLength = TokenLength(pc); 00554 00555 /* Handle parameters */ 00556 exp.nStackBytes = 0; 00557 if (exp.nCallingConvention != CC_EXTERN && 00558 exp.nCallingConvention != CC_STUB) 00559 { 00560 //fprintf(stderr, "info: options:'%.10s'\n", pc); 00561 /* Go to next token */ 00562 if (!(pc = NextToken(pc))) 00563 { 00564 fprintf(stderr, "fail4\n"); 00565 return -13; 00566 } 00567 00568 /* Verify syntax */ 00569 if (*pc++ != '(') 00570 { 00571 fprintf(stderr, "error: line %d, expected '('\n", nLine); 00572 return -14; 00573 } 00574 00575 /* Skip whitespaces */ 00576 while (*pc == ' ' || *pc == '\t') pc++; 00577 00578 exp.nStackBytes = 0; 00579 while (*pc >= '0') 00580 { 00581 if (CompareToken(pc, "long")) 00582 { 00583 exp.nStackBytes += 4; 00584 exp.anArgs[exp.nArgCount] = ARG_LONG; 00585 } 00586 else if (CompareToken(pc, "double")) 00587 { 00588 exp.nStackBytes += 8; 00589 exp.anArgs[exp.nArgCount] = ARG_DBL; 00590 } 00591 else if (CompareToken(pc, "ptr") || 00592 CompareToken(pc, "str") || 00593 CompareToken(pc, "wstr")) 00594 { 00595 exp.nStackBytes += 4; // sizeof(void*) on x86 00596 exp.anArgs[exp.nArgCount] = ARG_PTR; // FIXME: handle strings 00597 } 00598 else if (CompareToken(pc, "int64")) 00599 { 00600 exp.nStackBytes += 8; 00601 exp.anArgs[exp.nArgCount] = ARG_INT64; 00602 } 00603 else if (CompareToken(pc, "float")) 00604 { 00605 exp.nStackBytes += 4; 00606 exp.anArgs[exp.nArgCount] = ARG_FLOAT; 00607 } 00608 else 00609 fprintf(stderr, "error: line %d, expected type, got: %.10s\n", nLine, pc); 00610 00611 exp.nArgCount++; 00612 00613 /* Go to next parameter */ 00614 if (!(pc = NextToken(pc))) 00615 { 00616 fprintf(stderr, "fail5\n"); 00617 return -15; 00618 } 00619 } 00620 00621 /* Check syntax */ 00622 if (*pc++ != ')') 00623 { 00624 fprintf(stderr, "error: line %d, expected ')'\n", nLine); 00625 return -16; 00626 } 00627 } 00628 00629 /* Handle special stub cases */ 00630 if (exp.nCallingConvention == CC_STUB) 00631 { 00632 /* Check for c++ mangled name */ 00633 if (pc[0] == '?') 00634 { 00635 //printf("Found c++ mangled name...\n"); 00636 // 00637 } 00638 else 00639 { 00640 /* Check for stdcall name */ 00641 char *p = strchr(pc, '@'); 00642 if (p && ((size_t)(p - pc) < exp.nNameLength)) 00643 { 00644 int i; 00645 exp.nNameLength = p - pc; 00646 if (exp.nNameLength < 1) 00647 { 00648 fprintf(stderr, "error, @ in line %d\n", nLine); 00649 return -1; 00650 } 00651 exp.nStackBytes = atoi(p + 1); 00652 exp.nArgCount = exp.nStackBytes / 4; 00653 exp.nCallingConvention = CC_STDCALL; 00654 exp.uFlags |= FL_STUB; 00655 for (i = 0; i < exp.nArgCount; i++) 00656 exp.anArgs[i] = ARG_LONG; 00657 } 00658 } 00659 } 00660 00661 /* Get optional redirection */ 00662 if ((pc = NextToken(pc))) 00663 { 00664 exp.pcRedirection = pc; 00665 exp.nRedirectionLength = TokenLength(pc); 00666 00667 /* Check syntax (end of line) */ 00668 if (NextToken(pc)) 00669 { 00670 fprintf(stderr, "error: line %d, additional tokens after ')'\n", nLine); 00671 return -17; 00672 } 00673 } 00674 else 00675 { 00676 exp.pcRedirection = 0; 00677 exp.nRedirectionLength = 0; 00678 } 00679 00680 OutputLine(fileDest, &exp); 00681 } 00682 00683 return 0; 00684 } 00685 00686 00687 void usage(void) 00688 { 00689 printf("syntax: spec2pdef [<options> ...] <spec file>\n" 00690 "Possible options:\n" 00691 " -h --help prints this screen\n" 00692 " -l=<file> generates an asm lib stub\n" 00693 " -d=<file> generates a def file\n" 00694 " -s=<file> generates a stub file\n" 00695 " --ms msvc compatibility\n" 00696 " -n=<name> name of the dll\n" 00697 " --kill-at removes @xx decorations from exports\n" 00698 " -r removes redirections from def file\n" 00699 " -a=<arch> Set architecture to <arch>. (i386, x86_64, arm)\n"); 00700 } 00701 00702 int main(int argc, char *argv[]) 00703 { 00704 size_t nFileSize; 00705 char *pszSource, *pszDefFileName = 0, *pszStubFileName = 0, *pszLibStubName = 0; 00706 char achDllName[40]; 00707 FILE *file; 00708 int result, i; 00709 00710 if (argc < 2) 00711 { 00712 usage(); 00713 return -1; 00714 } 00715 00716 /* Read options */ 00717 for (i = 1; i < argc && *argv[i] == '-'; i++) 00718 { 00719 if ((strcasecmp(argv[i], "--help") == 0) || 00720 (strcasecmp(argv[i], "-h") == 0)) 00721 { 00722 usage(); 00723 return 0; 00724 } 00725 else if (argv[i][1] == 'd' && argv[i][2] == '=') 00726 { 00727 pszDefFileName = argv[i] + 3; 00728 } 00729 else if (argv[i][1] == 'l' && argv[i][2] == '=') 00730 { 00731 pszLibStubName = argv[i] + 3; 00732 } 00733 else if (argv[i][1] == 's' && argv[i][2] == '=') 00734 { 00735 pszStubFileName = argv[i] + 3; 00736 } 00737 else if (argv[i][1] == 'n' && argv[i][2] == '=') 00738 { 00739 pszDllName = argv[i] + 3; 00740 } 00741 else if ((strcasecmp(argv[i], "--implib") == 0)) 00742 { 00743 no_redirections = 1; 00744 gbImportLib = 1; 00745 } 00746 else if ((strcasecmp(argv[i], "--kill-at") == 0)) 00747 { 00748 gbKillAt = 1; 00749 } 00750 else if ((strcasecmp(argv[i], "--ms") == 0)) 00751 { 00752 gbMSComp = 1; 00753 } 00754 else if ((strcasecmp(argv[i], "-r") == 0)) 00755 { 00756 no_redirections = 1; 00757 } 00758 else if (argv[i][1] == 'a' && argv[i][2] == '=') 00759 { 00760 pszArchString = argv[i] + 3; 00761 } 00762 else 00763 { 00764 fprintf(stderr, "Unrecognized option: %s\n", argv[i]); 00765 return -1; 00766 } 00767 } 00768 00769 if (strcasecmp(pszArchString, "i386") == 0) 00770 { 00771 giArch = ARCH_X86; 00772 gpszUnderscore = "_"; 00773 } 00774 else if (strcasecmp(pszArchString, "x86_64") == 0) giArch = ARCH_AMD64; 00775 else if (strcasecmp(pszArchString, "ia64") == 0) giArch = ARCH_IA64; 00776 else if (strcasecmp(pszArchString, "arm") == 0) giArch = ARCH_ARM; 00777 else if (strcasecmp(pszArchString, "ppc") == 0) giArch = ARCH_PPC; 00778 00779 if ((giArch == ARCH_AMD64) || (giArch == ARCH_IA64)) 00780 { 00781 pszArchString2 = "win64"; 00782 } 00783 else 00784 pszArchString2 = "win32"; 00785 00786 /* Set a default dll name */ 00787 if (!pszDllName) 00788 { 00789 char *p1, *p2; 00790 size_t len; 00791 00792 p1 = strrchr(argv[i], '\\'); 00793 if (!p1) p1 = strrchr(argv[i], '/'); 00794 p2 = p1 = p1 ? p1 + 1 : argv[i]; 00795 00796 /* walk up to '.' */ 00797 while (*p2 != '.' && *p2 != 0) p2++; 00798 len = p2 - p1; 00799 if (len >= sizeof(achDllName) - 5) 00800 { 00801 fprintf(stderr, "name too long: %s\n", p1); 00802 return -2; 00803 } 00804 00805 strncpy(achDllName, p1, len); 00806 strncpy(achDllName + len, ".dll", sizeof(achDllName) - len); 00807 pszDllName = achDllName; 00808 } 00809 00810 /* Open input file argv[1] */ 00811 file = fopen(argv[i], "r"); 00812 if (!file) 00813 { 00814 fprintf(stderr, "error: could not open file %s ", argv[i]); 00815 return -3; 00816 } 00817 00818 /* Get file size */ 00819 fseek(file, 0, SEEK_END); 00820 nFileSize = ftell(file); 00821 rewind(file); 00822 00823 /* Allocate memory buffer */ 00824 pszSource = malloc(nFileSize + 1); 00825 if (!pszSource) 00826 { 00827 fclose(file); 00828 return -4; 00829 } 00830 00831 /* Load input file into memory */ 00832 nFileSize = fread(pszSource, 1, nFileSize, file); 00833 fclose(file); 00834 00835 /* Zero terminate the source */ 00836 pszSource[nFileSize] = '\0'; 00837 00838 if (pszDefFileName) 00839 { 00840 /* Open output file */ 00841 file = fopen(pszDefFileName, "w"); 00842 if (!file) 00843 { 00844 fprintf(stderr, "error: could not open output file %s ", argv[i + 1]); 00845 return -5; 00846 } 00847 00848 OutputHeader_def(file, pszDllName); 00849 result = ParseFile(pszSource, file, OutputLine_def); 00850 fclose(file); 00851 } 00852 00853 if (pszStubFileName) 00854 { 00855 /* Open output file */ 00856 file = fopen(pszStubFileName, "w"); 00857 if (!file) 00858 { 00859 fprintf(stderr, "error: could not open output file %s ", argv[i + 1]); 00860 return -5; 00861 } 00862 00863 OutputHeader_stub(file); 00864 result = ParseFile(pszSource, file, OutputLine_stub); 00865 fclose(file); 00866 } 00867 00868 if (pszLibStubName) 00869 { 00870 /* Open output file */ 00871 file = fopen(pszLibStubName, "w"); 00872 if (!file) 00873 { 00874 fprintf(stderr, "error: could not open output file %s ", argv[i + 1]); 00875 return -5; 00876 } 00877 00878 OutputHeader_asmstub(file, pszDllName); 00879 result = ParseFile(pszSource, file, OutputLine_asmstub); 00880 fprintf(file, "\nEND\n"); 00881 fclose(file); 00882 } 00883 00884 00885 return result; 00886 } Generated on Fri May 25 2012 04:36:11 for ReactOS by
1.7.6.1
|