ReactOS  0.4.15-dev-4916-gd519b11
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_ARM64, 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 77 of file spec2def.c.

Typedef Documentation

◆ PFNOUTLINE

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

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

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

◆ anonymous enum

anonymous enum
Enumerator
CC_STDCALL 
CC_CDECL 
CC_FASTCALL 
CC_THISCALL 
CC_EXTERN 
CC_STUB 

Definition at line 90 of file spec2def.c.

91 {
92  CC_STDCALL,
93  CC_CDECL,
96  CC_EXTERN,
97  CC_STUB,
98 };

◆ anonymous enum

anonymous enum
Enumerator
ARG_LONG 
ARG_PTR 
ARG_STR 
ARG_WSTR 
ARG_DBL 
ARG_INT64 
ARG_INT128 
ARG_FLOAT 

Definition at line 100 of file spec2def.c.

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

◆ _ARCH

Enumerator
ARCH_X86 
ARCH_AMD64 
ARCH_IA64 
ARCH_ARM 
ARCH_ARM64 
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_ARM64,
61  ARCH_PPC
62 };

Function Documentation

◆ ApplyOrdinals()

int ApplyOrdinals ( EXPORT pexports,
unsigned  cExports 
)

Definition at line 1352 of file spec2def.c.

1353 {
1354  unsigned short i, j;
1355  char* used;
1356 
1357  /* Allocate a table to mark used ordinals */
1358  used = malloc(65536);
1359  if (used == NULL)
1360  {
1361  fprintf(stderr, "Failed to allocate memory for ordinal use table\n");
1362  return -1;
1363  }
1364  memset(used, 0, 65536);
1365 
1366  /* Pass 1: mark the ordinals that are already used */
1367  for (i = 0; i < cExports; i++)
1368  {
1369  if (pexports[i].uFlags & FL_ORDINAL)
1370  {
1371  if (used[pexports[i].nOrdinal] != 0)
1372  {
1373  fprintf(stderr, "Found duplicate ordinal: %u\n", pexports[i].nOrdinal);
1374  return -1;
1375  }
1376  used[pexports[i].nOrdinal] = 1;
1377  }
1378  }
1379 
1380  /* Pass 2: apply available ordinals */
1381  for (i = 0, j = 1; i < cExports; i++)
1382  {
1383  if ((pexports[i].uFlags & FL_ORDINAL) == 0 && pexports[i].bVersionIncluded)
1384  {
1385  while (used[j] != 0)
1386  j++;
1387 
1388  pexports[i].nOrdinal = j;
1389  used[j] = 1;
1390  }
1391  }
1392 
1393  free(used);
1394  return 0;
1395 }
int nOrdinal
Definition: spec2def.c:25
#define free
Definition: debug_ros.c:5
UINT uFlags
Definition: api.c:59
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat 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
static int used
Definition: adh-main.c:39
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
#define NULL
Definition: types.h:112
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 154 of file spec2def.c.

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

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 851 of file spec2def.c.

859 {
860  va_list argptr;
861 
862  va_start(argptr, format);
863  Fatalv(filename, nLine, pcLine, pc, errorlen, format, argptr);
864  va_end(argptr);
865 }
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:801
#define va_end(ap)
Definition: acmsvcex.h:90
char * va_list
Definition: acmsvcex.h:78
va_start(ap, x)

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 801 of file spec2def.c.

