ReactOS  0.4.13-dev-249-gcba1a2f
spec2def.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
Include dependency graph for spec2def.c:

Go to the source code of this file.

Classes

struct  _STRING
 
struct  EXPORT
 

Macros

#define ARRAYSIZE(a)   (sizeof(a) / sizeof((a)[0]))
 
#define DbgPrint(...)   (!gbDebug || fprintf(stderr, __VA_ARGS__))
 

Typedefs

typedef struct _STRING STRING
 
typedef struct _STRINGPSTRING
 
typedef int(* PFNOUTLINE) (FILE *, EXPORT *)
 

Enumerations

enum  _ARCH {
  ARCH_X86, ARCH_AMD64, ARCH_IA64, ARCH_ARM,
  ARCH_PPC
}
 
enum  {
  FL_PRIVATE = 1, FL_STUB = 2, FL_NONAME = 4, FL_ORDINAL = 8,
  FL_NORELAY = 16, FL_RET64 = 32, FL_REGISTER = 64
}
 
enum  {
  CC_STDCALL, CC_CDECL, CC_FASTCALL, CC_THISCALL,
  CC_EXTERN, CC_STUB
}
 
enum  {
  ARG_LONG, ARG_PTR, ARG_STR, ARG_WSTR,
  ARG_DBL, ARG_INT64, ARG_INT128, ARG_FLOAT
}
 

Functions

static int IsSeparator (char chr)
 
int CompareToken (const char *token, const char *comparand)
 
const charScanToken (const char *token, char chr)
 
charNextLine (char *pc)
 
int TokenLength (char *pc)
 
charNextToken (char *pc)
 
void OutputHeader_stub (FILE *file)
 
int OutputLine_stub (FILE *file, EXPORT *pexp)
 
void OutputHeader_asmstub (FILE *file, char *libname)
 
void Output_stublabel (FILE *fileDest, char *pszSymbolName)
 
int OutputLine_asmstub (FILE *fileDest, EXPORT *pexp)
 
void OutputHeader_def (FILE *file, char *libname)
 
void PrintName (FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
 
void OutputLine_def_MS (FILE *fileDest, EXPORT *pexp)
 
void OutputLine_def_GCC (FILE *fileDest, EXPORT *pexp)
 
int OutputLine_def (FILE *fileDest, EXPORT *pexp)
 
int ParseFile (char *pcStart, FILE *fileDest, PFNOUTLINE OutputLine)
 
void usage (void)
 
int main (int argc, char *argv[])
 

Variables

int gbMSComp = 0
 
int gbImportLib = 0
 
int gbNotPrivateNoWarn = 0
 
int gbTracing = 0
 
int giArch = ARCH_X86
 
charpszArchString = "i386"
 
charpszArchString2
 
charpszSourceFileName = NULL
 
charpszDllName = NULL
 
chargpszUnderscore = ""
 
int gbDebug
 
unsigned guOsVersion = 0x502
 
const charastrCallingConventions []
 
static const charastrShouldBePrivate []
 

Macro Definition Documentation

◆ ARRAYSIZE

#define ARRAYSIZE (   a)    (sizeof(a) / sizeof((a)[0]))

Definition at line 11 of file spec2def.c.

◆ DbgPrint

#define DbgPrint (   ...)    (!gbDebug || fprintf(stderr, __VA_ARGS__))

Definition at line 54 of file spec2def.c.

Typedef Documentation

◆ PFNOUTLINE

typedef int(* PFNOUTLINE) (FILE *, EXPORT *)

Definition at line 41 of file spec2def.c.

◆ PSTRING

typedef struct _STRING * PSTRING

◆ STRING

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
FL_PRIVATE 
FL_STUB 
FL_NONAME 
FL_ORDINAL 
FL_NORELAY 
FL_RET64 
FL_REGISTER 

Definition at line 56 of file spec2def.c.

57 {
58  FL_PRIVATE = 1,
59  FL_STUB = 2,
60  FL_NONAME = 4,
61  FL_ORDINAL = 8,
62  FL_NORELAY = 16,
63  FL_RET64 = 32,
64  FL_REGISTER = 64,
65 };

◆ anonymous enum

anonymous enum
Enumerator
CC_STDCALL 
CC_CDECL 
CC_FASTCALL 
CC_THISCALL 
CC_EXTERN 
CC_STUB 

Definition at line 67 of file spec2def.c.

68 {
69  CC_STDCALL,
70  CC_CDECL,
73  CC_EXTERN,
74  CC_STUB,
75 };

◆ anonymous enum

anonymous enum
Enumerator
ARG_LONG 
ARG_PTR 
ARG_STR 
ARG_WSTR 
ARG_DBL 
ARG_INT64 
ARG_INT128 
ARG_FLOAT 

Definition at line 77 of file spec2def.c.

78 {
79  ARG_LONG,
80  ARG_PTR,
81  ARG_STR,
82  ARG_WSTR,
83  ARG_DBL,
84  ARG_INT64,
85  ARG_INT128,
86  ARG_FLOAT
87 };

◆ _ARCH

Enumerator
ARCH_X86 
ARCH_AMD64 
ARCH_IA64 
ARCH_ARM 
ARCH_PPC 

Definition at line 32 of file spec2def.c.

33 {
34  ARCH_X86,
35  ARCH_AMD64,
36  ARCH_IA64,
37  ARCH_ARM,
38  ARCH_PPC
39 };

Function Documentation

◆ CompareToken()

int CompareToken ( const char token,
const char comparand 
)

Definition at line 126 of file spec2def.c.

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 }
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
static int IsSeparator(char chr)
Definition: spec2def.c:119

