ReactOS  0.4.14-dev-815-ge410a12
spec2def.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdarg.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)
 
const charNextLine (const char *pc)
 
int TokenLength (const char *pc)
 
const charNextToken (const 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)
 
void Fatalv (const char *filename, unsigned nLine, const char *pcLine, const char *pc, size_t errorlen, const char *format, va_list argptr)
 
void Fatal (const char *filename, unsigned nLine, const char *pcLine, const char *pc, size_t errorlen, const char *format,...)
 
EXPORTParseFile (char *pcStart, FILE *fileDest, unsigned *cExports)
 
int ApplyOrdinals (EXPORT *pexports, unsigned cExports)
 
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 charastrOlePrivateExports []
 

Macro Definition Documentation

◆ ARRAYSIZE

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

Definition at line 12 of file spec2def.c.

◆ DbgPrint

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

Definition at line 76 of file spec2def.c.

Typedef Documentation

◆ PFNOUTLINE

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

Definition at line 63 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 78 of file spec2def.c.

79 {
80  FL_PRIVATE = 1,
81  FL_STUB = 2,
82  FL_NONAME = 4,
83  FL_ORDINAL = 8,
84  FL_NORELAY = 16,
85  FL_RET64 = 32,
86  FL_REGISTER = 64,
87 };

◆ anonymous enum

anonymous enum
Enumerator
CC_STDCALL 
CC_CDECL 
CC_FASTCALL 
CC_THISCALL 
CC_EXTERN 
CC_STUB 

Definition at line 89 of file spec2def.c.

90 {
91  CC_STDCALL,
92  CC_CDECL,
95  CC_EXTERN,
96  CC_STUB,
97 };

◆ anonymous enum

anonymous enum
Enumerator
ARG_LONG 
ARG_PTR 
ARG_STR 
ARG_WSTR 
ARG_DBL 
ARG_INT64 
ARG_INT128 
ARG_FLOAT 

Definition at line 99 of file spec2def.c.

100 {
101  ARG_LONG,
102  ARG_PTR,
103  ARG_STR,
104  ARG_WSTR,
105  ARG_DBL,
106  ARG_INT64,
107  ARG_INT128,
108  ARG_FLOAT
109 };

◆ _ARCH

Enumerator
ARCH_X86 
ARCH_AMD64 
ARCH_IA64 
ARCH_ARM 
ARCH_PPC 

Definition at line 54 of file spec2def.c.

55 {
56  ARCH_X86,
57  ARCH_AMD64,
58  ARCH_IA64,
59  ARCH_ARM,
60  ARCH_PPC
61 };

Function Documentation

◆ ApplyOrdinals()

int ApplyOrdinals ( EXPORT pexports,
unsigned  cExports 
)

Definition at line 1304 of file spec2def.c.

1305 {
1306  unsigned short i, j;
1307  char* used;
1308 
1309  /* Allocate a table to mark used ordinals */
1310  used = malloc(65536);
1311  if (used == NULL)
1312  {
1313  fprintf(stderr, "Failed to allocate memory for ordinal use table\n");
1314  return -1;
1315  }
1316  memset(used, 0, 65536);
1317 
1318  /* Pass 1: mark the ordinals that are already used */
1319  for (i = 0; i < cExports; i++)
1320  {
1321  if (pexports[i].uFlags & FL_ORDINAL)
1322  {
1323  if (used[pexports[i].nOrdinal] != 0)
1324  {
1325  fprintf(stderr, "Found duplicate ordinal: %u\n", pexports[i].nOrdinal);
1326  return -1;
1327  }
1328  used[pexports[i].nOrdinal] = 1;
1329  }
1330  }
1331 
1332  /* Pass 2: apply available ordinals */
1333  for (i = 0, j = 1; i < cExports; i++)
1334  {
1335  if ((pexports[i].uFlags & FL_ORDINAL) == 0)
1336  {
1337  while (used[j] != 0)
1338  j++;
1339 
1340  pexports[i].nOrdinal = j;
1341  used[j] = 1;
1342  }
1343  }
1344 
1345  free(used);
1346  return 0;
1347 }
int nOrdinal
Definition: spec2def.c:25
#define free
Definition: debug_ros.c:5
UINT uFlags
Definition: api.c:59
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,...)
smooth NULL
Definition: ftsmooth.c:416
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 GLint GLint j
Definition: glfuncs.h:250
c used
Definition: write.c:2877
FILE * stderr
#define malloc
Definition: debug_ros.c:4
#define memset(x, y, z)
Definition: compat.h:39

Referenced by main().

◆ CompareToken()

int CompareToken ( const char token,
const char comparand 
)

Definition at line 153 of file spec2def.c.

154 {
155  while (*comparand)
156  {
157  if (*token != *comparand) return 0;
158  token++;
159  comparand++;
160  }
161  if (IsSeparator(comparand[-1])) return 1;
162  if (!IsSeparator(*token)) return 0;
163  return 1;
164 }
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:146

Referenced by ParseFile().

◆ Fatal()

void Fatal ( const char filename,
unsigned  nLine,
const char pcLine,
const char pc,
size_t  errorlen,
const char format,
  ... 
)

Definition at line 812 of file spec2def.c.

820 {
821  va_list argptr;
822 
823  va_start(argptr, format);
824  Fatalv(filename, nLine, pcLine, pc, errorlen, format, argptr);
825  va_end(argptr);
826 }
const char * filename
Definition: ioapi.h:135
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
void Fatalv(const char *filename, unsigned nLine, const char *pcLine, const char *pc, size_t errorlen, const char *format, va_list argptr)
Definition: spec2def.c:762
#define va_end(ap)
Definition: acmsvcex.h:90
char * va_list
Definition: acmsvcex.h:78
#define va_start(ap, A)
Definition: acmsvcex.h:91

Referenced by AcpiExOpcode_3A_0T_0R(), and ParseFile().

◆ Fatalv()

void Fatalv ( const char filename,
unsigned  nLine,
const char pcLine,
const char pc,
size_t  errorlen,
const char format,
va_list  argptr 
)

Definition at line 762 of file spec2def.c.

770 {
771  unsigned i, errorpos, len;
772  const char* pcLineEnd;
773 
774  /* Get the length of the line */
775  pcLineEnd = strpbrk(pcLine, "\r\n");
776  len = (unsigned)(pcLineEnd - pcLine);
777 
778  if (pc == NULL)
779  {
780  pc = pcLine + len - 1;
781  errorlen = 1;
782  }
783 
784  errorpos = (unsigned)(pc - pcLine);
785 
786  /* Output the error message */
787  fprintf(stderr, "ERROR: (%s:%u:%u): ", filename, nLine, errorpos);
788  vfprintf(stderr, format, argptr);
789  fprintf(stderr, "\n");
790 
791  /* Output the line with the error */
792  fprintf(stderr, "> %.*s\n", len, pcLine);
793 
794  if (errorlen == 0)
795  {
796  errorlen = TokenLength(pc);
797  }
798 
799  for (i = 0; i < errorpos + 2; i++)
800  {
801  fprintf(stderr, " ");
802  }
803  for (i = 0; i < errorlen; i++)
804  {
805  fprintf(stderr, "~");
806  }
807  fprintf(stderr, "\n");
808  exit(-1);
809 }
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
const char * filename
Definition: ioapi.h:135
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
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,...)
smooth NULL
Definition: ftsmooth.c:416
GLenum GLsizei len
Definition: glext.h:6722
int TokenLength(const char *pc)
Definition: spec2def.c:190
FILE * stderr
void exit(int exitcode)
Definition: _exit.c:33
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
static unsigned(__cdecl *hash_bstr)(bstr_t s)