809 {
810  unsigned i, errorpos, len;
811  const char* pcLineEnd;
812 
813  /* Get the length of the line */
814  pcLineEnd = strpbrk(pcLine, "\r\n");
815  len = (unsigned)(pcLineEnd - pcLine);
816 
817  if (pc == NULL)
818  {
819  pc = pcLine + len - 1;
820  errorlen = 1;
821  }
822 
823  errorpos = (unsigned)(pc - pcLine);
824 
825  /* Output the error message */
826  fprintf(stderr, "ERROR: (%s:%u:%u): ", filename, nLine, errorpos);
827  vfprintf(stderr, format, argptr);
828  fprintf(stderr, "\n");
829 
830  /* Output the line with the error */
831  fprintf(stderr, "> %.*s\n", len, pcLine);
832 
833  if (errorlen == 0)
834  {
835  errorlen = TokenLength(pc);
836  }
837 
838  for (i = 0; i < errorpos + 2; i++)
839  {
840  fprintf(stderr, " ");
841  }
842  for (i = 0; i < errorlen; i++)
843  {
844  fprintf(stderr, "~");
845  }
846  fprintf(stderr, "\n");
847  exit(-1);
848 }
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
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
GLenum GLsizei len
Definition: glext.h:6722
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 TokenLength(const char *pc)
Definition: spec2def.c:191
#define NULL
Definition: types.h:112
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 147 of file spec2def.c.

148 {
149  return ((chr <= ',' && chr != '$' && chr != '#') ||
150  (chr >= ':' && chr < '?') );
151 }

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 1413 of file spec2def.c.