Referenced by ParseFile().

◆ IsSeparator()

static int IsSeparator ( char  chr)
static

Definition at line 119 of file spec2def.c.

120 {
121  return ((chr <= ',' && chr != '$' && chr != '#') ||
122  (chr >= ':' && chr < '?') );
123 }
int chr(char *serport)
Definition: gdblib.c:152

Referenced by CompareToken(), NextToken(), ScanToken(), and TokenLength().

◆ main()

int main ( int argc  ,
char argv[] 
)

hosttype.c Copyright (C) 2002 by Brian Palmer brian.nosp@m.p@sg.nosp@m.inet..nosp@m.com

Definition at line 1126 of file spec2def.c.

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 }
static int argc
Definition: ServiceArgs.c:12
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
#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
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int gbNotPrivateNoWarn
Definition: spec2def.c:44
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
_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 OutputHeader_def(FILE *file, char *libname)
Definition: spec2def.c:478
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
_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)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define strncasecmp
Definition: fake.h:10
smooth NULL
Definition: ftsmooth.c:416
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
char * gpszUnderscore
Definition: spec2def.c:51
_CRTIMP void __cdecl rewind(_Inout_ FILE *_File)
int gbMSComp
Definition: spec2def.c:42
const char file[]
Definition: icontest.c:11
void OutputHeader_asmstub(FILE *file, char *libname)
Definition: spec2def.c:395
int giArch
Definition: spec2def.c:46
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)
void usage(void)
Definition: spec2def.c:1110
int gbImportLib
Definition: spec2def.c:43
char * pszArchString2
Definition: spec2def.c:48
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
FILE * stderr
#define SEEK_END
Definition: cabinet.c:27
#define malloc
Definition: debug_ros.c:4
char * pszDllName
Definition: spec2def.c:50
unsigned guOsVersion
Definition: spec2def.c:53
GLuint64EXT * result
Definition: glext.h:11304
int gbTracing
Definition: spec2def.c:45
int OutputLine_asmstub(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:433
char * pszArchString
Definition: spec2def.c:47
Definition: fci.c:126

◆ NextLine()

char* NextLine ( char pc)

Definition at line 151 of file spec2def.c.

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 }

Referenced by ParseFile().

◆ NextToken()

char* NextToken ( char pc)

Definition at line 173 of file spec2def.c.

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 }
static int IsSeparator(char chr)
Definition: spec2def.c:119

Referenced by ParseFile().

◆ Output_stublabel()

void Output_stublabel ( FILE fileDest,
char pszSymbolName 
)

Definition at line 414 of file spec2def.c.

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 }
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int giArch
Definition: spec2def.c:46

Referenced by OutputLine_asmstub().

◆ OutputHeader_asmstub()

void OutputHeader_asmstub ( FILE file,
char libname 
)

Definition at line 395 of file spec2def.c.

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 }
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int giArch
Definition: spec2def.c:46
Definition: fci.c:126

Referenced by main().

◆ OutputHeader_def()

void OutputHeader_def ( FILE file,
char libname 
)

Definition at line 478 of file spec2def.c.

479 {
480  fprintf(file,
481  "; File generated automatically, do not edit!\n\n"
482  "NAME %s\n\n"
483  "EXPORTS\n",
484  libname);
485 }
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
Definition: fci.c:126

