ReactOS  0.4.15-dev-1150-g593bcce
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 1310 of file spec2def.c.

1311 {
1312  unsigned short i, j;
1313  char* used;
1314 
1315  /* Allocate a table to mark used ordinals */
1316  used = malloc(65536);
1317  if (used == NULL)
1318  {
1319  fprintf(stderr, "Failed to allocate memory for ordinal use table\n");
1320  return -1;
1321  }
1322  memset(used, 0, 65536);
1323 
1324  /* Pass 1: mark the ordinals that are already used */
1325  for (i = 0; i < cExports; i++)
1326  {
1327  if (pexports[i].uFlags & FL_ORDINAL)
1328  {
1329  if (used[pexports[i].nOrdinal] != 0)
1330  {
1331  fprintf(stderr, "Found duplicate ordinal: %u\n", pexports[i].nOrdinal);
1332  return -1;
1333  }
1334  used[pexports[i].nOrdinal] = 1;
1335  }
1336  }
1337 
1338  /* Pass 2: apply available ordinals */
1339  for (i = 0, j = 1; i < cExports; i++)
1340  {
1341  if ((pexports[i].uFlags & FL_ORDINAL) == 0 && pexports[i].bVersionIncluded)
1342  {
1343  while (used[j] != 0)
1344  j++;
1345 
1346  pexports[i].nOrdinal = j;
1347  used[j] = 1;
1348  }
1349  }
1350 
1351  free(used);
1352  return 0;
1353 }
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:2857
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 818 of file spec2def.c.

826 {
827  va_list argptr;
828 
829  va_start(argptr, format);
830  Fatalv(filename, nLine, pcLine, pc, errorlen, format, argptr);
831  va_end(argptr);
832 }
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:768
#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 768 of file spec2def.c.

776 {
777  unsigned i, errorpos, len;
778  const char* pcLineEnd;
779 
780  /* Get the length of the line */
781  pcLineEnd = strpbrk(pcLine, "\r\n");
782  len = (unsigned)(pcLineEnd - pcLine);
783 
784  if (pc == NULL)
785  {
786  pc = pcLine + len - 1;
787  errorlen = 1;
788  }
789 
790  errorpos = (unsigned)(pc - pcLine);
791 
792  /* Output the error message */
793  fprintf(stderr, "ERROR: (%s:%u:%u): ", filename, nLine, errorpos);
794  vfprintf(stderr, format, argptr);
795  fprintf(stderr, "\n");
796 
797  /* Output the line with the error */
798  fprintf(stderr, "> %.*s\n", len, pcLine);
799 
800  if (errorlen == 0)
801  {
802  errorlen = TokenLength(pc);
803  }
804 
805  for (i = 0; i < errorpos + 2; i++)
806  {
807  fprintf(stderr, " ");
808  }
809  for (i = 0; i < errorlen; i++)
810  {
811  fprintf(stderr, "~");
812  }
813  fprintf(stderr, "\n");
814  exit(-1);
815 }
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 1371 of file spec2def.c.

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

448 {
449  if (giArch == ARCH_ARM)
450  {
451  fprintf(fileDest,
452  "\tEXPORT |%s| [FUNC]\n|%s|\n",
453  pszSymbolName,
454  pszSymbolName);
455  }
456  else
457  {
458  fprintf(fileDest,
459  "PUBLIC %s\n%s: nop\n",
460  pszSymbolName,
461  pszSymbolName);
462  }
463 }
_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 428 of file spec2def.c.

429 {
430  fprintf(file, "; File generated automatically, do not edit! \n\n");
431 
432  if (giArch == ARCH_X86)
433  {
434  fprintf(file, ".586\n.model flat\n.code\n");
435  }
436  else if (giArch == ARCH_AMD64)
437  {
438  fprintf(file, ".code\n");
439  }
440  else if (giArch == ARCH_ARM)
441  {
442  fprintf(file, " AREA |.text|,ALIGN=2,CODE,READONLY\n\n");
443  }
444 }
_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 524 of file spec2def.c.

525 {
526  fprintf(file,
527  "; File generated automatically, do not edit!\n\n"
528  "NAME %s\n\n"
529  "EXPORTS\n",
530  libname);
531 }
_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  /* __int128 is not supported on x86, so use a custom type */
231  fprintf(file, "\n"
232  "typedef struct {\n"
233  " __int64 lower;\n"
234  " __int64 upper;\n"
235  "} MyInt128;\n");
236 
237  fprintf(file, "\n");
238 }
_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 466 of file spec2def.c.

