ReactOS  0.4.12-dev-918-g6c6e7b8
spec2def.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <ctype.h>
4 #include <string.h>
5 
6 #ifdef _MSC_VER
7 #define strcasecmp(_String1, _String2) _stricmp(_String1, _String2)
8 #define strncasecmp(_String1, _String2, _MaxCount) _strnicmp(_String1, _String2, _MaxCount)
9 #endif
10 
11 #define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
12 
13 typedef struct _STRING
14 {
15  const char *buf;
16  int len;
17 } STRING, *PSTRING;
18 
19 typedef struct
20 {
24  int nOrdinal;
26  int nArgCount;
27  int anArgs[30];
28  unsigned int uFlags;
29  int nNumber;
30 } EXPORT;
31 
32 enum _ARCH
33 {
39 };
40 
41 typedef int (*PFNOUTLINE)(FILE *, EXPORT *);
42 int gbMSComp = 0;
43 int gbImportLib = 0;
45 int gbTracing = 0;
47 char *pszArchString = "i386";
50 char *pszDllName = NULL;
51 char *gpszUnderscore = "";
52 int gbDebug;
53 unsigned guOsVersion = 0x502;
54 #define DbgPrint(...) (!gbDebug || fprintf(stderr, __VA_ARGS__))
55 
56 enum
57 {
59  FL_STUB = 2,
60  FL_NONAME = 4,
62  FL_NORELAY = 16,
63  FL_RET64 = 32,
65 };
66 
67 enum
68 {
75 };
76 
77 enum
78 {
87 };
88 
89 const char* astrCallingConventions[] =
90 {
91  "STDCALL",
92  "CDECL",
93  "FASTCALL",
94  "THISCALL",
95  "EXTERN"
96 };
97 
98 static const char* astrShouldBePrivate[] =
99 {
100  "DllCanUnloadNow",
101  "DllGetClassObject",
102  "DllGetClassFactoryFromClassString",
103  "DllGetDocumentation",
104  "DllInitialize",
105  "DllInstall",
106  "DllRegisterServer",
107  "DllRegisterServerEx",
108  "DllRegisterServerExW",
109  "DllUnload",
110  "DllUnregisterServer",
111  "RasCustomDeleteEntryNotify",
112  "RasCustomDial",
113  "RasCustomDialDlg",
114  "RasCustomEntryDlg",
115 };
116 
117 static
118 int
120 {
121  return ((chr <= ',' && chr != '$' && chr != '#') ||
122  (chr >= ':' && chr < '?') );
123 }
124 
125 int
126 CompareToken(const char *token, const char *comparand)
127 {
128  while (*comparand)
129  {
130  if (*token != *comparand) return 0;
131  token++;
132  comparand++;
133  }
134  if (IsSeparator(comparand[-1])) return 1;
135  if (!IsSeparator(*token)) return 0;
136  return 1;
137 }
138 
139 const char *
140 ScanToken(const char *token, char chr)
141 {
142  while (!IsSeparator(*token))
143  {
144  if (*token == chr) return token;
145  token++;
146  }
147  return 0;
148 }
149 
150 char *
151 NextLine(char *pc)
152 {
153  while (*pc != 0)
154  {
155  if (pc[0] == '\n' && pc[1] == '\r') return pc + 2;
156  else if (pc[0] == '\n') return pc + 1;
157  pc++;
158  }
159  return pc;
160 }
161 
162 int
163 TokenLength(char *pc)
164 {
165  int length = 0;
166 
167  while (!IsSeparator(*pc++)) length++;
168 
169  return length;
170 }
171 
172 char *
173 NextToken(char *pc)
174 {
175  /* Skip token */
176  while (!IsSeparator(*pc)) pc++;
177 
178  /* Skip white spaces */
179  while (*pc == ' ' || *pc == '\t') pc++;
180 
181  /* Check for end of line */
182  if (*pc == '\n' || *pc == '\r' || *pc == 0) return 0;
183 
184  /* Check for comment */
185  if (*pc == '#' || *pc == ';') return 0;
186 
187  return pc;
188 }
189 
190 void
192 {
193  fprintf(file, "/* This file is autogenerated, do not edit. */\n\n"
194  "#include <stubs.h>\n");
195 
196  if (gbTracing)
197  {
198  fprintf(file, "#include <wine/debug.h>\n");
199  fprintf(file, "#include <inttypes.h>\n");
200  fprintf(file, "WINE_DECLARE_DEBUG_CHANNEL(relay);\n");
201  }
202 
203  fprintf(file, "\n");
204 }
205 
206 int
208 {
209  int i;
210  int bRelay = 0;
211  int bInPrototype = 0;
212 
213  if (pexp->nCallingConvention != CC_STUB &&
214  (pexp->uFlags & FL_STUB) == 0)
215  {
216  /* Only relay trace stdcall C functions */
217  if (!gbTracing || (pexp->nCallingConvention != CC_STDCALL)
218  || (pexp->uFlags & FL_NORELAY)
219  || (pexp->strName.buf[0] == '?'))
220  {
221  return 0;
222  }
223  bRelay = 1;
224  }
225 
226  /* Declare the "real" function */
227  if (bRelay)
228  {
229  fprintf(file, "extern ");
230  bInPrototype = 1;
231  }
232 
233  do
234  {
235  if (pexp->uFlags & FL_REGISTER)
236  {
237  /* FIXME: Not sure this is right */
238  fprintf(file, "void ");
239  }
240  else if (pexp->uFlags & FL_RET64)
241  {
242  fprintf(file, "__int64 ");
243  }
244  else
245  {
246  fprintf(file, "int ");
247  }
248 
249  if ((giArch == ARCH_X86) &&
251  {
252  fprintf(file, "__stdcall ");
253  }
254 
255  /* Check for C++ */
256  if (pexp->strName.buf[0] == '?')
257  {
258  fprintf(file, "stub_function%d(", pexp->nNumber);
259  }
260  else
261  {
262  if (!bRelay || bInPrototype)
263  fprintf(file, "%.*s(", pexp->strName.len, pexp->strName.buf);
264  else
265  fprintf(file, "$relaytrace$%.*s(", pexp->strName.len, pexp->strName.buf);
266  }
267 
268  for (i = 0; i < pexp->nArgCount; i++)
269  {
270  if (i != 0) fprintf(file, ", ");
271  switch (pexp->anArgs[i])
272  {
273  case ARG_LONG: fprintf(file, "long"); break;
274  case ARG_PTR: fprintf(file, "void*"); break;
275  case ARG_STR: fprintf(file, "char*"); break;
276  case ARG_WSTR: fprintf(file, "wchar_t*"); break;
277  case ARG_DBL: fprintf(file, "double"); break;
278  case ARG_INT64 : fprintf(file, "__int64"); break;
279  /* __int128 is not supported on x86, and int128 in spec files most often represents a GUID */
280  case ARG_INT128 : fprintf(file, "GUID"); break;
281  case ARG_FLOAT: fprintf(file, "float"); break;
282  }
283  fprintf(file, " a%d", i);
284  }
285 
286  if (bInPrototype)
287  {
288  fprintf(file, ");\n\n");
289  }
290  } while (bInPrototype--);
291 
292  if (!bRelay)
293  {
294  fprintf(file, ")\n{\n\tDbgPrint(\"WARNING: calling stub %.*s(",
295  pexp->strName.len, pexp->strName.buf);
296  }
297  else
298  {
299  fprintf(file, ")\n{\n");
300  if (pexp->uFlags & FL_REGISTER)
301  {
302  /* No return value */
303  }
304  else if (pexp->uFlags & FL_RET64)
305  {
306  fprintf(file, "\t__int64 retval;\n");
307  }
308  else
309  {
310  fprintf(file, "\tint retval;\n");
311  }
312  fprintf(file, "\tif (TRACE_ON(relay))\n\t\tDPRINTF(\"%s: %.*s(",
313  pszDllName, pexp->strName.len, pexp->strName.buf);
314  }
315 
316  for (i = 0; i < pexp->nArgCount; i++)
317  {
318  if (i != 0) fprintf(file, ",");
319  switch (pexp->anArgs[i])
320  {
321  case ARG_LONG: fprintf(file, "0x%%lx"); break;
322  case ARG_PTR: fprintf(file, "0x%%p"); break;
323  case ARG_STR: fprintf(file, "'%%s'"); break;
324  case ARG_WSTR: fprintf(file, "'%%ws'"); break;
325  case ARG_DBL: fprintf(file, "%%f"); break;
326  case ARG_INT64: fprintf(file, "%%\"PRIx64\""); break;
327  case ARG_INT128: fprintf(file, "'%%s'"); break;
328  case ARG_FLOAT: fprintf(file, "%%f"); break;
329  }
330  }
331  fprintf(file, ")\\n\"");
332 
333  for (i = 0; i < pexp->nArgCount; i++)
334  {
335  fprintf(file, ", ");
336  switch (pexp->anArgs[i])
337  {
338  case ARG_LONG: fprintf(file, "(long)a%d", i); break;
339  case ARG_PTR: fprintf(file, "(void*)a%d", i); break;
340  case ARG_STR: fprintf(file, "(char*)a%d", i); break;
341  case ARG_WSTR: fprintf(file, "(wchar_t*)a%d", i); break;
342  case ARG_DBL: fprintf(file, "(double)a%d", i); break;
343  case ARG_INT64: fprintf(file, "(__int64)a%d", i); break;
344  case ARG_INT128: fprintf(file, "wine_dbgstr_guid(&a%d)", i); break;
345  case ARG_FLOAT: fprintf(file, "(float)a%d", i); break;
346  }
347  }
348  fprintf(file, ");\n");
349 
350  if (pexp->nCallingConvention == CC_STUB)
351  {
352  fprintf(file, "\t__wine_spec_unimplemented_stub(\"%s\", __FUNCTION__);\n", pszDllName);
353  }
354  else if (bRelay)
355  {
356  if (pexp->uFlags & FL_REGISTER)
357  {
358  fprintf(file,"\t");
359  }
360  else
361  {
362  fprintf(file, "\tretval = ");
363  }
364  fprintf(file, "%.*s(", pexp->strName.len, pexp->strName.buf);
365 
366  for (i = 0; i < pexp->nArgCount; i++)
367  {
368  if (i != 0) fprintf(file, ", ");
369  fprintf(file, "a%d", i);
370  }
371  fprintf(file, ");\n");
372  }
373 
374  if (!bRelay)
375  fprintf(file, "\treturn 0;\n}\n\n");
376  else if ((pexp->uFlags & FL_REGISTER) == 0)
377  {
378  if (pexp->uFlags & FL_RET64)
379  {
380  fprintf(file, "\tif (TRACE_ON(relay))\n\t\tDPRINTF(\"%s: %.*s: retval = %%\"PRIx64\"\\n\", retval);\n",
381  pszDllName, pexp->strName.len, pexp->strName.buf);
382  }
383  else
384  {
385  fprintf(file, "\tif (TRACE_ON(relay))\n\t\tDPRINTF(\"%s: %.*s: retval = 0x%%lx\\n\", retval);\n",
386  pszDllName, pexp->strName.len, pexp->strName.buf);
387  }
388  fprintf(file, "\treturn retval;\n}\n\n");
389  }
390 
391  return 1;
392 }
393 
394 void
396 {
397  fprintf(file, "; File generated automatically, do not edit! \n\n");
398 
399  if (giArch == ARCH_X86)
400  {
401  fprintf(file, ".586\n.model flat\n.code\n");
402  }
403  else if (giArch == ARCH_AMD64)
404  {
405  fprintf(file, ".code\n");
406  }
407  else if (giArch == ARCH_ARM)
408  {
409  fprintf(file, " AREA |.text|,ALIGN=2,CODE,READONLY\n\n");
410  }
411 }
412 
413 void
414 Output_stublabel(FILE *fileDest, char* pszSymbolName)
415 {
416  if (giArch == ARCH_ARM)
417  {
418  fprintf(fileDest,
419  "\tEXPORT |%s| [FUNC]\n|%s|\n",
420  pszSymbolName,
421  pszSymbolName);
422  }
423  else
424  {
425  fprintf(fileDest,
426  "PUBLIC %s\n%s: nop\n",
427  pszSymbolName,
428  pszSymbolName);
429  }
430 }
431 
432 int
433 OutputLine_asmstub(FILE *fileDest, EXPORT *pexp)
434 {
435  char szNameBuffer[128];
436 
437  /* Handle autoname */
438  if (pexp->strName.len == 1 && pexp->strName.buf[0] == '@')
439  {
440  sprintf(szNameBuffer, "%sordinal%d\n%sordinal%d: nop\n",
442  }
443  else if (giArch != ARCH_X86)
444  {
445  sprintf(szNameBuffer, "_stub_%.*s",
446  pexp->strName.len, pexp->strName.buf);
447  }
448  else if (pexp->nCallingConvention == CC_STDCALL)
449  {
450  sprintf(szNameBuffer, "__stub_%.*s@%d",
451  pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
452  }
453  else if (pexp->nCallingConvention == CC_FASTCALL)
454  {
455  sprintf(szNameBuffer, "@_stub_%.*s@%d",
456  pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
457  }
458  else if ((pexp->nCallingConvention == CC_CDECL) ||
459  (pexp->nCallingConvention == CC_THISCALL) ||
460  (pexp->nCallingConvention == CC_EXTERN) ||
461  (pexp->nCallingConvention == CC_STUB))
462  {
463  sprintf(szNameBuffer, "__stub_%.*s",
464  pexp->strName.len, pexp->strName.buf);
465  }
466  else
467  {
468  fprintf(stderr, "Invalid calling convention");
469  return 0;
470  }
471 
472  Output_stublabel(fileDest, szNameBuffer);
473 
474  return 1;
475 }
476 
477 void
478 OutputHeader_def(FILE *file, char *libname)
479 {
480  fprintf(file,
481  "; File generated automatically, do not edit!\n\n"
482  "NAME %s\n\n"
483  "EXPORTS\n",
484  libname);
485 }
486 
487 void
488 PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
489 {
490  const char *pcName = pstr->buf;
491  int nNameLength = pstr->len;
492  const char* pcDot, *pcAt;
493 
494  /* Check for non-x86 first */
495  if (giArch != ARCH_X86)
496  {
497  /* Does the string already have stdcall decoration? */
498  pcAt = ScanToken(pcName, '@');
499  if (pcAt && (pcAt < (pcName + nNameLength)) && (pcName[0] == '_'))
500  {
501  /* Skip leading underscore and remove trailing decoration */
502  pcName++;
503  nNameLength = pcAt - pcName;
504  }
505 
506  /* Print the undecorated function name */
507  fprintf(fileDest, "%.*s", nNameLength, pcName);
508  }
509  else if (fDeco &&
510  ((pexp->nCallingConvention == CC_STDCALL) ||
511  (pexp->nCallingConvention == CC_FASTCALL)))
512  {
513  /* Scan for a dll forwarding dot */
514  pcDot = ScanToken(pcName, '.');
515  if (pcDot)
516  {
517  /* First print the dll name, followed by a dot */
518  nNameLength = pcDot - pcName;
519  fprintf(fileDest, "%.*s.", nNameLength, pcName);
520 
521  /* Now the actual function name */
522  pcName = pcDot + 1;
523  nNameLength = pexp->strTarget.len - nNameLength - 1;
524  }
525 
526  /* Does the string already have decoration? */
527  pcAt = ScanToken(pcName, '@');
528  if (pcAt && (pcAt < (pcName + nNameLength)))
529  {
530  /* On GCC, we need to remove the leading stdcall underscore */
531  if (!gbMSComp && (pexp->nCallingConvention == CC_STDCALL))
532  {
533  pcName++;
534  nNameLength--;
535  }
536 
537  /* Print the already decorated function name */
538  fprintf(fileDest, "%.*s", nNameLength, pcName);
539  }
540  else
541  {
542  /* Print the prefix, but skip it for (GCC && stdcall) */
543  if (gbMSComp || (pexp->nCallingConvention != CC_STDCALL))
544  {
545  fprintf(fileDest, "%c", pexp->nCallingConvention == CC_FASTCALL ? '@' : '_');
546  }
547 
548  /* Print the name with trailing decoration */
549  fprintf(fileDest, "%.*s@%d", nNameLength, pcName, pexp->nStackBytes);
550  }
551  }
552  else
553  {
554  /* Print the undecorated function name */
555  fprintf(fileDest, "%.*s", nNameLength, pcName);
556  }
557 }
558 
559 void
560 OutputLine_def_MS(FILE *fileDest, EXPORT *pexp)
561 {
562  PrintName(fileDest, pexp, &pexp->strName, 0);
563 
564  if (gbImportLib)
565  {
566  /* Redirect to a stub function, to get the right decoration in the lib */
567  fprintf(fileDest, "=_stub_%.*s", pexp->strName.len, pexp->strName.buf);
568  }
569  else if (pexp->strTarget.buf)
570  {
571  if (pexp->strName.buf[0] == '?')
572  {
573  //fprintf(stderr, "warning: ignoring C++ redirection %.*s -> %.*s\n",
574  // pexp->strName.len, pexp->strName.buf, pexp->strTarget.len, pexp->strTarget.buf);
575  }
576  else
577  {
578  fprintf(fileDest, "=");
579 
580  /* If the original name was decorated, use decoration in the forwarder as well */
581  if ((giArch == ARCH_X86) && ScanToken(pexp->strName.buf, '@') &&
582  !ScanToken(pexp->strTarget.buf, '@') &&
583  ((pexp->nCallingConvention == CC_STDCALL) ||
584  (pexp->nCallingConvention == CC_FASTCALL)) )
585  {
586  PrintName(fileDest, pexp, &pexp->strTarget, 1);
587  }
588  else
589  {
590  /* Write the undecorated redirection name */
591  fprintf(fileDest, "%.*s", pexp->strTarget.len, pexp->strTarget.buf);
592  }
593  }
594  }
595  else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
596  (pexp->strName.buf[0] == '?'))
597  {
598  /* C++ stubs are forwarded to C stubs */
599  fprintf(fileDest, "=stub_function%d", pexp->nNumber);
600  }
601  else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CC_STDCALL) &&
602  (pexp->strName.buf[0] != '?'))
603  {
604  /* Redirect it to the relay-tracing trampoline */
605  fprintf(fileDest, "=$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
606  }
607 }
608 
609 void
610 OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp)
611 {
612  int bTracing = 0;
613  /* Print the function name, with decoration for export libs */
614  PrintName(fileDest, pexp, &pexp->strName, gbImportLib);
615  DbgPrint("Generating def line for '%.*s'\n", pexp->strName.len, pexp->strName.buf);
616 
617  /* Check if this is a forwarded export */
618  if (pexp->strTarget.buf)
619  {
620  int fIsExternal = !!ScanToken(pexp->strTarget.buf, '.');
621  DbgPrint("Got redirect '%.*s'\n", pexp->strTarget.len, pexp->strTarget.buf);
622 
623  /* print the target name, don't decorate if it is external */
624  fprintf(fileDest, "=");
625  PrintName(fileDest, pexp, &pexp->strTarget, !fIsExternal);
626  }
627  else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
628  (pexp->strName.buf[0] == '?'))
629  {
630  /* C++ stubs are forwarded to C stubs */
631  fprintf(fileDest, "=stub_function%d", pexp->nNumber);
632  }
633  else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) &&
634  (pexp->nCallingConvention == CC_STDCALL) &&
635  (pexp->strName.buf[0] != '?'))
636  {
637  /* Redirect it to the relay-tracing trampoline */
638  char buf[256];
639  STRING strTarget;
640  fprintf(fileDest, "=");
641  sprintf(buf, "$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
642  strTarget.buf = buf;
643  strTarget.len = pexp->strName.len + 12;
644  PrintName(fileDest, pexp, &strTarget, 1);
645  bTracing = 1;
646  }
647 
648  /* Special handling for stdcall and fastcall */
649  if ((giArch == ARCH_X86) &&
650  ((pexp->nCallingConvention == CC_STDCALL) ||
651  (pexp->nCallingConvention == CC_FASTCALL)))
652  {
653  /* Is this the import lib? */
654  if (gbImportLib)
655  {
656  /* Is the name in the spec file decorated? */
657  const char* pcDeco = ScanToken(pexp->strName.buf, '@');
658  if (pcDeco && (pcDeco < pexp->strName.buf + pexp->strName.len))
659  {
660  /* Write the name including the leading @ */
661  fprintf(fileDest, "==%.*s", pexp->strName.len, pexp->strName.buf);
662  }
663  }
664  else if ((!pexp->strTarget.buf) && !(bTracing))
665  {
666  /* Write a forwarder to the actual decorated symbol */
667  fprintf(fileDest, "=");
668  PrintName(fileDest, pexp, &pexp->strName, 1);
669  }
670  }
671 }
672 
673 int
674 OutputLine_def(FILE *fileDest, EXPORT *pexp)
675 {
676  DbgPrint("OutputLine_def: '%.*s'...\n", pexp->strName.len, pexp->strName.buf);
677  fprintf(fileDest, " ");
678 
679  if (gbMSComp)
680  OutputLine_def_MS(fileDest, pexp);
681  else
682  OutputLine_def_GCC(fileDest, pexp);
683 
684  if (pexp->uFlags & FL_ORDINAL)
685  {
686  fprintf(fileDest, " @%d", pexp->nOrdinal);
687  }
688 
689  if (pexp->uFlags & FL_NONAME)
690  {
691  fprintf(fileDest, " NONAME");
692  }
693 
694  /* Either PRIVATE or DATA */
695  if (pexp->uFlags & FL_PRIVATE)
696  {
697  fprintf(fileDest, " PRIVATE");
698  }
699  else if (pexp->nCallingConvention == CC_EXTERN)
700  {
701  fprintf(fileDest, " DATA");
702  }
703 
704  fprintf(fileDest, "\n");
705 
706  return 1;
707 }
708 
709 int
710 ParseFile(char* pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
711 {
712  char *pc, *pcLine;
713  int nLine;
714  EXPORT exp;
715  int included, version_included;
716  char namebuffer[16];
717  unsigned int i;
718 
719  //fprintf(stderr, "info: line %d, pcStart:'%.30s'\n", nLine, pcStart);
720 
721  /* Loop all lines */
722  nLine = 1;
723  exp.nNumber = 0;
724  for (pcLine = pcStart; *pcLine; pcLine = NextLine(pcLine), nLine++)
725  {
726  pc = pcLine;
727 
728  exp.nArgCount = 0;
729  exp.uFlags = 0;
730  exp.nNumber++;
731 
732  /* Skip white spaces */
733  while (*pc == ' ' || *pc == '\t') pc++;
734 
735  /* Skip empty lines, stop at EOF */
736  if (*pc == ';' || *pc <= '#') continue;
737  if (*pc == 0) return 0;
738 
739  /* Now we should get either an ordinal or @ */
740  if (*pc == '@')
741  exp.nOrdinal = -1;
742  else
743  {
744  exp.nOrdinal = atol(pc);
745  /* The import lib should contain the ordinal only if -ordinal was specified */
746  if (!gbImportLib)
747  exp.uFlags |= FL_ORDINAL;
748  }
749 
750  /* Go to next token (type) */
751  if (!(pc = NextToken(pc)))
752  {
753  fprintf(stderr, "%s line %d: error: unexpected end of line\n", pszSourceFileName, nLine);
754  return -10;
755  }
756 
757  //fprintf(stderr, "info: Token:'%.*s'\n", TokenLength(pc), pc);
758 
759  /* Now we should get the type */
760  if (CompareToken(pc, "stdcall"))
761  {
762  exp.nCallingConvention = CC_STDCALL;
763  }
764  else if (CompareToken(pc, "cdecl") ||
765  CompareToken(pc, "varargs"))
766  {
767  exp.nCallingConvention = CC_CDECL;
768  }
769  else if (CompareToken(pc, "fastcall"))
770  {
771  exp.nCallingConvention = CC_FASTCALL;
772  }
773  else if (CompareToken(pc, "thiscall"))
774  {
775  exp.nCallingConvention = CC_THISCALL;
776  }
777  else if (CompareToken(pc, "extern"))
778  {
779  exp.nCallingConvention = CC_EXTERN;
780  }
781  else if (CompareToken(pc, "stub"))
782  {
783  exp.nCallingConvention = CC_STUB;
784  }
785  else
786  {
787  fprintf(stderr, "%s line %d: error: expected callconv, got '%.*s' %d\n",
788  pszSourceFileName, nLine, TokenLength(pc), pc, *pc);
789  return -11;
790  }
791 
792  /* Go to next token (options or name) */
793  if (!(pc = NextToken(pc)))
794  {
795  fprintf(stderr, "fail2\n");
796  return -12;
797  }
798 
799  /* Handle options */
800  included = 1;
801  version_included = 1;
802  while (*pc == '-')
803  {
804  if (CompareToken(pc, "-arch="))
805  {
806  /* Default to not included */
807  included = 0;
808  pc += 5;
809 
810  /* Look if we are included */
811  do
812  {
813  pc++;
814  if (CompareToken(pc, pszArchString) ||
816  {
817  included = 1;
818  }
819 
820  /* Skip to next arch or end */
821  while (*pc > ',') pc++;
822  } while (*pc == ',');
823  }
824  else if (CompareToken(pc, "-i386"))
825  {
826  if (giArch != ARCH_X86) included = 0;
827  }
828  else if (CompareToken(pc, "-version="))
829  {
830  /* Default to not included */
831  version_included = 0;
832  pc += 8;
833 
834  /* Look if we are included */
835  do
836  {
837  unsigned version, endversion;
838 
839  /* Optionally skip leading '0x' */
840  pc++;
841  if ((pc[0] == '0') && (pc[1] == 'x')) pc += 2;
842 
843  /* Now get the version number */
844  endversion = version = strtoul(pc, &pc, 16);
845 
846  /* Check if it's a range */
847  if (pc[0] == '+')
848  {
849  endversion = 0xFFF;
850  pc++;
851  }
852  else if (pc[0] == '-')
853  {
854  /* Optionally skip leading '0x' */
855  pc++;
856  if ((pc[0] == '0') && (pc[1] == 'x')) pc += 2;
857  endversion = strtoul(pc, &pc, 16);
858  }
859 
860  /* Check for degenerate range */
861  if (version > endversion)
862  {
863  fprintf(stderr, "%s line %d: error: invalid version rangen\n", pszSourceFileName, nLine);
864  return -1;
865  }
866 
867  /* Now compare the range with our version */
868  if ((guOsVersion >= version) &&
869  (guOsVersion <= endversion))
870  {
871  version_included = 1;
872  }
873 
874  /* Skip to next arch or end */
875  while (*pc > ',') pc++;
876 
877  } while (*pc == ',');
878  }
879  else if (CompareToken(pc, "-private"))
880  {
881  exp.uFlags |= FL_PRIVATE;
882  }
883  else if (CompareToken(pc, "-noname"))
884  {
885  exp.uFlags |= FL_ORDINAL | FL_NONAME;
886  }
887  else if (CompareToken(pc, "-ordinal"))
888  {
889  exp.uFlags |= FL_ORDINAL;
890  /* GCC doesn't automatically import by ordinal if an ordinal
891  * is found in the def file. Force it. */
892  if (gbImportLib && !gbMSComp)
893  exp.uFlags |= FL_NONAME;
894  }
895  else if (CompareToken(pc, "-stub"))
896  {
897  exp.uFlags |= FL_STUB;
898  }
899  else if (CompareToken(pc, "-norelay"))
900  {
901  exp.uFlags |= FL_NORELAY;
902  }
903  else if (CompareToken(pc, "-ret64"))
904  {
905  exp.uFlags |= FL_RET64;
906  }
907  else if (CompareToken(pc, "-register"))
908  {
909  exp.uFlags |= FL_REGISTER;
910  }
911  else
912  {
913  fprintf(stderr, "info: ignored option: '%.*s'\n",
914  TokenLength(pc), pc);
915  }
916 
917  /* Go to next token */
918  pc = NextToken(pc);
919  }
920 
921  //fprintf(stderr, "info: Name:'%.10s'\n", pc);
922 
923  /* If arch didn't match ours, skip this entry */
924  if (!included || !version_included) continue;
925 
926  /* Get name */
927  exp.strName.buf = pc;
928  exp.strName.len = TokenLength(pc);
929  DbgPrint("Got name: '%.*s'\n", exp.strName.len, exp.strName.buf);
930 
931  /* Check for autoname */
932  if ((exp.strName.len == 1) && (exp.strName.buf[0] == '@'))
933  {
934  sprintf(namebuffer, "ordinal%d", exp.nOrdinal);
935  exp.strName.len = strlen(namebuffer);
936  exp.strName.buf = namebuffer;
937  exp.uFlags |= FL_ORDINAL | FL_NONAME;
938  }
939 
940  /* Handle parameters */
941  exp.nStackBytes = 0;
942  if (exp.nCallingConvention != CC_EXTERN &&
943  exp.nCallingConvention != CC_STUB)
944  {
945  /* Go to next token */
946  if (!(pc = NextToken(pc)))
947  {
948  fprintf(stderr, "%s line %d: error: expected token\n", pszSourceFileName, nLine);
949  return -13;
950  }
951 
952  /* Verify syntax */
953  if (*pc++ != '(')
954  {
955  fprintf(stderr, "%s line %d: error: expected '('\n", pszSourceFileName, nLine);
956  return -14;
957  }
958 
959  /* Skip whitespaces */
960  while (*pc == ' ' || *pc == '\t') pc++;
961 
962  exp.nStackBytes = 0;
963  while (*pc >= '0')
964  {
965  if (CompareToken(pc, "long"))
966  {
967  exp.nStackBytes += 4;
968  exp.anArgs[exp.nArgCount] = ARG_LONG;
969  }
970  else if (CompareToken(pc, "double"))
971  {
972  exp.nStackBytes += 8;
973  exp.anArgs[exp.nArgCount] = ARG_DBL;
974  }
975  else if (CompareToken(pc, "ptr"))
976  {
977  exp.nStackBytes += 4; // sizeof(void*) on x86
978  exp.anArgs[exp.nArgCount] = ARG_PTR;
979  }
980  else if (CompareToken(pc, "str"))
981  {
982  exp.nStackBytes += 4; // sizeof(void*) on x86
983  exp.anArgs[exp.nArgCount] = ARG_STR;
984  }
985  else if (CompareToken(pc, "wstr"))
986  {
987  exp.nStackBytes += 4; // sizeof(void*) on x86
988  exp.anArgs[exp.nArgCount] = ARG_WSTR;
989  }
990  else if (CompareToken(pc, "int64"))
991  {
992  exp.nStackBytes += 8;
993  exp.anArgs[exp.nArgCount] = ARG_INT64;
994  }
995  else if (CompareToken(pc, "int128"))
996  {
997  exp.nStackBytes += 16;
998  exp.anArgs[exp.nArgCount] = ARG_INT128;
999  }
1000  else if (CompareToken(pc, "float"))
1001  {
1002  exp.nStackBytes += 4;
1003  exp.anArgs[exp.nArgCount] = ARG_FLOAT;
1004  }
1005  else
1006  fprintf(stderr, "%s line %d: error: expected type, got: %.10s\n", pszSourceFileName, nLine, pc);
1007 
1008  exp.nArgCount++;
1009 
1010  /* Go to next parameter */
1011  if (!(pc = NextToken(pc)))
1012  {
1013  fprintf(stderr, "fail5\n");
1014  return -15;
1015  }
1016  }
1017 
1018  /* Check syntax */
1019  if (*pc++ != ')')
1020  {
1021  fprintf(stderr, "%s line %d: error: expected ')'\n", pszSourceFileName, nLine);
1022  return -16;
1023  }
1024  }
1025 
1026  /* Handle special stub cases */
1027  if (exp.nCallingConvention == CC_STUB)
1028  {
1029  /* Check for c++ mangled name */
1030  if (pc[0] == '?')
1031  {
1032  //printf("Found c++ mangled name...\n");
1033  //
1034  }
1035  else
1036  {
1037  /* Check for stdcall name */
1038  const char *p = ScanToken(pc, '@');
1039  if (p && (p - pc < exp.strName.len))
1040  {
1041  int i;
1042 
1043  /* Truncate the name to before the @ */
1044  exp.strName.len = (int)(p - pc);
1045  if (exp.strName.len < 1)
1046  {
1047  fprintf(stderr, "%s line %d: error: unexpected @ found\n", pszSourceFileName, nLine);
1048  return -1;
1049  }
1050  exp.nStackBytes = atoi(p + 1);
1051  exp.nArgCount = exp.nStackBytes / 4;
1052  exp.nCallingConvention = CC_STDCALL;
1053  exp.uFlags |= FL_STUB;
1054  for (i = 0; i < exp.nArgCount; i++)
1055  exp.anArgs[i] = ARG_LONG;
1056  }
1057  }
1058  }
1059 
1060  /* Get optional redirection */
1061  pc = NextToken(pc);
1062  if (pc)
1063  {
1064  exp.strTarget.buf = pc;
1065  exp.strTarget.len = TokenLength(pc);
1066 
1067  /* Check syntax (end of line) */
1068  if (NextToken(pc))
1069  {
1070  fprintf(stderr, "%s line %d: error: additional tokens after ')'\n", pszSourceFileName, nLine);
1071  return -17;
1072  }
1073 
1074  /* Don't relay-trace forwarded functions */
1075  exp.uFlags |= FL_NORELAY;
1076  }
1077  else
1078  {
1079  exp.strTarget.buf = NULL;
1080  exp.strTarget.len = 0;
1081  }
1082 
1083  /* Check for no-name without ordinal */
1084  if ((exp.uFlags & FL_ORDINAL) && (exp.nOrdinal == -1))
1085  {
1086  fprintf(stderr, "%s line %d: error: ordinal export without ordinal!\n", pszSourceFileName, nLine);
1087  return -1;
1088  }
1089 
1090  if (!gbMSComp && !gbNotPrivateNoWarn && gbImportLib && !(exp.uFlags & FL_PRIVATE))
1091  {
1092  for (i = 0; i < ARRAYSIZE(astrShouldBePrivate); i++)
1093  {
1094  if (strlen(astrShouldBePrivate[i]) == exp.strName.len &&
1095  strncmp(exp.strName.buf, astrShouldBePrivate[i], exp.strName.len) == 0)
1096  {
1097  fprintf(stderr, "%s line %d: warning: export of '%.*s' should be PRIVATE\n",
1098  pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
1099  }
1100  }
1101  }
1102 
1103  OutputLine(fileDest, &exp);
1104  gbDebug = 0;
1105  }
1106 
1107  return 0;
1108 }
1109 
1110 void usage(void)
1111 {
1112  printf("syntax: spec2def [<options> ...] <spec file>\n"
1113  "Possible options:\n"
1114  " -h --help print this help screen\n"
1115  " -l=<file> generate an asm lib stub\n"
1116  " -d=<file> generate a def file\n"
1117  " -s=<file> generate a stub file\n"
1118  " --ms MSVC compatibility\n"
1119  " -n=<name> name of the dll\n"
1120  " --implib generate a def file for an import library\n"
1121  " --no-private-warnings suppress warnings about symbols that should be -private\n"
1122  " -a=<arch> set architecture to <arch> (i386, x86_64, arm)\n"
1123  " --with-tracing generate wine-like \"+relay\" trace trampolines (needs -s)\n");
1124 }
1125 
1126 int main(int argc, char *argv[])
1127 {
1128  size_t nFileSize;
1129  char *pszSource, *pszDefFileName = NULL, *pszStubFileName = NULL, *pszLibStubName = NULL;
1130  const char* pszVersionOption = "--version=0x";
1131  char achDllName[40];
1132  FILE *file;
1133  int result = 0, i;
1134 
1135  if (argc < 2)
1136  {
1137  usage();
1138  return -1;
1139  }
1140 
1141  /* Read options */
1142  for (i = 1; i < argc && *argv[i] == '-'; i++)
1143  {
1144  if ((strcasecmp(argv[i], "--help") == 0) ||
1145  (strcasecmp(argv[i], "-h") == 0))
1146  {
1147  usage();
1148  return 0;
1149  }
1150  else if (argv[i][1] == 'd' && argv[i][2] == '=')
1151  {
1152  pszDefFileName = argv[i] + 3;
1153  }
1154  else if (argv[i][1] == 'l' && argv[i][2] == '=')
1155  {
1156  pszLibStubName = argv[i] + 3;
1157  }
1158  else if (argv[i][1] == 's' && argv[i][2] == '=')
1159  {
1160  pszStubFileName = argv[i] + 3;
1161  }
1162  else if (argv[i][1] == 'n' && argv[i][2] == '=')
1163  {
1164  pszDllName = argv[i] + 3;
1165  }
1166  else if (strncasecmp(argv[i], pszVersionOption, strlen(pszVersionOption)) == 0)
1167  {
1168  guOsVersion = strtoul(argv[i] + strlen(pszVersionOption), NULL, 16);
1169  }
1170  else if (strcasecmp(argv[i], "--implib") == 0)
1171  {
1172  gbImportLib = 1;
1173  }
1174  else if (strcasecmp(argv[i], "--ms") == 0)
1175  {
1176  gbMSComp = 1;
1177  }
1178  else if (strcasecmp(argv[i], "--no-private-warnings") == 0)
1179  {
1180  gbNotPrivateNoWarn = 1;
1181  }
1182  else if (strcasecmp(argv[i], "--with-tracing") == 0)
1183  {
1184  if (!pszStubFileName)
1185  {
1186  fprintf(stderr, "Error: cannot use --with-tracing without -s option.\n");
1187  return -1;
1188  }
1189  gbTracing = 1;
1190  }
1191  else if (argv[i][1] == 'a' && argv[i][2] == '=')
1192  {
1193  pszArchString = argv[i] + 3;
1194  }
1195  else
1196  {
1197  fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
1198  return -1;
1199  }
1200  }
1201 
1202  if (strcasecmp(pszArchString, "i386") == 0)
1203  {
1204  giArch = ARCH_X86;
1205  gpszUnderscore = "_";
1206  }
1207  else if (strcasecmp(pszArchString, "x86_64") == 0) giArch = ARCH_AMD64;
1208  else if (strcasecmp(pszArchString, "ia64") == 0) giArch = ARCH_IA64;
1209  else if (strcasecmp(pszArchString, "arm") == 0) giArch = ARCH_ARM;
1210  else if (strcasecmp(pszArchString, "ppc") == 0) giArch = ARCH_PPC;
1211 
1212  if ((giArch == ARCH_AMD64) || (giArch == ARCH_IA64))
1213  {
1214  pszArchString2 = "win64";
1215  }
1216  else
1217  pszArchString2 = "win32";
1218 
1219  /* Set a default dll name */
1220  if (!pszDllName)
1221  {
1222  char *p1, *p2;
1223  size_t len;
1224 
1225  p1 = strrchr(argv[i], '\\');
1226  if (!p1) p1 = strrchr(argv[i], '/');
1227  p2 = p1 = p1 ? p1 + 1 : argv[i];
1228 
1229  /* walk up to '.' */
1230  while (*p2 != '.' && *p2 != 0) p2++;
1231  len = p2 - p1;
1232  if (len >= sizeof(achDllName) - 5)
1233  {
1234  fprintf(stderr, "name too long: %s\n", p1);
1235  return -2;
1236  }
1237 
1238  strncpy(achDllName, p1, len);
1239  strncpy(achDllName + len, ".dll", sizeof(achDllName) - len);
1240  pszDllName = achDllName;
1241  }
1242 
1243  /* Open input file */
1245  file = fopen(pszSourceFileName, "r");
1246  if (!file)
1247  {
1248  fprintf(stderr, "error: could not open file %s\n", pszSourceFileName);
1249  return -3;
1250  }
1251 
1252  /* Get file size */
1253  fseek(file, 0, SEEK_END);
1254  nFileSize = ftell(file);
1255  rewind(file);
1256 
1257  /* Allocate memory buffer */
1258  pszSource = malloc(nFileSize + 1);
1259  if (!pszSource)
1260  {
1261  fclose(file);
1262  return -4;
1263  }
1264 
1265  /* Load input file into memory */
1266  nFileSize = fread(pszSource, 1, nFileSize, file);
1267  fclose(file);
1268 
1269  /* Zero terminate the source */
1270  pszSource[nFileSize] = '\0';
1271 
1272  if (pszDefFileName)
1273  {
1274  /* Open output file */
1275  file = fopen(pszDefFileName, "w");
1276  if (!file)
1277  {
1278  fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1279  return -5;
1280  }
1281 
1283  result = ParseFile(pszSource, file, OutputLine_def);
1284  fclose(file);
1285  }
1286 
1287  if (pszStubFileName)
1288  {
1289  /* Open output file */
1290  file = fopen(pszStubFileName, "w");
1291  if (!file)
1292  {
1293  fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1294  return -5;
1295  }
1296 
1298  result = ParseFile(pszSource, file, OutputLine_stub);
1299  fclose(file);
1300  }
1301 
1302  if (pszLibStubName)
1303  {
1304  /* Open output file */
1305  file = fopen(pszLibStubName, "w");
1306  if (!file)
1307  {
1308  fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1309  return -5;
1310  }
1311 
1313  result = ParseFile(pszSource, file, OutputLine_asmstub);
1314  fprintf(file, "\n END\n");
1315  fclose(file);
1316  }
1317 
1318  return result;
1319 }
void PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
Definition: spec2def.c:488
static int argc
Definition: ServiceArgs.c:12
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
STRING strName
Definition: spec2def.c:21
int nOrdinal
Definition: spec2def.c:24
#define strcasecmp
Definition: fake.h:9
int OutputLine_stub(FILE *file, EXPORT *pexp)
Definition: spec2def.c:207
void OutputHeader_stub(FILE *file)
Definition: spec2def.c:191
struct _STRING * PSTRING
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
int gbNotPrivateNoWarn
Definition: spec2def.c:44
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
int nArgCount
Definition: spec2def.c:26
int gbDebug
Definition: spec2def.c:52
const char * astrCallingConventions[]
Definition: spec2def.c:89
char * NextToken(char *pc)
Definition: spec2def.c:173
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define argv
Definition: mplay32.c:18
int OutputLine_def(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:674
void OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:610
char * NextLine(char *pc)
Definition: spec2def.c:151
#define sprintf(buf, format,...)
Definition: sprintf.c:55
void OutputHeader_def(FILE *file, char *libname)
Definition: spec2def.c:478
int nCallingConvention
Definition: spec2def.c:23
#define ARRAYSIZE(a)
Definition: spec2def.c:11
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
int CompareToken(const char *token, const char *comparand)
Definition: spec2def.c:126
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
const char * ScanToken(const char *token, char chr)
Definition: spec2def.c:140
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
struct _EXPORT EXPORT
#define strncasecmp
Definition: fake.h:10
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:64
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
int(* PFNOUTLINE)(FILE *, EXPORT *)
Definition: spec2def.c:41
char * gpszUnderscore
Definition: spec2def.c:51
int main(int argc, char *argv[])
Definition: spec2def.c:1126
_CRTIMP void __cdecl rewind(_Inout_ FILE *_File)
int len
Definition: spec2def.c:16
int gbMSComp
Definition: spec2def.c:42
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
const char file[]
Definition: icontest.c:11
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
void OutputHeader_asmstub(FILE *file, char *libname)
Definition: spec2def.c:395
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
int nNumber
Definition: spec2def.c:29
std::wstring STRING
Definition: fontsub.cpp:33
int giArch
Definition: spec2def.c:46
void Output_stublabel(FILE *fileDest, char *pszSymbolName)
Definition: spec2def.c:414
char * pszSourceFileName
Definition: spec2def.c:49
int ParseFile(char *pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
Definition: spec2def.c:710
GLenum GLsizei len
Definition: glext.h:6722
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
static int IsSeparator(char chr)
Definition: spec2def.c:119
_ARCH
Definition: spec2def.c:32
int chr(char *serport)
Definition: gdblib.c:152
void usage(void)
Definition: spec2def.c:1110
const char * buf
Definition: spec2def.c:15
static const char * astrShouldBePrivate[]
Definition: spec2def.c:98
unsigned int uFlags
Definition: spec2def.c:28
int nStackBytes
Definition: spec2def.c:25
int gbImportLib
Definition: spec2def.c:43
int TokenLength(char *pc)
Definition: spec2def.c:163
DWORD exp
Definition: msg.c:15681
char * pszArchString2
Definition: spec2def.c:48
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
FILE * stderr
#define SEEK_END
Definition: cabinet.c:27
void OutputLine_def_MS(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:560
#define malloc
Definition: debug_ros.c:4
STRING strTarget
Definition: spec2def.c:22
char * pszDllName
Definition: spec2def.c:50
GLfloat GLfloat p
Definition: glext.h:8902
unsigned guOsVersion
Definition: spec2def.c:53
struct _STRING STRING
GLuint64EXT * result
Definition: glext.h:11304
int gbTracing
Definition: spec2def.c:45
int anArgs[30]
Definition: spec2def.c:27
int OutputLine_asmstub(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:433
#define DbgPrint(...)
Definition: spec2def.c:54
#define printf
Definition: config.h:203
char * pszArchString
Definition: spec2def.c:47
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
Definition: fci.c:126