ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

spec2def.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.