467 {
468  char szNameBuffer[128];
469 
470  /* Handle autoname */
471  if (pexp->strName.len == 1 && pexp->strName.buf[0] == '@')
472  {
473  sprintf(szNameBuffer, "%s_stub_ordinal%d",
474  gpszUnderscore, pexp->nOrdinal);
475  }
476  else if (giArch != ARCH_X86)
477  {
478  /* Does the string already have stdcall decoration? */
479  const char *pcAt = ScanToken(pexp->strName.buf, '@');
480  if (pcAt && (pcAt < (pexp->strName.buf + pexp->strName.len)) &&
481  (pexp->strName.buf[0] == '_'))
482  {
483  /* Skip leading underscore and remove trailing decoration */
484  sprintf(szNameBuffer, "_stub_%.*s",
485  (int)(pcAt - pexp->strName.buf - 1),
486  pexp->strName.buf + 1);
487  }
488  else
489  {
490  sprintf(szNameBuffer, "_stub_%.*s",
491  pexp->strName.len, pexp->strName.buf);
492  }
493  }
494  else if (pexp->nCallingConvention == CC_STDCALL)
495  {
496  sprintf(szNameBuffer, "__stub_%.*s@%d",
497  pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
498  }
499  else if (pexp->nCallingConvention == CC_FASTCALL)
500  {
501  sprintf(szNameBuffer, "@_stub_%.*s@%d",
502  pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
503  }
504  else if ((pexp->nCallingConvention == CC_CDECL) ||
505  (pexp->nCallingConvention == CC_THISCALL) ||
506  (pexp->nCallingConvention == CC_EXTERN) ||
507  (pexp->nCallingConvention == CC_STUB))
508  {
509  sprintf(szNameBuffer, "__stub_%.*s",
510  pexp->strName.len, pexp->strName.buf);
511  }
512  else
513  {
514  fprintf(stderr, "Invalid calling convention");
515  return 0;
516  }
517 
518  Output_stublabel(fileDest, szNameBuffer);
519 
520  return 1;
521 }
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:447
int nStackBytes
Definition: spec2def.c:26
FILE * stderr

Referenced by main().

◆ OutputLine_def()

int OutputLine_def ( FILE fileDest,
EXPORT pexp 
)

Definition at line 731 of file spec2def.c.

732 {
733  DbgPrint("OutputLine_def: '%.*s'...\n", pexp->strName.len, pexp->strName.buf);
734  fprintf(fileDest, " ");
735 
736  if (gbMSComp)
737  OutputLine_def_MS(fileDest, pexp);
738  else
739  OutputLine_def_GCC(fileDest, pexp);
740 
741  /* On GCC builds we force ordinals */
742  if ((pexp->uFlags & FL_ORDINAL) || (!gbMSComp && !gbImportLib))
743  {
744  fprintf(fileDest, " @%d", pexp->nOrdinal);
745  }
746 
747  if (pexp->uFlags & FL_NONAME)
748  {
749  fprintf(fileDest, " NONAME");
750  }
751 
752  /* Either PRIVATE or DATA */
753  if (pexp->uFlags & FL_PRIVATE)
754  {
755  fprintf(fileDest, " PRIVATE");
756  }
757  else if (pexp->nCallingConvention == CC_EXTERN)
758  {
759  fprintf(fileDest, " DATA");
760  }
761 
762  fprintf(fileDest, "\n");
763 
764  return 1;
765 }
STRING strName
Definition: spec2def.c:22
int nOrdinal
Definition: spec2def.c:25
void OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:665
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:614
#define DbgPrint(...)
Definition: spec2def.c:76

Referenced by main().

◆ OutputLine_def_GCC()

void OutputLine_def_GCC ( FILE fileDest,
EXPORT pexp 
)

Definition at line 665 of file spec2def.c.

666 {
667  int bTracing = 0;
668  /* Print the function name, with decoration for export libs */
669  PrintName(fileDest, pexp, &pexp->strName, gbImportLib);
670  DbgPrint("Generating def line for '%.*s'\n", pexp->strName.len, pexp->strName.buf);
671 
672  /* Check if this is a forwarded export */
673  if (pexp->strTarget.buf)
674  {
675  int fIsExternal = !!ScanToken(pexp->strTarget.buf, '.');
676  DbgPrint("Got redirect '%.*s'\n", pexp->strTarget.len, pexp->strTarget.buf);
677 
678  /* print the target name, don't decorate if it is external */
679  fprintf(fileDest, "=");
680  PrintName(fileDest, pexp, &pexp->strTarget, !fIsExternal);
681  }
682  else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
683  (pexp->strName.buf[0] == '?'))
684  {
685  /* C++ stubs are forwarded to C stubs */
686  fprintf(fileDest, "=stub_function%d", pexp->nNumber);
687  }
688  else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) &&
689  (pexp->nCallingConvention == CC_STDCALL) &&
690  (pexp->strName.buf[0] != '?'))
691  {
692  /* Redirect it to the relay-tracing trampoline */
693  char buf[256];
694  STRING strTarget;
695  fprintf(fileDest, "=");
696  sprintf(buf, "$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
697  strTarget.buf = buf;
698  strTarget.len = pexp->strName.len + 12;
699  PrintName(fileDest, pexp, &strTarget, 1);
700  bTracing = 1;
701  }
702 
703  /* Special handling for stdcall and fastcall */
704  if ((giArch == ARCH_X86) &&
705  ((pexp->nCallingConvention == CC_STDCALL) ||
706  (pexp->nCallingConvention == CC_FASTCALL)))
707  {
708  /* Is this the import lib? */
709  if (gbImportLib)
710  {
711  /* Is the name in the spec file decorated? */
712  const char* pcDeco = ScanToken(pexp->strName.buf, '@');
713  if (pcDeco &&
714  (pexp->strName.len > 1) &&
715  (pcDeco < pexp->strName.buf + pexp->strName.len))
716  {
717  /* Write the name including the leading @ */
718  fprintf(fileDest, "==%.*s", pexp->strName.len, pexp->strName.buf);
719  }
720  }
721  else if ((!pexp->strTarget.buf) && !(bTracing))
722  {
723  /* Write a forwarder to the actual decorated symbol */
724  fprintf(fileDest, "=");
725  PrintName(fileDest, pexp, &pexp->strName, 1);
726  }
727  }
728 }
void PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
Definition: spec2def.c:534
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 614 of file spec2def.c.