Referenced by main().

◆ OutputHeader_stub()

void OutputHeader_stub ( FILE file)

Definition at line 191 of file spec2def.c.

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 }
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int gbTracing
Definition: spec2def.c:45
Definition: fci.c:126

Referenced by main().

◆ OutputLine_asmstub()

int OutputLine_asmstub ( FILE fileDest,
EXPORT pexp 
)

Definition at line 433 of file spec2def.c.

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 }
STRING strName
Definition: spec2def.c:21
int nOrdinal
Definition: spec2def.c:24
#define sprintf(buf, format,...)
Definition: sprintf.c:55
int nCallingConvention
Definition: spec2def.c:23
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
char * gpszUnderscore
Definition: spec2def.c:51
int giArch
Definition: spec2def.c:46
void Output_stublabel(FILE *fileDest, char *pszSymbolName)
Definition: spec2def.c:414
int nStackBytes
Definition: spec2def.c:25
FILE * stderr

Referenced by main().

◆ OutputLine_def()

int OutputLine_def ( FILE fileDest,
EXPORT pexp 
)

Definition at line 674 of file spec2def.c.

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 }
STRING strName
Definition: spec2def.c:21
int nOrdinal
Definition: spec2def.c:24
void OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:610
int nCallingConvention
Definition: spec2def.c:23
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int gbMSComp
Definition: spec2def.c:42
unsigned int uFlags
Definition: spec2def.c:28
void OutputLine_def_MS(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:560
#define DbgPrint(...)
Definition: spec2def.c:54

Referenced by main().

◆ OutputLine_def_GCC()

void OutputLine_def_GCC ( FILE fileDest,
EXPORT pexp 
)

Definition at line 610 of file spec2def.c.

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 }
void PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
Definition: spec2def.c:488
STRING strName
Definition: spec2def.c:21
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define sprintf(buf, format,...)
Definition: sprintf.c:55
int nCallingConvention
Definition: spec2def.c:23
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,...)
int nNumber
Definition: spec2def.c:29
std::wstring STRING
Definition: fontsub.cpp:33
int giArch
Definition: spec2def.c:46
unsigned int uFlags
Definition: spec2def.c:28
int gbImportLib
Definition: spec2def.c:43
STRING strTarget
Definition: spec2def.c:22
int gbTracing
Definition: spec2def.c:45
#define DbgPrint(...)
Definition: spec2def.c:54

Referenced by OutputLine_def().

◆ OutputLine_def_MS()

void OutputLine_def_MS ( FILE fileDest,
EXPORT pexp 
)

Definition at line 560 of file spec2def.c.

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 }
void PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
Definition: spec2def.c:488
STRING strName
Definition: spec2def.c:21
int nCallingConvention
Definition: spec2def.c:23
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,...)
int nNumber
Definition: spec2def.c:29
int giArch
Definition: spec2def.c:46
unsigned int uFlags
Definition: spec2def.c:28
int gbImportLib
Definition: spec2def.c:43
STRING strTarget
Definition: spec2def.c:22
int gbTracing
Definition: spec2def.c:45

Referenced by OutputLine_def().

◆ OutputLine_stub()

int OutputLine_stub ( FILE file,
EXPORT pexp 
)

Definition at line 207 of file spec2def.c.

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 }
STRING strName
Definition: spec2def.c:21
int nArgCount
Definition: spec2def.c:26
int nCallingConvention
Definition: spec2def.c:23
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
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int nNumber
Definition: spec2def.c:29
int giArch
Definition: spec2def.c:46
unsigned int uFlags
Definition: spec2def.c:28
char * pszDllName
Definition: spec2def.c:50
int gbTracing
Definition: spec2def.c:45
int anArgs[30]
Definition: spec2def.c:27
Definition: fci.c:126

Referenced by main().

◆ ParseFile()

int ParseFile ( char pcStart,
FILE fileDest,
PFNOUTLINE  OutputLine 
)