1414 {
1415  size_t nFileSize;
1416  char *pszSource, *pszDefFileName = NULL, *pszStubFileName = NULL, *pszLibStubName = NULL;
1417  const char* pszVersionOption = "--version=0x";
1418  char achDllName[40];
1419  FILE *file;
1420  unsigned cExports = 0, i;
1421  EXPORT *pexports;
1422 
1423  if (argc < 2)
1424  {
1425  usage();
1426  return -1;
1427  }
1428 
1429  /* Read options */
1430  for (i = 1; i < (unsigned)argc && *argv[i] == '-'; i++)
1431  {
1432  if ((strcasecmp(argv[i], "--help") == 0) ||
1433  (strcasecmp(argv[i], "-h") == 0))
1434  {
1435  usage();
1436  return 0;
1437  }
1438  else if (argv[i][1] == 'd' && argv[i][2] == '=')
1439  {
1440  pszDefFileName = argv[i] + 3;
1441  }
1442  else if (argv[i][1] == 'l' && argv[i][2] == '=')
1443  {
1444  pszLibStubName = argv[i] + 3;
1445  }
1446  else if (argv[i][1] == 's' && argv[i][2] == '=')
1447  {
1448  pszStubFileName = argv[i] + 3;
1449  }
1450  else if (argv[i][1] == 'n' && argv[i][2] == '=')
1451  {
1452  pszDllName = argv[i] + 3;
1453  }
1454  else if (strncasecmp(argv[i], pszVersionOption, strlen(pszVersionOption)) == 0)
1455  {
1456  guOsVersion = strtoul(argv[i] + strlen(pszVersionOption), NULL, 16);
1457  }
1458  else if (strcasecmp(argv[i], "--implib") == 0)
1459  {
1460  gbImportLib = 1;
1461  }
1462  else if (strcasecmp(argv[i], "--ms") == 0)
1463  {
1464  gbMSComp = 1;
1465  }
1466  else if (strcasecmp(argv[i], "--no-private-warnings") == 0)
1467  {
1468  gbNotPrivateNoWarn = 1;
1469  }
1470  else if (strcasecmp(argv[i], "--with-tracing") == 0)
1471  {
1472  if (!pszStubFileName)
1473  {
1474  fprintf(stderr, "Error: cannot use --with-tracing without -s option.\n");
1475  return -1;
1476  }
1477  gbTracing = 1;
1478  }
1479  else if (argv[i][1] == 'a' && argv[i][2] == '=')
1480  {
1481  pszArchString = argv[i] + 3;
1482  }
1483  else
1484  {
1485  fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
1486  return -1;
1487  }
1488  }
1489 
1490  if (strcasecmp(pszArchString, "i386") == 0)
1491  {
1492  giArch = ARCH_X86;
1493  gpszUnderscore = "_";
1494  }
1495  else if (strcasecmp(pszArchString, "x86_64") == 0) giArch = ARCH_AMD64;
1496  else if (strcasecmp(pszArchString, "ia64") == 0) giArch = ARCH_IA64;
1497  else if (strcasecmp(pszArchString, "arm") == 0) giArch = ARCH_ARM;
1498  else if (strcasecmp(pszArchString, "arm64") == 0) giArch = ARCH_ARM64;
1499  else if (strcasecmp(pszArchString, "ppc") == 0) giArch = ARCH_PPC;
1500 
1501  if ((giArch == ARCH_AMD64) || (giArch == ARCH_IA64))
1502  {
1503  pszArchString2 = "win64";
1504  }
1505  else
1506  pszArchString2 = "win32";
1507 
1508  /* Set a default dll name */
1509  if (!pszDllName)
1510  {
1511  char *p1, *p2;
1512  size_t len;
1513 
1514  p1 = strrchr(argv[i], '\\');
1515  if (!p1) p1 = strrchr(argv[i], '/');
1516  p2 = p1 = p1 ? p1 + 1 : argv[i];
1517 
1518  /* walk up to '.' */
1519  while (*p2 != '.' && *p2 != 0) p2++;
1520  len = p2 - p1;
1521  if (len >= sizeof(achDllName) - 5)
1522  {
1523  fprintf(stderr, "name too long: %s\n", p1);
1524  return -2;
1525  }
1526 
1527  strncpy(achDllName, p1, len);
1528  strncpy(achDllName + len, ".dll", sizeof(achDllName) - len);
1529  pszDllName = achDllName;
1530  }
1531 
1532  /* Open input file */
1534  file = fopen(pszSourceFileName, "r");
1535  if (!file)
1536  {
1537  fprintf(stderr, "error: could not open file %s\n", pszSourceFileName);
1538  return -3;
1539  }
1540 
1541  /* Get file size */
1542  fseek(file, 0, SEEK_END);
1543  nFileSize = ftell(file);
1544  rewind(file);
1545 
1546  /* Allocate memory buffer */
1547  pszSource = malloc(nFileSize + 1);
1548  if (!pszSource)
1549  {
1550  fclose(file);
1551  return -4;
1552  }
1553 
1554  /* Load input file into memory */
1555  nFileSize = fread(pszSource, 1, nFileSize, file);
1556  fclose(file);
1557 
1558  /* Zero terminate the source */
1559  pszSource[nFileSize] = '\0';
1560 
1561  pexports = ParseFile(pszSource, file, &cExports);
1562  if (pexports == NULL)
1563  {
1564  fprintf(stderr, "error: could not parse file!\n");
1565  return -1;
1566  }
1567 
1568  if (!gbMSComp)
1569  {
1570  if (ApplyOrdinals(pexports, cExports) < 0)
1571  {
1572  fprintf(stderr, "error: could not apply ordinals!\n");
1573  return -1;
1574  }
1575  }
1576 
1577  if (pszDefFileName)
1578  {
1579  /* Open output file */
1580  file = fopen(pszDefFileName, "w");
1581  if (!file)
1582  {
1583  fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1584  return -5;
1585  }
1586 
1588 
1589  for (i = 0; i < cExports; i++)
1590  {
1591  if (pexports[i].bVersionIncluded)
1592  OutputLine_def(file, &pexports[i]);
1593  }
1594 
1595  fclose(file);
1596  }
1597 
1598  if (pszStubFileName)
1599  {
1600  /* Open output file */
1601  file = fopen(pszStubFileName, "w");
1602  if (!file)
1603  {
1604  fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1605  return -5;
1606  }
1607 
1609 
1610  for (i = 0; i < cExports; i++)
1611  {
1612  if (pexports[i].bVersionIncluded)
1613  OutputLine_stub(file, &pexports[i]);
1614  }
1615 
1616  fclose(file);
1617  }
1618 
1619  if (pszLibStubName)
1620  {
1621  /* Open output file */
1622  file = fopen(pszLibStubName, "w");
1623  if (!file)
1624  {
1625  fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
1626  return -5;
1627  }
1628 
1630 
1631  for (i = 0; i < cExports; i++)
1632  {
1633  if (pexports[i].bVersionIncluded)
1634  OutputLine_asmstub(file, &pexports[i]);
1635  }
1636 
1637  fprintf(file, "\n END\n");
1638  fclose(file);
1639  }
1640 
1641  free(pexports);
1642 
1643  return 0;
1644 }
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:1352
#define strcasecmp
Definition: fake.h:9
int OutputLine_stub(FILE *file, EXPORT *pexp)
Definition: spec2def.c:242
void OutputHeader_stub(FILE *file)
Definition: spec2def.c:219
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int gbNotPrivateNoWarn
Definition: spec2def.c:67
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:748
void OutputHeader_def(FILE *file, char *libname)
Definition: spec2def.c:537
_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
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
char * gpszUnderscore
Definition: spec2def.c:74
_CRTIMP void __cdecl rewind(_Inout_ FILE *_File)
int gbMSComp
Definition: spec2def.c:65
const char file[]
Definition: icontest.c:11
void OutputHeader_asmstub(FILE *file, char *libname)
Definition: spec2def.c:441
int giArch
Definition: spec2def.c:69
char * pszSourceFileName
Definition: spec2def.c:72
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:1397
EXPORT * ParseFile(char *pcStart, FILE *fileDest, unsigned *cExports)
Definition: spec2def.c:868
int gbImportLib
Definition: spec2def.c:66
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
#define NULL
Definition: types.h:112
char * pszArchString2
Definition: spec2def.c:71
_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:73
unsigned guOsVersion
Definition: spec2def.c:76
int gbTracing
Definition: spec2def.c:68
int OutputLine_asmstub(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:479
static unsigned(__cdecl *hash_bstr)(bstr_t s)
char * pszArchString
Definition: spec2def.c:70
Definition: fci.c:126

◆ NextLine()

const char* NextLine ( const char pc)

Definition at line 179 of file spec2def.c.

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

Referenced by ParseFile().

◆ NextToken()

const char* NextToken ( const char pc)

Definition at line 201 of file spec2def.c.

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

Referenced by ParseFile().

◆ Output_stublabel()

void Output_stublabel ( FILE fileDest,
char pszSymbolName 
)

Definition at line 460 of file spec2def.c.

461 {
462  if (giArch == ARCH_ARM || giArch == ARCH_ARM64)
463  {
464  fprintf(fileDest,
465  "\tEXPORT |%s| [FUNC]\n|%s|\n",
466  pszSymbolName,
467  pszSymbolName);
468  }
469  else
470  {
471  fprintf(fileDest,
472  "PUBLIC %s\n%s: nop\n",
473  pszSymbolName,
474  pszSymbolName);
475  }
476 }
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int giArch
Definition: spec2def.c:69

Referenced by OutputLine_asmstub().

◆ OutputHeader_asmstub()

void OutputHeader_asmstub ( FILE file,
char libname 
)

Definition at line 441 of file spec2def.c.

442 {
443  fprintf(file, "; File generated automatically, do not edit!\n\n");
444 
445  if (giArch == ARCH_X86)
446  {
447  fprintf(file, ".586\n.model flat\n.code\n");
448  }
449  else if (giArch == ARCH_AMD64)
450  {
451  fprintf(file, ".code\n");
452  }
453  else if (giArch == ARCH_ARM || giArch == ARCH_ARM64)
454  {
455  fprintf(file, " AREA |.text|,ALIGN=2,CODE,READONLY\n\n");
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:69
Definition: fci.c:126

Referenced by main().

◆ OutputHeader_def()

void OutputHeader_def ( FILE file,
char libname 
)

Definition at line 537 of file spec2def.c.

538 {
539  fprintf(file,
540  "; File generated automatically, do not edit!\n\n"
541  "NAME %s\n\n"
542  "EXPORTS\n",
543  libname);
544 }
_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 219 of file spec2def.c.

220 {
221  fprintf(file, "/* This file is autogenerated, do not edit. */\n\n"
222  "#include <stubs.h>\n");
223 
224  if (gbTracing)
225  {
226  fprintf(file, "#include <wine/debug.h>\n");
227  fprintf(file, "#include <inttypes.h>\n");
228  fprintf(file, "WINE_DECLARE_DEBUG_CHANNEL(relay);\n");
229  }
230 
231  /* __int128 is not supported on x86, so use a custom type */
232  fprintf(file, "\n"
233  "typedef struct {\n"
234  " __int64 lower;\n"
235  " __int64 upper;\n"
236  "} MyInt128;\n");
237 
238  fprintf(file, "\n");
239 }
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int gbTracing
Definition: spec2def.c:68
Definition: fci.c:126

Referenced by main().

◆ OutputLine_asmstub()

int OutputLine_asmstub ( FILE fileDest,
EXPORT pexp 
)

Definition at line 479 of file spec2def.c.

480 {
481  char szNameBuffer[128];
482 
483  /* Handle autoname */
484  if (pexp->strName.len == 1 && pexp->strName.buf[0] == '@')
485  {
486  sprintf(szNameBuffer, "%s_stub_ordinal%d",
487  gpszUnderscore, pexp->nOrdinal);
488  }
489  else if (giArch != ARCH_X86)
490  {
491  /* Does the string already have stdcall decoration? */
492  const char *pcAt = ScanToken(pexp->strName.buf, '@');
493  if (pcAt && (pcAt < (pexp->strName.buf + pexp->strName.len)) &&
494  (pexp->strName.buf[0] == '_'))
495  {
496  /* Skip leading underscore and remove trailing decoration */
497  sprintf(szNameBuffer, "_stub_%.*s",
498  (int)(pcAt - pexp->strName.buf - 1),
499  pexp->strName.buf + 1);
500  }
501  else
502  {
503  sprintf(szNameBuffer, "_stub_%.*s",
504  pexp->strName.len, pexp->strName.buf);
505  }
506  }
507  else if (pexp->nCallingConvention == CC_STDCALL)
508  {
509  sprintf(szNameBuffer, "__stub_%.*s@%d",
510  pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
511  }
512  else if (pexp->nCallingConvention == CC_FASTCALL)
513  {
514  sprintf(szNameBuffer, "@_stub_%.*s@%d",
515  pexp->strName.len, pexp->strName.buf, pexp->nStackBytes);
516  }
517  else if ((pexp->nCallingConvention == CC_CDECL) ||
518  (pexp->nCallingConvention == CC_THISCALL) ||
519  (pexp->nCallingConvention == CC_EXTERN) ||
520  (pexp->nCallingConvention == CC_STUB))
521  {
522  sprintf(szNameBuffer, "__stub_%.*s",
523  pexp->strName.len, pexp->strName.buf);
524  }
525  else
526  {
527  fprintf(stderr, "Invalid calling convention");
528  return 0;
529  }
530 
531  Output_stublabel(fileDest, szNameBuffer);
532 
533  return 1;
534 }
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:168
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
char * gpszUnderscore
Definition: spec2def.c:74
int giArch
Definition: spec2def.c:69
void Output_stublabel(FILE *fileDest, char *pszSymbolName)
Definition: spec2def.c:460
int nStackBytes
Definition: spec2def.c:26
FILE * stderr

Referenced by main().

◆ OutputLine_def()

int OutputLine_def ( FILE fileDest,
EXPORT pexp 
)

Definition at line 748 of file spec2def.c.

749 {
750  /* Don't add private exports to the import lib */
751  if (gbImportLib && (pexp->uFlags & FL_PRIVATE))
752  {
753  DbgPrint("OutputLine_def: skipping private export '%.*s'...\n", pexp->strName.len, pexp->strName.buf);
754  return 1;
755  }
756 
757  /* For MS linker, forwarded externs are managed via #pragma comment(linker,"/export:_data=org.data,DATA") */
758  if (gbMSComp && !gbImportLib && (pexp->nCallingConvention == CC_EXTERN) &&
759  (pexp->strTarget.buf != NULL) && !!ScanToken(pexp->strTarget.buf, '.'))
760  {
761  DbgPrint("OutputLine_def: skipping forwarded extern export '%.*s' ->'%.*s'...\n",
762  pexp->strName.len, pexp->strName.buf, pexp->strTarget.len, pexp->strTarget.buf);
763  return 1;
764  }
765 
766  DbgPrint("OutputLine_def: '%.*s'...\n", pexp->strName.len, pexp->strName.buf);
767  fprintf(fileDest, " ");
768 
769  if (gbMSComp)
770  OutputLine_def_MS(fileDest, pexp);
771  else
772  OutputLine_def_GCC(fileDest, pexp);
773 
774  /* On GCC builds we force ordinals */
775  if ((pexp->uFlags & FL_ORDINAL) || (!gbMSComp && !gbImportLib))
776  {
777  fprintf(fileDest, " @%d", pexp->nOrdinal);
778  }
779 
780  if (pexp->uFlags & FL_NONAME)
781  {
782  fprintf(fileDest, " NONAME");
783  }
784 
785  /* Either PRIVATE or DATA */
786  if (pexp->uFlags & FL_PRIVATE)
787  {
788  fprintf(fileDest, " PRIVATE");
789  }
790  else if (pexp->nCallingConvention == CC_EXTERN)
791  {
792  fprintf(fileDest, " DATA");
793  }
794 
795  fprintf(fileDest, "\n");
796 
797  return 1;
798 }
STRING strName
Definition: spec2def.c:22
int nOrdinal
Definition: spec2def.c:25
void OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:681
int nCallingConvention
Definition: spec2def.c:24
const char * ScanToken(const char *token, char chr)
Definition: spec2def.c:168
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int gbMSComp
Definition: spec2def.c:65
unsigned int uFlags
Definition: spec2def.c:29
int gbImportLib
Definition: spec2def.c:66
#define NULL
Definition: types.h:112
void OutputLine_def_MS(FILE *fileDest, EXPORT *pexp)
Definition: spec2def.c:630
STRING strTarget
Definition: spec2def.c:23
#define DbgPrint(...)
Definition: spec2def.c:77

Referenced by main().

◆ OutputLine_def_GCC()

void OutputLine_def_GCC ( FILE fileDest,
EXPORT pexp 
)

Definition at line 681 of file spec2def.c.

682 {
683  int bTracing = 0;
684  /* Print the function name, with decoration for export libs */
685  PrintName(fileDest, pexp, &pexp->strName, gbImportLib);
686  DbgPrint("Generating def line for '%.*s'\n", pexp->strName.len, pexp->strName.buf);
687 
688  /* Check if this is a forwarded export */
689  if (pexp->strTarget.buf)
690  {
691  int fIsExternal = !!ScanToken(pexp->strTarget.buf, '.');
692  DbgPrint("Got redirect '%.*s'\n", pexp->strTarget.len, pexp->strTarget.buf);
693 
694  /* print the target name, don't decorate if it is external */
695  fprintf(fileDest, "=");
696  PrintName(fileDest, pexp, &pexp->strTarget, !fIsExternal);
697  }
698  else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
699  (pexp->strName.buf[0] == '?'))
700  {
701  /* C++ stubs are forwarded to C stubs */
702  fprintf(fileDest, "=stub_function%d", pexp->nNumber);
703  }
704  else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) &&
705  (pexp->nCallingConvention == CC_STDCALL) &&
706  (pexp->strName.buf[0] != '?'))
707  {
708  /* Redirect it to the relay-tracing trampoline */
709  char buf[256];
710  STRING strTarget;
711  fprintf(fileDest, "=");
712  sprintf(buf, "$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
713  strTarget.buf = buf;
714  strTarget.len = pexp->strName.len + 12;
715  PrintName(fileDest, pexp, &strTarget, 1);
716  bTracing = 1;
717  }
718 
719  /* Special handling for stdcall and fastcall, but not C++ exports*/
720  if ((giArch == ARCH_X86) &&
721  (pexp->strName.buf[0] != '?') &&
722  ((pexp->nCallingConvention == CC_STDCALL) ||
723  (pexp->nCallingConvention == CC_FASTCALL)))
724  {
725  /* Is this the import lib? */
726  if (gbImportLib)
727  {
728  /* Is the name in the spec file decorated? */
729  const char* pcDeco = ScanToken(pexp->strName.buf, '@');
730  if (pcDeco &&
731  (pexp->strName.len > 1) &&
732  (pcDeco < pexp->strName.buf + pexp->strName.len))
733  {
734  /* Write the name including the leading @ */
735  fprintf(fileDest, "==%.*s", pexp->strName.len, pexp->strName.buf);
736  }
737  }
738  else if ((!pexp->strTarget.buf) && !(bTracing))
739  {
740  /* Write a forwarder to the actual decorated symbol */
741  fprintf(fileDest, "=");
742  PrintName(fileDest, pexp, &pexp->strName, 1);
743  }
744  }
745 }
void PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
Definition: spec2def.c:547
STRING strName
Definition: spec2def.c:22
#define sprintf(buf, format,...)
Definition: sprintf.c:55
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
int nCallingConvention
Definition: spec2def.c:24
const char * ScanToken(const char *token, char chr)
Definition: spec2def.c:168
_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:69
unsigned int uFlags
Definition: spec2def.c:29
int gbImportLib
Definition: spec2def.c:66
STRING strTarget
Definition: spec2def.c:23
int gbTracing
Definition: spec2def.c:68
#define DbgPrint(...)
Definition: spec2def.c:77

Referenced by OutputLine_def().

◆ OutputLine_def_MS()

void OutputLine_def_MS ( FILE fileDest,
EXPORT pexp 
)

Definition at line 630 of file spec2def.c.

631 {
632  PrintName(fileDest, pexp, &pexp->strName, 0);
633 
634  if (gbImportLib)
635  {
636  /* Redirect to a stub function, to get the right decoration in the lib */
637  fprintf(fileDest, "=_stub_");
638  PrintName(fileDest, pexp, &pexp->strName, 0);
639  }
640  else if (pexp->strTarget.buf)
641  {
642  if (pexp->strName.buf[0] == '?')
643  {
644  //fprintf(stderr, "warning: ignoring C++ redirection %.*s -> %.*s\n",
645  // pexp->strName.len, pexp->strName.buf, pexp->strTarget.len, pexp->strTarget.buf);
646  }
647  else
648  {
649  fprintf(fileDest, "=");
650 
651  /* If the original name was decorated, use decoration in the forwarder as well */
652  if ((giArch == ARCH_X86) && ScanToken(pexp->strName.buf, '@') &&
653  !ScanToken(pexp->strTarget.buf, '@') &&
654  ((pexp->nCallingConvention == CC_STDCALL) ||
655  (pexp->nCallingConvention == CC_FASTCALL)) )
656  {
657  PrintName(fileDest, pexp, &pexp->strTarget, 1);
658  }
659  else
660  {
661  /* Write the undecorated redirection name */
662  fprintf(fileDest, "%.*s", pexp->strTarget.len, pexp->strTarget.buf);
663  }
664  }
665  }
666  else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
667  (pexp->strName.buf[0] == '?'))
668  {
669  /* C++ stubs are forwarded to C stubs */
670  fprintf(fileDest, "=stub_function%d", pexp->nNumber);
671  }
672  else if (gbTracing && ((pexp->uFlags & FL_NORELAY) == 0) && (pexp->nCallingConvention == CC_STDCALL) &&
673  (pexp->strName.buf[0] != '?'))
674  {
675  /* Redirect it to the relay-tracing trampoline */
676  fprintf(fileDest, "=$relaytrace$%.*s", pexp->strName.len, pexp->strName.buf);
677  }
678 }
void PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
Definition: spec2def.c:547
STRING strName
Definition: spec2def.c:22
int nCallingConvention
Definition: spec2def.c:24
const char * ScanToken(const char *token, char chr)
Definition: spec2def.c:168
_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:69
unsigned int uFlags
Definition: spec2def.c:29
int gbImportLib
Definition: spec2def.c:66
STRING strTarget
Definition: spec2def.c:23
int gbTracing
Definition: spec2def.c:68

Referenced by OutputLine_def().

◆ OutputLine_stub()

int OutputLine_stub ( FILE file,
EXPORT pexp 
)

Definition at line 242 of file spec2def.c.

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

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

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

169 {
170  while (!IsSeparator(*token))
171  {
172  if (*token == chr) return token;
173  token++;
174  }
175  return 0;
176 }
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:147

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

◆ TokenLength()

int TokenLength ( const char pc)

Definition at line 191 of file spec2def.c.

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

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

◆ usage()

void usage ( void  )

Definition at line 1397 of file spec2def.c.

1398 {
1399  printf("syntax: spec2def [<options> ...] <spec file>\n"
1400  "Possible options:\n"
1401  " -h --help print this help screen\n"
1402  " -l=<file> generate an asm lib stub\n"
1403  " -d=<file> generate a def file\n"
1404  " -s=<file> generate a stub file\n"
1405  " --ms MSVC compatibility\n"
1406  " -n=<name> name of the dll\n"
1407  " --implib generate a def file for an import library\n"
1408  " --no-private-warnings suppress warnings about symbols that should be -private\n"
1409  " -a=<arch> set architecture to <arch> (i386, x86_64, arm, arm64)\n"
1410  " --with-tracing generate wine-like \"+relay\" trace trampolines (needs -s)\n");
1411 }
#define printf
Definition: freeldr.h:94

Referenced by main().

Variable Documentation

◆ astrCallingConventions

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

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

Referenced by ParseFile().

◆ gbDebug

int gbDebug

Definition at line 75 of file spec2def.c.

Referenced by ParseFile().

◆ gbImportLib

int gbImportLib = 0

Definition at line 66 of file spec2def.c.

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

◆ gbMSComp

int gbMSComp = 0

Definition at line 65 of file spec2def.c.

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

◆ gbNotPrivateNoWarn

int gbNotPrivateNoWarn = 0

Definition at line 67 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ gbTracing

int gbTracing = 0

◆ giArch

◆ gpszUnderscore

char* gpszUnderscore = ""

Definition at line 74 of file spec2def.c.

Referenced by main(), OutputLine_asmstub(), and OutputLine_stub().

◆ guOsVersion

unsigned guOsVersion = 0x502

Definition at line 76 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszArchString

char* pszArchString = "i386"

Definition at line 70 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszArchString2

char* pszArchString2

Definition at line 71 of file spec2def.c.

Referenced by main(), and ParseFile().

◆ pszDllName

char* pszDllName = NULL

Definition at line 73 of file spec2def.c.

Referenced by main(), and OutputLine_stub().

◆ pszSourceFileName

char* pszSourceFileName = NULL

Definition at line 72 of file spec2def.c.

Referenced by main(), and ParseFile().