615 {
616  PrintName(fileDest, pexp, &pexp->strName, 0);
617 
618  if (gbImportLib)
619  {
620  /* Redirect to a stub function, to get the right decoration in the lib */
621  fprintf(fileDest, "=_stub_");
622  PrintName(fileDest, pexp, &pexp->strName, 0);
623  }
624  else if (pexp->strTarget.buf)
625  {
626  if (pexp->strName.buf[0] == '?')
627  {
628  //fprintf(stderr, "warning: ignoring C++ redirection %.*s -> %.*s\n",
629  // pexp->strName.len, pexp->strName.buf, pexp->strTarget.len, pexp->strTarget.buf);
630  }
631  else
632  {
633  fprintf(fileDest, "=");
634 
635  /* If the original name was decorated, use decoration in the forwarder as well */
636  if ((giArch == ARCH_X86) && ScanToken(pexp->strName.buf, '@') &&
637  !ScanToken(pexp->strTarget.buf, '@') &&
638  ((pexp->nCallingConvention == CC_STDCALL) ||
639  (pexp->nCallingConvention == CC_FASTCALL)) )
640  {
641  PrintName(fileDest, pexp, &pexp->strTarget, 1);
642  }
643  else
644  {
645  /* Write the undecorated redirection name */
646  fprintf(fileDest, "%.*s", pexp->strTarget.len, pexp->strTarget.buf);
647  }
648  }
649  }
650  else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
651  (pexp->strName.buf[0] == '?'))
652  {
653  /* C++ stubs are forwarded to C stubs */
654  fprintf(fileDest, "=stub_function%d", pexp->nNumber);
655  }
656  else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CC_STDCALL) &&
657  (pexp->strName.buf[0] != '?'))
658  {
659  /* Redirect it to the relay-tracing trampoline */
660  fprintf(fileDest, "=$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
661  }
662 }
void PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
Definition: spec2def.c:534
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 241 of file spec2def.c.

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

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

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

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