Definition at line 710 of file spec2def.c.

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 }
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int gbNotPrivateNoWarn
Definition: spec2def.c:44
int gbDebug
Definition: spec2def.c:52
char * NextToken(char *pc)
Definition: spec2def.c:173
char * NextLine(char *pc)
Definition: spec2def.c:151
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#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
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,...)
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:64
int gbMSComp
Definition: spec2def.c:42
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
int giArch
Definition: spec2def.c:46
char * pszSourceFileName
Definition: spec2def.c:49
static const char * astrShouldBePrivate[]
Definition: spec2def.c:98
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)
FILE * stderr
GLfloat GLfloat p
Definition: glext.h:8902
unsigned guOsVersion
Definition: spec2def.c:53
#define DbgPrint(...)
Definition: spec2def.c:54
char * pszArchString
Definition: spec2def.c:47
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

Referenced by main().

◆ PrintName()

void PrintName ( FILE fileDest,
EXPORT pexp,
PSTRING  pstr,
int  fDeco 
)

Definition at line 488 of file spec2def.c.

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 = (int)(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 = (int)(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 }
int nCallingConvention
Definition: spec2def.c:23
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,...)
int len
Definition: spec2def.c:16
int gbMSComp
Definition: spec2def.c:42
int giArch
Definition: spec2def.c:46
const char * buf
Definition: spec2def.c:15
int nStackBytes
Definition: spec2def.c:25
STRING strTarget
Definition: spec2def.c:22
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

Referenced by OutputLine_def_GCC(), OutputLine_def_MS(), and Defragment::Start().

◆ ScanToken()

const char* ScanToken ( const char token,
char  chr 
)

Definition at line 140 of file spec2def.c.

141 {
142  while (!IsSeparator(*token))
143  {
144  if (*token == chr) return token;
145  token++;
146  }
147  return 0;
148 }
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
static int IsSeparator(char chr)
Definition: spec2def.c:119
int chr(char *serport)
Definition: gdblib.c:152

Referenced by OutputLine_def_GCC(), OutputLine_def_MS(), ParseFile(), and PrintName().

◆ TokenLength()

int TokenLength ( char pc)

Definition at line 163 of file spec2def.c.

164 {
165  int length = 0;
166 
167  while (!IsSeparator(*pc++)) length++;
168 
169  return length;
170 }
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static int IsSeparator(char chr)
Definition: spec2def.c:119

Referenced by ParseFile(), and SmpParseToken().

◆ usage()

void usage ( void  )

Definition at line 1110 of file spec2def.c.

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 }
#define printf
Definition: config.h:203

Referenced by main().

Variable Documentation

◆ astrCallingConventions

const char* astrCallingConventions[]
Initial value:
=
{
"STDCALL",
"CDECL",
"FASTCALL",
"THISCALL",
"EXTERN"
}

Definition at line 89 of file spec2def.c.

◆ astrShouldBePrivate

const char* astrShouldBePrivate[]
static
Initial value:
=
{
"DllCanUnloadNow",
"DllGetClassObject",
"DllGetClassFactoryFromClassString",
"DllGetDocumentation",
"DllInitialize",
"DllInstall",
"DllRegisterServer",
"DllRegisterServerEx",
"DllRegisterServerExW",
"DllUnload",
"DllUnregisterServer",
"RasCustomDeleteEntryNotify",
"RasCustomDial",
"RasCustomDialDlg",
"RasCustomEntryDlg",
}

Definition at line 98 of file spec2def.c.

Referenced by ParseFile().

◆ gbDebug

int gbDebug

Definition at line 52 of file spec2def.c.

Referenced by ParseFile().

◆ gbImportLib

int gbImportLib = 0

Definition at line 43 of file spec2def.c.

Referenced by main(), OutputLine_def_GCC(), OutputLine_def_MS(), and ParseFile().

◆ gbMSComp

int gbMSComp = 0

Definition at line 42 of file spec2def.c.

Referenced by main(), OutputLine_def(), ParseFile(), and PrintName().

◆ gbNotPrivateNoWarn

int gbNotPrivateNoWarn = 0

Definition at line 44 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ gbTracing

int gbTracing = 0

◆ giArch

◆ gpszUnderscore

char* gpszUnderscore = ""

Definition at line 51 of file spec2def.c.

Referenced by main(), and OutputLine_asmstub().

◆ guOsVersion

unsigned guOsVersion = 0x502

Definition at line 53 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszArchString

char* pszArchString = "i386"

Definition at line 47 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszArchString2

char* pszArchString2

Definition at line 48 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszDllName

char* pszDllName = NULL

Definition at line 50 of file spec2def.c.

Referenced by main(), and OutputLine_stub().

◆ pszSourceFileName

char* pszSourceFileName = NULL

Definition at line 49 of file spec2def.c.

Referenced by main(), and ParseFile().