Referenced by Fatal().

◆ IsSeparator()

static int IsSeparator ( char  chr)
static

Definition at line 146 of file spec2def.c.

147 {
148  return ((chr <= ',' && chr != '$' && chr != '#') ||
149  (chr >= ':' && chr < '?') );
150 }
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 1365 of file spec2def.c.

1366 {
1367  size_t nFileSize;
1368  char *pszSource, *pszDefFileName = NULL, *pszStubFileName = NULL, *pszLibStubName = NULL;
1369  const char* pszVersionOption = "--version=0x";
1370  char achDllName[40];
1371  FILE *file;
1372  unsigned cExports = 0, i;
1373  EXPORT *pexports;
1374 
1375  if (argc < 2)
1376  {
1377  usage();
1378  return -1;
1379  }
1380 
1381  /* Read options */
1382  for (i = 1; i < (unsigned)argc && *argv[i] == '-'; i++)
1383  {
1384  if ((strcasecmp(argv[i], "--help") == 0) ||
1385  (strcasecmp(argv[i], "-h") == 0))
1386  {
1387  usage();
1388  return 0;
1389  }
1390  else if (argv[i][1] == 'd' && argv[i][2] == '=')
1391  {
1392  pszDefFileName = argv[i] + 3;
1393  }
1394  else if (argv[i][1] == 'l' && argv[i][2] == '=')
1395  {
1396  pszLibStubName = argv[i] + 3;
1397  }
1398  else if (argv[i][1] == 's' && argv[i][2] == '=')
1399  {
1400  pszStubFileName = argv[i] + 3;
1401  }
1402  else if (argv[i][1] == 'n' && argv[i][2] == '=')
1403  {
1404  pszDllName = argv[i] + 3;
1405  }
1406  else if (strncasecmp(argv[i], pszVersionOption, strlen(pszVersionOption)) == 0)
1407  {
1408  guOsVersion = strtoul(argv[i] + strlen(pszVersionOption), NULL, 16);
1409  }
1410  else if (strcasecmp(argv[i], "--implib") == 0)
1411  {
1412  gbImportLib = 1;
1413  }
1414  else if (strcasecmp(argv[i], "--ms") == 0)
1415  {
1416  gbMSComp = 1;
1417  }
1418  else if (strcasecmp(argv[i], "--no-private-warnings") == 0)
1419  {
1420  gbNotPrivateNoWarn = 1;
1421  }
1422  else if (strcasecmp(argv[i], "--with-tracing") == 0)
1423  {
1424  if (!pszStubFileName)
1425  {
1426  fprintf(stderr, "Error: cannot use --with-tracing without -s option.\n");
1427  return -1;
1428  }
1429  gbTracing = 1;
1430  }
1431  else if (argv[i][1] == 'a' && argv[i][2] == '=')
1432  {
1433  pszArchString = argv[i] + 3;
1434  }
1435  else
1436  {
1437  fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
1438  return -1;
1439  }
1440  }
1441 
1442  if (strcasecmp(pszArchString, "i386") == 0)
1443  {
1444  giArch = ARCH_X86;
1445  gpszUnderscore = "_";
1446  }
1447  else if (strcasecmp(pszArchString, "x86_64") == 0) giArch = ARCH_AMD64;
1448  else if (strcasecmp(pszArchString, "ia64") == 0) giArch = ARCH_IA64;
1449  else if (strcasecmp(pszArchString, "arm") == 0) giArch = ARCH_ARM;
1450  else if (strcasecmp(pszArchString, "ppc") == 0) giArch = ARCH_PPC;
1451 
1452  if ((giArch == ARCH_AMD64) || (giArch == ARCH_IA64))
1453  {
1454  pszArchString2 = "win64";
1455  }
1456  else
1457  pszArchString2 = "win32";
1458 
1459  /* Set a default dll name */
1460  if (!pszDllName)
1461  {
1462  char *p1, *p2;
1463  size_t len;
1464 
1465  p1 = strrchr(argv[i], '\\');
1466  if (!p1) p1 = strrchr(argv[i], '/');
1467  p2 = p1 = p1 ? p1 + 1 : argv[i];
1468 
1469  /* walk up to '.' */
1470  while (*p2 != '.' && *p2 != 0) p2++;
1471  len = p2 - p1;
1472  if (len >= sizeof(achDllName) - 5)
1473  {
1474  fprintf(stderr, "name too long: %s\n", p1);
1475  return -2;
1476  }
1477 
1478  strncpy(achDllName, p1, len);
1479  strncpy(achDllName + len, ".dll", sizeof(achDllName) - len);
1480  pszDllName = achDllName;
1481  }
1482 
1483  /* Open input file */
1485  file = fopen(pszSourceFileName, "r");
1486  if (!file)
1487  {
1488  fprintf(stderr, "error: could not open file %s\n", pszSourceFileName);
1489  return -3;
1490  }
1491 
1492  /* Get file size */
1493  fseek(file, 0, SEEK_END);
1494  nFileSize = ftell(file);
1495  rewind(file);
1496 
1497  /* Allocate memory buffer */
1498  pszSource = malloc(nFileSize + 1);
1499  if (!pszSource)
1500  {
1501  fclose(file);
1502  return -4;
1503  }
1504 
1505  /* Load input file into memory */
1506  nFileSize = fread(pszSource, 1, nFileSize, file);
1507  fclose(file);
1508 
1509  /* Zero terminate the source */
1510  pszSource[nFileSize] = '\0';
1511 
1512  pexports = ParseFile(pszSource, file, &cExports);
1513  if (pexports == NULL)
1514  {
1515  fprintf(stderr, "error: could not parse file!\n");
1516  return -1;
1517  }
1518 
1519  if (!gbMSComp)
1520  {
1521  if (ApplyOrdinals(pexports, cExports) < 0)
1522  {
1523  fprintf(stderr, "error: could not apply ordinals!\n");
1524  return -1;
1525  }
1526  }
1527 
1528  if (pszDefFileName)
1529  {
1530  /* Open output file */
1531  file = fopen(pszDefFileName, "w");
1532  if (!file)
1533  {
1534  fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1535  return -5;
1536  }
1537 
1539 
1540  for (i = 0; i < cExports; i++)
1541  {
1542  if (pexports[i].bVersionIncluded)
1543  OutputLine_def(file, &pexports[i]);
1544  }
1545 
1546  fclose(file);
1547  }
1548 
1549  if (pszStubFileName)
1550  {
1551  /* Open output file */
1552  file = fopen(pszStubFileName, "w");
1553  if (!file)
1554  {
1555  fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1556  return -5;
1557  }
1558 
1560 
1561  for (i = 0; i < cExports; i++)
1562  {
1563  if (pexports[i].bVersionIncluded)
1564  OutputLine_stub(file, &pexports[i]);
1565  }
1566 
1567  fclose(file);
1568  }
1569 
1570  if (pszLibStubName)
1571  {
1572  /* Open output file */
1573  file = fopen(pszLibStubName, "w");
1574  if (!file)
1575  {
1576  fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1577  return -5;
1578  }
1579 
1581 
1582  for (i = 0; i < cExports; i++)
1583  {
1584  if (pexports[i].bVersionIncluded)
1585  OutputLine_asmstub(file, &pexports[i]);
1586  }
1587 
1588  fprintf(file, "\n END\n");
1589  fclose(file);
1590  }
1591 
1592  free(pexports);
1593 
1594  return 0;
1595 }
static int argc
Definition: ServiceArgs.c:12
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
int ApplyOrdinals(EXPORT *pexports, unsigned cExports)
Definition: spec2def.c:1304
#define strcasecmp
Definition: fake.h:9
int OutputLine_stub(FILE *file, EXPORT *pexp)
Definition: spec2def.c:234
void OutputHeader_stub(FILE *file)
Definition: spec2def.c:218
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int gbNotPrivateNoWarn
Definition: spec2def.c:66
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define free
Definition: debug_ros.c:5
_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:725
void OutputHeader_def(FILE *file, char *libname)
Definition: spec2def.c:518
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:73
_CRTIMP void __cdecl rewind(_Inout_ FILE *_File)
int gbMSComp
Definition: spec2def.c:64
const char file[]
Definition: icontest.c:11
void OutputHeader_asmstub(FILE *file, char *libname)
Definition: spec2def.c:422
int giArch
Definition: spec2def.c:68
char * pszSourceFileName
Definition: spec2def.c:71
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:1349
EXPORT * ParseFile(char *pcStart, FILE *fileDest, unsigned *cExports)
Definition: spec2def.c:829
int gbImportLib
Definition: spec2def.c:65
char * pszArchString2
Definition: spec2def.c:70
_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:72
unsigned guOsVersion
Definition: spec2def.c:75
int gbTracing
Definition: spec2def.c:67
int OutputLine_asmstub(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:460
static unsigned(__cdecl *hash_bstr)(bstr_t s)
char * pszArchString
Definition: spec2def.c:69
Definition: fci.c:126

◆ NextLine()

const char* NextLine ( const char pc)

Definition at line 178 of file spec2def.c.

179 {
180  while (*pc != 0)
181  {
182  if (pc[0] == '\n' && pc[1] == '\r') return pc + 2;
183  else if (pc[0] == '\n') return pc + 1;
184  pc++;
185  }
186  return pc;
187 }

Referenced by ParseFile().

◆ NextToken()

const char* NextToken ( const char pc)

Definition at line 200 of file spec2def.c.

201 {
202  /* Skip token */
203  while (!IsSeparator(*pc)) pc++;
204 
205  /* Skip white spaces */
206  while (*pc == ' ' || *pc == '\t') pc++;
207 
208  /* Check for end of line */
209  if (*pc == '\n' || *pc == '\r' || *pc == 0) return 0;
210 
211  /* Check for comment */
212  if (*pc == '#' || *pc == ';') return 0;
213 
214  return pc;
215 }
static int IsSeparator(char chr)
Definition: spec2def.c:146

Referenced by ParseFile().

◆ Output_stublabel()

void Output_stublabel ( FILE fileDest,
char pszSymbolName 
)

Definition at line 441 of file spec2def.c.

442 {
443  if (giArch == ARCH_ARM)
444  {
445  fprintf(fileDest,
446  "\tEXPORT |%s| [FUNC]\n|%s|\n",
447  pszSymbolName,
448  pszSymbolName);
449  }
450  else
451  {
452  fprintf(fileDest,
453  "PUBLIC %s\n%s: nop\n",
454  pszSymbolName,
455  pszSymbolName);
456  }
457 }
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int giArch
Definition: spec2def.c:68

Referenced by OutputLine_asmstub().

◆ OutputHeader_asmstub()

void OutputHeader_asmstub ( FILE file,
char libname 
)

Definition at line 422 of file spec2def.c.

423 {
424  fprintf(file, "; File generated automatically, do not edit! \n\n");
425 
426  if (giArch == ARCH_X86)
427  {
428  fprintf(file, ".586\n.model flat\n.code\n");
429  }
430  else if (giArch == ARCH_AMD64)
431  {
432  fprintf(file, ".code\n");
433  }
434  else if (giArch == ARCH_ARM)
435  {
436  fprintf(file, " AREA |.text|,ALIGN=2,CODE,READONLY\n\n");
437  }
438 }
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int giArch
Definition: spec2def.c:68
Definition: fci.c:126

Referenced by main().

◆ OutputHeader_def()

void OutputHeader_def ( FILE file,
char libname 
)

Definition at line 518 of file spec2def.c.

519 {
520  fprintf(file,
521  "; File generated automatically, do not edit!\n\n"
522  "NAME %s\n\n"
523  "EXPORTS\n",
524  libname);
525 }
_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 218 of file spec2def.c.

219 {
220  fprintf(file, "/* This file is autogenerated, do not edit. */\n\n"
221  "#include <stubs.h>\n");
222 
223  if (gbTracing)
224  {
225  fprintf(file, "#include <wine/debug.h>\n");
226  fprintf(file, "#include <inttypes.h>\n");
227  fprintf(file, "WINE_DECLARE_DEBUG_CHANNEL(relay);\n");
228  }
229 
230  fprintf(file, "\n");
231 }
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int gbTracing
Definition: spec2def.c:67
Definition: fci.c:126

Referenced by main().

◆ OutputLine_asmstub()

int OutputLine_asmstub ( FILE fileDest,
EXPORT pexp 
)

Definition at line 460 of file spec2def.c.

461 {
462  char szNameBuffer[128];
463 
464  /* Handle autoname */
465  if (pexp->strName.len == 1 && pexp->strName.buf[0] == '@')
466  {
467  sprintf(szNameBuffer, "%s_stub_ordinal%d",
468  gpszUnderscore, pexp->nOrdinal);
469  }
470  else if (giArch != ARCH_X86)
471  {
472  /* Does the string already have stdcall decoration? */
473  const char *pcAt = ScanToken(pexp->strName.buf, '@');
474  if (pcAt && (pcAt < (pexp->strName.buf + pexp->strName.len)) &&
475  (pexp->strName.buf[0] == '_'))
476  {
477  /* Skip leading underscore and remove trailing decoration */
478  sprintf(szNameBuffer, "_stub_%.*s",
479  (int)(pcAt - pexp->strName.buf - 1),
480  pexp->strName.buf + 1);
481  }
482  else
483  {
484  sprintf(szNameBuffer, "_stub_%.*s",
485  pexp->strName.len, pexp->strName.buf);
486  }
487  }
488  else if (pexp->nCallingConvention == CC_STDCALL)
489  {
490  sprintf(szNameBuffer, "__stub_%.*s@%d",
491  pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
492  }
493  else if (pexp->nCallingConvention == CC_FASTCALL)
494  {
495  sprintf(szNameBuffer, "@_stub_%.*s@%d",
496  pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
497  }
498  else if ((pexp->nCallingConvention == CC_CDECL) ||
499  (pexp->nCallingConvention == CC_THISCALL) ||
500  (pexp->nCallingConvention == CC_EXTERN) ||
501  (pexp->nCallingConvention == CC_STUB))
502  {
503  sprintf(szNameBuffer, "__stub_%.*s",
504  pexp->strName.len, pexp->strName.buf);
505  }
506  else
507  {
508  fprintf(stderr, "Invalid calling convention");
509  return 0;
510  }
511 
512  Output_stublabel(fileDest, szNameBuffer);
513 
514  return 1;
515 }
STRING strName
Definition: spec2def.c:22
int nOrdinal
Definition: spec2def.c:25
#define sprintf(buf, format,...)
Definition: sprintf.c:55
int nCallingConvention
Definition: spec2def.c:24
const char * ScanToken(const char *token, char chr)
Definition: spec2def.c:167
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
char * gpszUnderscore
Definition: spec2def.c:73
int giArch
Definition: spec2def.c:68
void Output_stublabel(FILE *fileDest, char *pszSymbolName)
Definition: spec2def.c:441
int nStackBytes
Definition: spec2def.c:26
FILE * stderr

Referenced by main().

◆ OutputLine_def()

int OutputLine_def ( FILE fileDest,
EXPORT pexp 
)

Definition at line 725 of file spec2def.c.

726 {
727  DbgPrint("OutputLine_def: '%.*s'...\n", pexp->strName.len, pexp->strName.buf);
728  fprintf(fileDest, " ");
729 
730  if (gbMSComp)
731  OutputLine_def_MS(fileDest, pexp);
732  else
733  OutputLine_def_GCC(fileDest, pexp);
734 
735  /* On GCC builds we force ordinals */
736  if ((pexp->uFlags & FL_ORDINAL) || (!gbMSComp && !gbImportLib))
737  {
738  fprintf(fileDest, " @%d", pexp->nOrdinal);
739  }
740 
741  if (pexp->uFlags & FL_NONAME)
742  {
743  fprintf(fileDest, " NONAME");
744  }
745 
746  /* Either PRIVATE or DATA */
747  if (pexp->uFlags & FL_PRIVATE)
748  {
749  fprintf(fileDest, " PRIVATE");
750  }
751  else if (pexp->nCallingConvention == CC_EXTERN)
752  {
753  fprintf(fileDest, " DATA");
754  }
755 
756  fprintf(fileDest, "\n");
757 
758  return 1;
759 }
STRING strName
Definition: spec2def.c:22
int nOrdinal
Definition: spec2def.c:25
void OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:659
int nCallingConvention
Definition: spec2def.c:24
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int gbMSComp
Definition: spec2def.c:64
unsigned int uFlags
Definition: spec2def.c:29
int gbImportLib
Definition: spec2def.c:65
void OutputLine_def_MS(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:608
#define DbgPrint(...)
Definition: spec2def.c:76

Referenced by main().

◆ OutputLine_def_GCC()

void OutputLine_def_GCC ( FILE fileDest,
EXPORT pexp 
)

Definition at line 659 of file spec2def.c.

660 {
661  int bTracing = 0;
662  /* Print the function name, with decoration for export libs */
663  PrintName(fileDest, pexp, &pexp->strName, gbImportLib);
664  DbgPrint("Generating def line for '%.*s'\n", pexp->strName.len, pexp->strName.buf);
665 
666  /* Check if this is a forwarded export */
667  if (pexp->strTarget.buf)
668  {
669  int fIsExternal = !!ScanToken(pexp->strTarget.buf, '.');
670  DbgPrint("Got redirect '%.*s'\n", pexp->strTarget.len, pexp->strTarget.buf);
671 
672  /* print the target name, don't decorate if it is external */
673  fprintf(fileDest, "=");
674  PrintName(fileDest, pexp, &pexp->strTarget, !fIsExternal);
675  }
676  else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
677  (pexp->strName.buf[0] == '?'))
678  {
679  /* C++ stubs are forwarded to C stubs */
680  fprintf(fileDest, "=stub_function%d", pexp->nNumber);
681  }
682  else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) &&
683  (pexp->nCallingConvention == CC_STDCALL) &&
684  (pexp->strName.buf[0] != '?'))
685  {
686  /* Redirect it to the relay-tracing trampoline */
687  char buf[256];
688  STRING strTarget;
689  fprintf(fileDest, "=");
690  sprintf(buf, "$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
691  strTarget.buf = buf;
692  strTarget.len = pexp->strName.len + 12;
693  PrintName(fileDest, pexp, &strTarget, 1);
694  bTracing = 1;
695  }
696 
697  /* Special handling for stdcall and fastcall */
698  if ((giArch == ARCH_X86) &&
699  ((pexp->nCallingConvention == CC_STDCALL) ||
700  (pexp->nCallingConvention == CC_FASTCALL)))
701  {
702  /* Is this the import lib? */
703  if (gbImportLib)
704  {
705  /* Is the name in the spec file decorated? */
706  const char* pcDeco = ScanToken(pexp->strName.buf, '@');
707  if (pcDeco &&
708  (pexp->strName.len > 1) &&
709  (pcDeco < pexp->strName.buf + pexp->strName.len))
710  {
711  /* Write the name including the leading @ */
712  fprintf(fileDest, "==%.*s", pexp->strName.len, pexp->strName.buf);
713  }
714  }
715  else if ((!pexp->strTarget.buf) && !(bTracing))
716  {
717  /* Write a forwarder to the actual decorated symbol */
718  fprintf(fileDest, "=");
719  PrintName(fileDest, pexp, &pexp->strName, 1);
720  }
721  }
722 }
void PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
Definition: spec2def.c:528
STRING strName
Definition: spec2def.c:22
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define sprintf(buf, format,...)
Definition: sprintf.c:55
int nCallingConvention
Definition: spec2def.c:24
const char * ScanToken(const char *token, char chr)
Definition: spec2def.c:167
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int nNumber
Definition: spec2def.c:30
std::wstring STRING
Definition: fontsub.cpp:33
int giArch
Definition: spec2def.c:68
unsigned int uFlags
Definition: spec2def.c:29
int gbImportLib
Definition: spec2def.c:65
STRING strTarget
Definition: spec2def.c:23
int gbTracing
Definition: spec2def.c:67
#define DbgPrint(...)
Definition: spec2def.c:76

Referenced by OutputLine_def().

◆ OutputLine_def_MS()

void OutputLine_def_MS ( FILE fileDest,
EXPORT pexp 
)

Definition at line 608 of file spec2def.c.

609 {
610  PrintName(fileDest, pexp, &pexp->strName, 0);
611 
612  if (gbImportLib)
613  {
614  /* Redirect to a stub function, to get the right decoration in the lib */
615  fprintf(fileDest, "=_stub_");
616  PrintName(fileDest, pexp, &pexp->strName, 0);
617  }
618  else if (pexp->strTarget.buf)
619  {
620  if (pexp->strName.buf[0] == '?')
621  {
622  //fprintf(stderr, "warning: ignoring C++ redirection %.*s -> %.*s\n",
623  // pexp->strName.len, pexp->strName.buf, pexp->strTarget.len, pexp->strTarget.buf);
624  }
625  else
626  {
627  fprintf(fileDest, "=");
628 
629  /* If the original name was decorated, use decoration in the forwarder as well */
630  if ((giArch == ARCH_X86) && ScanToken(pexp->strName.buf, '@') &&
631  !ScanToken(pexp->strTarget.buf, '@') &&
632  ((pexp->nCallingConvention == CC_STDCALL) ||
633  (pexp->nCallingConvention == CC_FASTCALL)) )
634  {
635  PrintName(fileDest, pexp, &pexp->strTarget, 1);
636  }
637  else
638  {
639  /* Write the undecorated redirection name */
640  fprintf(fileDest, "%.*s", pexp->strTarget.len, pexp->strTarget.buf);
641  }
642  }
643  }
644  else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
645  (pexp->strName.buf[0] == '?'))
646  {
647  /* C++ stubs are forwarded to C stubs */
648  fprintf(fileDest, "=stub_function%d", pexp->nNumber);
649  }
650  else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CC_STDCALL) &&
651  (pexp->strName.buf[0] != '?'))
652  {
653  /* Redirect it to the relay-tracing trampoline */
654  fprintf(fileDest, "=$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
655  }
656 }
void PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
Definition: spec2def.c:528
STRING strName
Definition: spec2def.c:22
int nCallingConvention
Definition: spec2def.c:24
const char * ScanToken(const char *token, char chr)
Definition: spec2def.c:167
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int nNumber
Definition: spec2def.c:30
int giArch
Definition: spec2def.c:68
unsigned int uFlags
Definition: spec2def.c:29
int gbImportLib
Definition: spec2def.c:65
STRING strTarget
Definition: spec2def.c:23
int gbTracing
Definition: spec2def.c:67

Referenced by OutputLine_def().

◆ OutputLine_stub()

int OutputLine_stub ( FILE file,
EXPORT pexp 
)

Definition at line 234 of file spec2def.c.

235 {
236  int i;
237  int bRelay = 0;
238  int bInPrototype = 0;
239 
240  if (pexp->nCallingConvention != CC_STUB &&
241  (pexp->uFlags & FL_STUB) == 0)
242  {
243  /* Only relay trace stdcall C functions */
244  if (!gbTracing || (pexp->nCallingConvention != CC_STDCALL)
245  || (pexp->uFlags & FL_NORELAY)
246  || (pexp->strName.buf[0] == '?'))
247  {
248  return 0;
249  }
250  bRelay = 1;
251  }
252 
253  /* Declare the "real" function */
254  if (bRelay)
255  {
256  fprintf(file, "extern ");
257  bInPrototype = 1;
258  }
259 
260  do
261  {
262  if (pexp->uFlags & FL_REGISTER)
263  {
264  /* FIXME: Not sure this is right */
265  fprintf(file, "void ");
266  }
267  else if (pexp->uFlags & FL_RET64)
268  {
269  fprintf(file, "__int64 ");
270  }
271  else
272  {
273  fprintf(file, "int ");
274  }
275 
276  if ((giArch == ARCH_X86) &&
278  {
279  fprintf(file, "__stdcall ");
280  }
281 
282  /* Check for C++ */
283  if (pexp->strName.buf[0] == '?')
284  {
285  fprintf(file, "stub_function%d(", pexp->nNumber);
286  }
287  else
288  {
289  if (!bRelay || bInPrototype)
290  fprintf(file, "%.*s(", pexp->strName.len, pexp->strName.buf);
291  else
292  fprintf(file, "$relaytrace$%.*s(", pexp->strName.len, pexp->strName.buf);
293  }
294 
295  for (i = 0; i < pexp->nArgCount; i++)
296  {
297  if (i != 0) fprintf(file, ", ");
298  switch (pexp->anArgs[i])
299  {
300  case ARG_LONG: fprintf(file, "long"); break;
301  case ARG_PTR: fprintf(file, "void*"); break;
302  case ARG_STR: fprintf(file, "char*"); break;
303  case ARG_WSTR: fprintf(file, "wchar_t*"); break;
304  case ARG_DBL: fprintf(file, "double"); break;
305  case ARG_INT64 : fprintf(file, "__int64"); break;
306  /* __int128 is not supported on x86, and int128 in spec files most often represents a GUID */
307  case ARG_INT128 : fprintf(file, "GUID"); break;
308  case ARG_FLOAT: fprintf(file, "float"); break;
309  }
310  fprintf(file, " a%d", i);
311  }
312 
313  if (bInPrototype)
314  {
315  fprintf(file, ");\n\n");
316  }
317  } while (bInPrototype--);
318 
319  if (!bRelay)
320  {
321  fprintf(file, ")\n{\n\tDbgPrint(\"WARNING: calling stub %.*s(",
322  pexp->strName.len, pexp->strName.buf);
323  }
324  else
325  {
326  fprintf(file, ")\n{\n");
327  if (pexp->uFlags & FL_REGISTER)
328  {
329  /* No return value */
330  }
331  else if (pexp->uFlags & FL_RET64)
332  {
333  fprintf(file, "\t__int64 retval;\n");
334  }
335  else
336  {
337  fprintf(file, "\tint retval;\n");
338  }
339  fprintf(file, "\tif (TRACE_ON(relay))\n\t\tDPRINTF(\"%s: %.*s(",
340  pszDllName, pexp->strName.len, pexp->strName.buf);
341  }
342 
343  for (i = 0; i < pexp->nArgCount; i++)
344  {
345  if (i != 0) fprintf(file, ",");
346  switch (pexp->anArgs[i])
347  {
348  case ARG_LONG: fprintf(file, "0x%%lx"); break;
349  case ARG_PTR: fprintf(file, "0x%%p"); break;
350  case ARG_STR: fprintf(file, "'%%s'"); break;
351  case ARG_WSTR: fprintf(file, "'%%ws'"); break;
352  case ARG_DBL: fprintf(file, "%%f"); break;
353  case ARG_INT64: fprintf(file, "%%\"PRIx64\""); break;
354  case ARG_INT128: fprintf(file, "'%%s'"); break;
355  case ARG_FLOAT: fprintf(file, "%%f"); break;
356  }
357  }
358  fprintf(file, ")\\n\"");
359 
360  for (i = 0; i < pexp->nArgCount; i++)
361  {
362  fprintf(file, ", ");
363  switch (pexp->anArgs[i])
364  {
365  case ARG_LONG: fprintf(file, "(long)a%d", i); break;
366  case ARG_PTR: fprintf(file, "(void*)a%d", i); break;
367  case ARG_STR: fprintf(file, "(char*)a%d", i); break;
368  case ARG_WSTR: fprintf(file, "(wchar_t*)a%d", i); break;
369  case ARG_DBL: fprintf(file, "(double)a%d", i); break;
370  case ARG_INT64: fprintf(file, "(__int64)a%d", i); break;
371  case ARG_INT128: fprintf(file, "wine_dbgstr_guid(&a%d)", i); break;
372  case ARG_FLOAT: fprintf(file, "(float)a%d", i); break;
373  }
374  }
375  fprintf(file, ");\n");
376 
377  if (pexp->nCallingConvention == CC_STUB)
378  {
379  fprintf(file, "\t__wine_spec_unimplemented_stub(\"%s\", __FUNCTION__);\n", pszDllName);
380  }
381  else if (bRelay)
382  {
383  if (pexp->uFlags & FL_REGISTER)
384  {
385  fprintf(file,"\t");
386  }
387  else
388  {
389  fprintf(file, "\tretval = ");
390  }
391  fprintf(file, "%.*s(", pexp->strName.len, pexp->strName.buf);
392 
393  for (i = 0; i < pexp->nArgCount; i++)
394  {
395  if (i != 0) fprintf(file, ", ");
396  fprintf(file, "a%d", i);
397  }
398  fprintf(file, ");\n");
399  }
400 
401  if (!bRelay)
402  fprintf(file, "\treturn 0;\n}\n\n");
403  else if ((pexp->uFlags & FL_REGISTER) == 0)
404  {
405  if (pexp->uFlags & FL_RET64)
406  {
407  fprintf(file, "\tif (TRACE_ON(relay))\n\t\tDPRINTF(\"%s: %.*s: retval = %%\"PRIx64\"\\n\", retval);\n",
408  pszDllName, pexp->strName.len, pexp->strName.buf);
409  }
410  else
411  {
412  fprintf(file, "\tif (TRACE_ON(relay))\n\t\tDPRINTF(\"%s: %.*s: retval = 0x%%lx\\n\", retval);\n",
413  pszDllName, pexp->strName.len, pexp->strName.buf);
414  }
415  fprintf(file, "\treturn retval;\n}\n\n");
416  }
417 
418  return 1;
419 }
STRING strName
Definition: spec2def.c:22
int nArgCount
Definition: spec2def.c:27
int nCallingConvention
Definition: spec2def.c:24
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:30
int giArch
Definition: spec2def.c:68
unsigned int uFlags
Definition: spec2def.c:29
char * pszDllName
Definition: spec2def.c:72
int gbTracing
Definition: spec2def.c:67
int anArgs[30]
Definition: spec2def.c:28
Definition: fci.c:126

Referenced by main().

◆ ParseFile()

EXPORT* ParseFile ( char pcStart,
FILE fileDest,
unsigned cExports 
)

Definition at line 829 of file spec2def.c.

830 {
831  EXPORT *pexports;
832  const char *pc, *pcLine;
833  int cLines, nLine;
834  EXPORT exp;
835  int included;
836  unsigned int i;
837 
838  *cExports = 0;
839 
840  //fprintf(stderr, "info: line %d, pcStart:'%.30s'\n", nLine, pcStart);
841 
842  /* Count the lines */
843  for (cLines = 1, pcLine = pcStart; *pcLine; pcLine = NextLine(pcLine), cLines++)
844  {
845  /* Nothing */
846  }
847 
848  /* Allocate an array of EXPORT structures */
849  pexports = malloc(cLines * sizeof(EXPORT));
850  if (pexports == NULL)
851  {
852  fprintf(stderr, "ERROR: %s: failed to allocate EXPORT array of %u elements\n", pszSourceFileName, cLines);
853  return NULL;
854  }
855 
856  /* Loop all lines */
857  nLine = 1;
858  exp.nNumber = 0;
859  for (pcLine = pcStart; *pcLine; pcLine = NextLine(pcLine), nLine++)
860  {
861  pc = pcLine;
862 
863  exp.strName.buf = NULL;
864  exp.strName.len = 0;
865  exp.strTarget.buf = NULL;
866  exp.strTarget.len = 0;
867  exp.nArgCount = 0;
868  exp.uFlags = 0;
869  exp.nNumber++;
870  exp.nStartVersion = 0;
871  exp.nEndVersion = 0xFFFFFFFF;
872  exp.bVersionIncluded = 1;
873 
874  /* Skip white spaces */
875  while (*pc == ' ' || *pc == '\t') pc++;
876 
877  /* Check for line break or comment */
878  if ((*pc == '\r') || (*pc == '\n') ||
879  (*pc == ';') || (*pc == '#'))
880  {
881  continue;
882  }
883 
884  /* On EOF we are done */
885  if (*pc == 0)
886  {
887  return pexports;
888  }
889 
890  /* Now we should get either an ordinal or @ */
891  if (*pc == '@')
892  {
893  exp.nOrdinal = -1;
894  }
895  else if ((*pc >= '0') && (*pc <= '9'))
896  {
897  char* end;
898  long int number = strtol(pc, &end, 10);
899  if ((*end != ' ') && (*end != '\t'))
900  {
901  Fatal(pszSourceFileName, nLine, pcLine, end, 0, "Unexpected character(s) after ordinal");
902  }
903 
904  if ((number < 0) || (number > 0xFFFE))
905  {
906  Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Invalid value for ordinal");
907  }
908 
909  exp.nOrdinal = number;
910 
911  /* The import lib should contain the ordinal only if -ordinal was specified */
912  if (!gbImportLib)
913  exp.uFlags |= FL_ORDINAL;
914  }
915  else
916  {
917  Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Expected '@' or ordinal");
918  }
919 
920  /* Go to next token (type) */
921  if (!(pc = NextToken(pc)))
922  {
923  Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
924  }
925 
926  //fprintf(stderr, "info: Token:'%.*s'\n", TokenLength(pc), pc);
927 
928  /* Now we should get the type */
929  if (CompareToken(pc, "stdcall"))
930  {
931  exp.nCallingConvention = CC_STDCALL;
932  }
933  else if (CompareToken(pc, "cdecl") ||
934  CompareToken(pc, "varargs"))
935  {
936  exp.nCallingConvention = CC_CDECL;
937  }
938  else if (CompareToken(pc, "fastcall"))
939  {
940  exp.nCallingConvention = CC_FASTCALL;
941  }
942  else if (CompareToken(pc, "thiscall"))
943  {
944  exp.nCallingConvention = CC_THISCALL;
945  }
946  else if (CompareToken(pc, "extern"))
947  {
948  exp.nCallingConvention = CC_EXTERN;
949  }
950  else if (CompareToken(pc, "stub"))
951  {
952  exp.nCallingConvention = CC_STUB;
953  }
954  else
955  {
956  Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Invalid calling convention");
957  }
958 
959  /* Go to next token (options or name) */
960  if (!(pc = NextToken(pc)))
961  {
962  Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
963  }
964 
965  /* Handle options */
966  included = 1;
967  while (*pc == '-')
968  {
969  if (CompareToken(pc, "-arch="))
970  {
971  /* Default to not included */
972  included = 0;
973  pc += 5;
974 
975  /* Look if we are included */
976  do
977  {
978  pc++;
979  if (CompareToken(pc, pszArchString) ||
981  {
982  included = 1;
983  }
984 
985  /* Skip to next arch or end */
986  while (*pc > ',') pc++;
987  } while (*pc == ',');
988  }
989  else if (CompareToken(pc, "-i386"))
990  {
991  if (giArch != ARCH_X86) included = 0;
992  }
993  else if (CompareToken(pc, "-version="))
994  {
995  const char *pcVersionStart = pc + 9;
996 
997  /* Default to not included */
998  exp.bVersionIncluded = 0;
999  pc += 8;
1000 
1001  /* Look if we are included */
1002  do
1003  {
1004  unsigned version, endversion;
1005 
1006  /* Optionally skip leading '0x' */
1007  pc++;
1008  if ((pc[0] == '0') && (pc[1] == 'x')) pc += 2;
1009 
1010  /* Now get the version number */
1011  endversion = version = strtoul(pc, (char**)&pc, 16);
1012 
1013  /* Check if it's a range */
1014  if (pc[0] == '+')
1015  {
1016  endversion = 0xFFF;
1017  pc++;
1018  }
1019  else if (pc[0] == '-')
1020  {
1021  /* Optionally skip leading '0x' */
1022  pc++;
1023  if ((pc[0] == '0') && (pc[1] == 'x')) pc += 2;
1024  endversion = strtoul(pc, (char**)&pc, 16);
1025  }
1026 
1027  /* Check for degenerate range */
1028  if (version > endversion)
1029  {
1031  nLine,
1032  pcLine,
1033  pcVersionStart,
1034  pc - pcVersionStart,
1035  "Invalid version range");
1036  }
1037 
1038  exp.nStartVersion = version;
1039  exp.nEndVersion = endversion;
1040 
1041  /* Now compare the range with our version */
1042  if ((guOsVersion >= version) &&
1043  (guOsVersion <= endversion))
1044  {
1045  exp.bVersionIncluded = 1;
1046  }
1047 
1048  /* Skip to next arch or end */
1049  while (*pc > ',') pc++;
1050 
1051  } while (*pc == ',');
1052  }
1053  else if (CompareToken(pc, "-private"))
1054  {
1055  exp.uFlags |= FL_PRIVATE;
1056  }
1057  else if (CompareToken(pc, "-noname"))
1058  {
1059  exp.uFlags |= FL_ORDINAL | FL_NONAME;
1060  }
1061  else if (CompareToken(pc, "-ordinal"))
1062  {
1063  exp.uFlags |= FL_ORDINAL;
1064  /* GCC doesn't automatically import by ordinal if an ordinal
1065  * is found in the def file. Force it. */
1066  if (gbImportLib && !gbMSComp)
1067  exp.uFlags |= FL_NONAME;
1068  }
1069  else if (CompareToken(pc, "-stub"))
1070  {
1071  exp.uFlags |= FL_STUB;
1072  }
1073  else if (CompareToken(pc, "-norelay"))
1074  {
1075  exp.uFlags |= FL_NORELAY;
1076  }
1077  else if (CompareToken(pc, "-ret64"))
1078  {
1079  exp.uFlags |= FL_RET64;
1080  }
1081  else if (CompareToken(pc, "-register"))
1082  {
1083  exp.uFlags |= FL_REGISTER;
1084  }
1085  else
1086  {
1087  fprintf(stdout,
1088  "INFO: %s line %d: Ignored option: '%.*s'\n",
1090  nLine,
1091  TokenLength(pc),
1092  pc);
1093  }
1094 
1095  /* Go to next token */
1096  pc = NextToken(pc);
1097  }
1098 
1099  //fprintf(stderr, "info: Name:'%.10s'\n", pc);
1100 
1101  /* If arch didn't match ours, skip this entry */
1102  if (!included) continue;
1103 
1104  /* Get name */
1105  exp.strName.buf = pc;
1106  exp.strName.len = TokenLength(pc);
1107  //DbgPrint("Got name: '%.*s'\n", exp.strName.len, exp.strName.buf);
1108 
1109  /* Check for autoname */
1110  if ((exp.strName.len == 1) && (exp.strName.buf[0] == '@'))
1111  {
1112  exp.uFlags |= FL_ORDINAL | FL_NONAME;
1113  }
1114 
1115  /* Handle parameters */
1116  exp.nStackBytes = 0;
1117  if (exp.nCallingConvention != CC_EXTERN &&
1118  exp.nCallingConvention != CC_STUB)
1119  {
1120  /* Go to next token */
1121  if (!(pc = NextToken(pc)))
1122  {
1123  Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
1124  }
1125 
1126  /* Verify syntax */
1127  if (*pc++ != '(')
1128  {
1129  Fatal(pszSourceFileName, nLine, pcLine, pc - 1, 0, "Expected '('");
1130  }
1131 
1132  /* Skip whitespaces */
1133  while (*pc == ' ' || *pc == '\t') pc++;
1134 
1135  exp.nStackBytes = 0;
1136  while (*pc >= '0')
1137  {
1138  if (CompareToken(pc, "long"))
1139  {
1140  exp.nStackBytes += 4;
1141  exp.anArgs[exp.nArgCount] = ARG_LONG;
1142  }
1143  else if (CompareToken(pc, "double"))
1144  {
1145  exp.nStackBytes += 8;
1146  exp.anArgs[exp.nArgCount] = ARG_DBL;
1147  }
1148  else if (CompareToken(pc, "ptr"))
1149  {
1150  exp.nStackBytes += 4; // sizeof(void*) on x86
1151  exp.anArgs[exp.nArgCount] = ARG_PTR;
1152  }
1153  else if (CompareToken(pc, "str"))
1154  {
1155  exp.nStackBytes += 4; // sizeof(void*) on x86
1156  exp.anArgs[exp.nArgCount] = ARG_STR;
1157  }
1158  else if (CompareToken(pc, "wstr"))
1159  {
1160  exp.nStackBytes += 4; // sizeof(void*) on x86
1161  exp.anArgs[exp.nArgCount] = ARG_WSTR;
1162  }
1163  else if (CompareToken(pc, "int64"))
1164  {
1165  exp.nStackBytes += 8;
1166  exp.anArgs[exp.nArgCount] = ARG_INT64;
1167  }
1168  else if (CompareToken(pc, "int128"))
1169  {
1170  exp.nStackBytes += 16;
1171  exp.anArgs[exp.nArgCount] = ARG_INT128;
1172  }
1173  else if (CompareToken(pc, "float"))
1174  {
1175  exp.nStackBytes += 4;
1176  exp.anArgs[exp.nArgCount] = ARG_FLOAT;
1177  }
1178  else
1179  {
1180  Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Unrecognized type");
1181  }
1182 
1183  exp.nArgCount++;
1184 
1185  /* Go to next parameter */
1186  if (!(pc = NextToken(pc)))
1187  {
1188  Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Unexpected end of line");
1189  }
1190  }
1191 
1192  /* Check syntax */
1193  if (*pc++ != ')')
1194  {
1195  Fatal(pszSourceFileName, nLine, pcLine, pc - 1, 0, "Expected ')'");
1196  }
1197  }
1198 
1199  /* Handle special stub cases */
1200  if (exp.nCallingConvention == CC_STUB)
1201  {
1202  /* Check for c++ mangled name */
1203  if (pc[0] == '?')
1204  {
1205  //printf("Found c++ mangled name...\n");
1206  //
1207  }
1208  else
1209  {
1210  /* Check for stdcall name */
1211  const char *p = ScanToken(pc, '@');
1212  if (p && (p - pc < exp.strName.len))
1213  {
1214  int i;
1215 
1216  /* Truncate the name to before the @ */
1217  exp.strName.len = (int)(p - pc);
1218  if (exp.strName.len < 1)
1219  {
1220  Fatal(pszSourceFileName, nLine, pcLine, p, 1, "Unexpected @");
1221  }
1222  exp.nStackBytes = atoi(p + 1);
1223  exp.nArgCount = exp.nStackBytes / 4;
1224  exp.nCallingConvention = CC_STDCALL;
1225  exp.uFlags |= FL_STUB;
1226  for (i = 0; i < exp.nArgCount; i++)
1227  exp.anArgs[i] = ARG_LONG;
1228  }
1229  }
1230  }
1231 
1232  /* Get optional redirection */
1233  pc = NextToken(pc);
1234  if (pc)
1235  {
1236  exp.strTarget.buf = pc;
1237  exp.strTarget.len = TokenLength(pc);
1238 
1239  /* Check syntax (end of line) */
1240  if (NextToken(pc))
1241  {
1242  Fatal(pszSourceFileName, nLine, pcLine, NextToken(pc), 0, "Excess token(s) at end of definition");
1243  }
1244 
1245  /* Don't relay-trace forwarded functions */
1246  exp.uFlags |= FL_NORELAY;
1247  }
1248  else
1249  {
1250  exp.strTarget.buf = NULL;
1251  exp.strTarget.len = 0;
1252  }
1253 
1254  /* Check for no-name without ordinal */
1255  if ((exp.uFlags & FL_ORDINAL) && (exp.nOrdinal == -1))
1256  {
1257  Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Ordinal export without ordinal");
1258  }
1259 
1260  /*
1261  * Check for special handling of OLE exports, only when MSVC
1262  * is not used, since otherwise this is handled by MS LINK.EXE.
1263  */
1264  if (!gbMSComp)
1265  {
1266  /* Check whether the current export is not PRIVATE, or has an ordinal */
1267  int bIsNotPrivate = (!gbNotPrivateNoWarn && /*gbImportLib &&*/ !(exp.uFlags & FL_PRIVATE));
1268  int bHasOrdinal = (exp.uFlags & FL_ORDINAL);
1269 
1270  /* Check whether the current export is an OLE export, in case any of these tests pass */
1271  if (bIsNotPrivate || bHasOrdinal)
1272  {
1273  for (i = 0; i < ARRAYSIZE(astrOlePrivateExports); ++i)
1274  {
1275  if (strlen(astrOlePrivateExports[i]) == exp.strName.len &&
1276  strncmp(exp.strName.buf, astrOlePrivateExports[i], exp.strName.len) == 0)
1277  {
1278  /* The current export is an OLE export: display the corresponding warning */
1279  if (bIsNotPrivate)
1280  {
1281  fprintf(stderr, "WARNING: %s line %d: Exported symbol '%.*s' should be PRIVATE\n",
1282  pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
1283  }
1284  if (bHasOrdinal)
1285  {
1286  fprintf(stderr, "WARNING: %s line %d: exported symbol '%.*s' should not be assigned an ordinal\n",
1287  pszSourceFileName, nLine, exp.strName.len, exp.strName.buf);
1288  }
1289  break;
1290  }
1291  }
1292  }
1293  }
1294 
1295  pexports[*cExports] = exp;
1296  (*cExports)++;
1297  gbDebug = 0;
1298  }
1299 
1300  return pexports;
1301 }
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:66
const char * NextLine(const char *pc)
Definition: spec2def.c:178
const char * NextToken(const char *pc)
Definition: spec2def.c:200
int gbDebug
Definition: spec2def.c:74
GLuint GLuint end
Definition: gl.h:1545
FILE * stdout
#define ARRAYSIZE(a)
Definition: spec2def.c:12
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:153
void Fatal(const char *filename, unsigned nLine, const char *pcLine, const char *pc, size_t errorlen, const char *format,...)
Definition: spec2def.c:812
const char * ScanToken(const char *token, char chr)
Definition: spec2def.c:167
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
static size_t double number
Definition: printf.c:69
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:66
static const char * astrOlePrivateExports[]
Definition: spec2def.c:125
int gbMSComp
Definition: spec2def.c:64
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
int giArch
Definition: spec2def.c:68
char * pszSourceFileName
Definition: spec2def.c:71
int gbImportLib
Definition: spec2def.c:65
int TokenLength(const char *pc)
Definition: spec2def.c:190
DWORD exp
Definition: msg.c:16038
char * pszArchString2
Definition: spec2def.c:70
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
FILE * stderr
#define malloc
Definition: debug_ros.c:4
GLfloat GLfloat p
Definition: glext.h:8902
unsigned guOsVersion
Definition: spec2def.c:75
char * pszArchString
Definition: spec2def.c:69
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 528 of file spec2def.c.

529 {
530  const char *pcName = pstr->buf;
531  int nNameLength = pstr->len;
532  const char* pcDot, *pcAt;
533  char namebuffer[19];
534 
535  if ((nNameLength == 1) && (pcName[0] == '@'))
536  {
537  sprintf(namebuffer, "ordinal%d", pexp->nOrdinal);
538  pcName = namebuffer;
539  nNameLength = strlen(namebuffer);
540  }
541 
542  /* Check for non-x86 first */
543  if (giArch != ARCH_X86)
544  {
545  /* Does the string already have stdcall decoration? */
546  pcAt = ScanToken(pcName, '@');
547  if (pcAt && (pcAt < (pcName + nNameLength)) && (pcName[0] == '_'))
548  {
549  /* Skip leading underscore and remove trailing decoration */
550  pcName++;
551  nNameLength = (int)(pcAt - pcName);
552  }
553 
554  /* Print the undecorated function name */
555  fprintf(fileDest, "%.*s", nNameLength, pcName);
556  }
557  else if (fDeco &&
558  ((pexp->nCallingConvention == CC_STDCALL) ||
559  (pexp->nCallingConvention == CC_FASTCALL)))
560  {
561  /* Scan for a dll forwarding dot */
562  pcDot = ScanToken(pcName, '.');
563  if (pcDot)
564  {
565  /* First print the dll name, followed by a dot */
566  nNameLength = (int)(pcDot - pcName);
567  fprintf(fileDest, "%.*s.", nNameLength, pcName);
568 
569  /* Now the actual function name */
570  pcName = pcDot + 1;
571  nNameLength = pexp->strTarget.len - nNameLength - 1;
572  }
573 
574  /* Does the string already have decoration? */
575  pcAt = ScanToken(pcName, '@');
576  if (pcAt && (pcAt < (pcName + nNameLength)))
577  {
578  /* On GCC, we need to remove the leading stdcall underscore */
579  if (!gbMSComp && (pexp->nCallingConvention == CC_STDCALL))
580  {
581  pcName++;
582  nNameLength--;
583  }
584 
585  /* Print the already decorated function name */
586  fprintf(fileDest, "%.*s", nNameLength, pcName);
587  }
588  else
589  {
590  /* Print the prefix, but skip it for (GCC && stdcall) */
591  if (gbMSComp || (pexp->nCallingConvention != CC_STDCALL))
592  {
593  fprintf(fileDest, "%c", pexp->nCallingConvention == CC_FASTCALL ? '@' : '_');
594  }
595 
596  /* Print the name with trailing decoration */
597  fprintf(fileDest, "%.*s@%d", nNameLength, pcName, pexp->nStackBytes);
598  }
599  }
600  else
601  {
602  /* Print the undecorated function name */
603  fprintf(fileDest, "%.*s", nNameLength, pcName);
604  }
605 }
int nOrdinal
Definition: spec2def.c:25
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define sprintf(buf, format,...)
Definition: sprintf.c:55
int nCallingConvention
Definition: spec2def.c:24
const char * ScanToken(const char *token, char chr)
Definition: spec2def.c:167
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int len
Definition: spec2def.c:17
int gbMSComp
Definition: spec2def.c:64
int giArch
Definition: spec2def.c:68
const char * buf
Definition: spec2def.c:16
int nStackBytes
Definition: spec2def.c:26
STRING strTarget
Definition: spec2def.c:23
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 167 of file spec2def.c.

168 {
169  while (!IsSeparator(*token))
170  {
171  if (*token == chr) return token;
172  token++;
173  }
174  return 0;
175 }
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:146
int chr(char *serport)
Definition: gdblib.c:152

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

◆ TokenLength()

int TokenLength ( const char pc)

Definition at line 190 of file spec2def.c.

191 {
192  int length = 0;
193 
194  while (!IsSeparator(*pc++)) length++;
195 
196  return length;
197 }
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static int IsSeparator(char chr)
Definition: spec2def.c:146

Referenced by Fatalv(), ParseFile(), and SmpParseToken().

◆ usage()

void usage ( void  )

Definition at line 1349 of file spec2def.c.

1350 {
1351  printf("syntax: spec2def [<options> ...] <spec file>\n"
1352  "Possible options:\n"
1353  " -h --help print this help screen\n"
1354  " -l=<file> generate an asm lib stub\n"
1355  " -d=<file> generate a def file\n"
1356  " -s=<file> generate a stub file\n"
1357  " --ms MSVC compatibility\n"
1358  " -n=<name> name of the dll\n"
1359  " --implib generate a def file for an import library\n"
1360  " --no-private-warnings suppress warnings about symbols that should be -private\n"
1361  " -a=<arch> set architecture to <arch> (i386, x86_64, arm)\n"
1362  " --with-tracing generate wine-like \"+relay\" trace trampolines (needs -s)\n");
1363 }
#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 111 of file spec2def.c.

◆ astrOlePrivateExports

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

Definition at line 125 of file spec2def.c.

Referenced by ParseFile().

◆ gbDebug

int gbDebug

Definition at line 74 of file spec2def.c.

Referenced by ParseFile().

◆ gbImportLib

int gbImportLib = 0

Definition at line 65 of file spec2def.c.

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

◆ gbMSComp

int gbMSComp = 0

Definition at line 64 of file spec2def.c.

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

◆ gbNotPrivateNoWarn

int gbNotPrivateNoWarn = 0

Definition at line 66 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ gbTracing

int gbTracing = 0

◆ giArch

◆ gpszUnderscore

char* gpszUnderscore = ""

Definition at line 73 of file spec2def.c.

Referenced by main(), and OutputLine_asmstub().

◆ guOsVersion

unsigned guOsVersion = 0x502

Definition at line 75 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszArchString

char* pszArchString = "i386"

Definition at line 69 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszArchString2

char* pszArchString2

Definition at line 70 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszDllName

char* pszDllName = NULL

Definition at line 72 of file spec2def.c.

Referenced by main(), and OutputLine_stub().

◆ pszSourceFileName

char* pszSourceFileName = NULL

Definition at line 71 of file spec2def.c.

Referenced by main(), and ParseFile().