| ︙ | | | ︙ | |
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
** doesn't tell about the objects structure. A typical forward declaration
** is:
**
** struct Xyzzy;
**
** Not every object has a forward declaration. If it does, thought, the
** forward declaration will be contained in the zFwd field for C and
** the zFwdCpp for C++. The zDecl field contains the complete
** declaration text.
*/
typedef struct Decl Decl;
struct Decl {
char *zName; /* Name of the object being declared. The appearance
** of this name is a source file triggers the declaration
** to be added to the header for that file. */
char *zFile; /* File from which extracted. */
char *zIf; /* Surround the declaration with this #if */
char *zFwd; /* A forward declaration. NULL if there is none. */
char *zFwdCpp; /* Use this forward declaration for C++. */
char *zDecl; /* A full declaration of this object */
char *zExtra; /* Extra declaration text inserted into class objects */
int extraType; /* Last public:, protected: or private: in zExtraDecl */
struct Include *pInclude; /* #includes that come before this declaration */
|
|
|
|
|
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
** doesn't tell about the objects structure. A typical forward declaration
** is:
**
** struct Xyzzy;
**
** Not every object has a forward declaration. If it does, thought, the
** forward declaration will be contained in the zFwd field for C and
** the zFwdCpp for C++. The zDecl field contains the complete
** declaration text.
*/
typedef struct Decl Decl;
struct Decl {
char *zName; /* Name of the object being declared. The appearance
** of this name is a source file triggers the declaration
** to be added to the header for that file. */
const char *zFile; /* File from which extracted. */
char *zIf; /* Surround the declaration with this #if */
char *zFwd; /* A forward declaration. NULL if there is none. */
char *zFwdCpp; /* Use this forward declaration for C++. */
char *zDecl; /* A full declaration of this object */
char *zExtra; /* Extra declaration text inserted into class objects */
int extraType; /* Last public:, protected: or private: in zExtraDecl */
struct Include *pInclude; /* #includes that come before this declaration */
|
| ︙ | | | ︙ | |
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
** a library, then the object is not visible to users
** of the library. (i.e. the object does not appear
** in the output when using the -H option.)
**
** EXPORT scope The object is visible and usable everywhere.
**
** The DP_Flag is a temporary use flag that is used during processing to
** prevent an infinite loop. It's use is localized.
**
** The DP_Cplusplus, DP_ExternCReqd and DP_ExternReqd flags are permanent
** and are used to specify what type of declaration the object requires.
*/
#define DP_Forward 0x001 /* Has a forward declaration in this file */
#define DP_Declared 0x002 /* Has a full declaration in this file */
#define DP_Export 0x004 /* Export this declaration */
|
|
|
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
** a library, then the object is not visible to users
** of the library. (i.e. the object does not appear
** in the output when using the -H option.)
**
** EXPORT scope The object is visible and usable everywhere.
**
** The DP_Flag is a temporary use flag that is used during processing to
** prevent an infinite loop. It's use is localized.
**
** The DP_Cplusplus, DP_ExternCReqd and DP_ExternReqd flags are permanent
** and are used to specify what type of declaration the object requires.
*/
#define DP_Forward 0x001 /* Has a forward declaration in this file */
#define DP_Declared 0x002 /* Has a full declaration in this file */
#define DP_Export 0x004 /* Export this declaration */
|
| ︙ | | | ︙ | |
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
** the same "flags" field.
**
** Be careful not to confuse PS_Export with DP_Export or
** PS_Local with DP_Local. Their names are similar, but the meanings
** of these flags are very different.
*/
#define PS_Extern 0x000800 /* "extern" has been seen */
#define PS_Export 0x001000 /* If between "#if EXPORT_INTERFACE"
** and "#endif" */
#define PS_Export2 0x002000 /* If "EXPORT" seen */
#define PS_Typedef 0x004000 /* If "typedef" has been seen */
#define PS_Static 0x008000 /* If "static" has been seen */
#define PS_Interface 0x010000 /* If within #if INTERFACE..#endif */
#define PS_Method 0x020000 /* If "::" token has been seen */
#define PS_Local 0x040000 /* If within #if LOCAL_INTERFACE..#endif */
|
|
|
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
** the same "flags" field.
**
** Be careful not to confuse PS_Export with DP_Export or
** PS_Local with DP_Local. Their names are similar, but the meanings
** of these flags are very different.
*/
#define PS_Extern 0x000800 /* "extern" has been seen */
#define PS_Export 0x001000 /* If between "#if EXPORT_INTERFACE"
** and "#endif" */
#define PS_Export2 0x002000 /* If "EXPORT" seen */
#define PS_Typedef 0x004000 /* If "typedef" has been seen */
#define PS_Static 0x008000 /* If "static" has been seen */
#define PS_Interface 0x010000 /* If within #if INTERFACE..#endif */
#define PS_Method 0x020000 /* If "::" token has been seen */
#define PS_Local 0x040000 /* If within #if LOCAL_INTERFACE..#endif */
|
| ︙ | | | ︙ | |
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
#define TY_Variable 0x01000000
#define TY_Structure 0x02000000
#define TY_Union 0x04000000
#define TY_Enumeration 0x08000000
#define TY_Defunct 0x10000000 /* Used to erase a declaration */
/*
** Each nested #if (or #ifdef or #ifndef) is stored in a stack of
** instances of the following structure.
*/
typedef struct Ifmacro Ifmacro;
struct Ifmacro {
int nLine; /* Line number where this macro occurs */
char *zCondition; /* Text of the condition for this macro */
Ifmacro *pNext; /* Next down in the stack */
|
|
|
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
#define TY_Variable 0x01000000
#define TY_Structure 0x02000000
#define TY_Union 0x04000000
#define TY_Enumeration 0x08000000
#define TY_Defunct 0x10000000 /* Used to erase a declaration */
/*
** Each nested #if (or #ifdef or #ifndef) is stored in a stack of
** instances of the following structure.
*/
typedef struct Ifmacro Ifmacro;
struct Ifmacro {
int nLine; /* Line number where this macro occurs */
char *zCondition; /* Text of the condition for this macro */
Ifmacro *pNext; /* Next down in the stack */
|
| ︙ | | | ︙ | |
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
|
char *zHdr; /* Name of the generated .h file for this input.
** Will be NULL if input is to be scanned only */
int flags; /* One or more DP_, PS_ and/or TY_ flags */
InFile *pNext; /* Next input file in the list of them all */
IdentTable idTable; /* All identifiers in this input file */
};
/*
** An unbounded string is able to grow without limit. We use these
** to construct large in-memory strings from lots of smaller components.
*/
typedef struct String String;
struct String {
int nAlloc; /* Number of bytes allocated */
int nUsed; /* Number of bytes used (not counting null terminator) */
|
|
|
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
|
char *zHdr; /* Name of the generated .h file for this input.
** Will be NULL if input is to be scanned only */
int flags; /* One or more DP_, PS_ and/or TY_ flags */
InFile *pNext; /* Next input file in the list of them all */
IdentTable idTable; /* All identifiers in this input file */
};
/*
** An unbounded string is able to grow without limit. We use these
** to construct large in-memory strings from lots of smaller components.
*/
typedef struct String String;
struct String {
int nAlloc; /* Number of bytes allocated */
int nUsed; /* Number of bytes used (not counting null terminator) */
|
| ︙ | | | ︙ | |
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
|
** The following text line appears at the top of every file generated
** by this program. By recognizing this line, the program can be sure
** never to read a file that it generated itself.
**
** The "#undef INTERFACE" part is a hack to work around a name collision
** in MSVC 2008.
*/
const char zTopLine[] =
"/* \aThis file was automatically generated. Do not edit! */\n"
"#undef INTERFACE\n";
#define nTopLine (sizeof(zTopLine)-1)
/*
** The name of the file currently being parsed.
*/
static char *zFilename;
/*
** The stack of #if macros for the file currently being parsed.
*/
static Ifmacro *ifStack = 0;
/*
|
|
|
|
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
|
** The following text line appears at the top of every file generated
** by this program. By recognizing this line, the program can be sure
** never to read a file that it generated itself.
**
** The "#undef INTERFACE" part is a hack to work around a name collision
** in MSVC 2008.
*/
const char zTopLine[] =
"/* \aThis file was automatically generated. Do not edit! */\n"
"#undef INTERFACE\n";
#define nTopLine (sizeof(zTopLine)-1)
/*
** The name of the file currently being parsed.
*/
static const char *zFilename;
/*
** The stack of #if macros for the file currently being parsed.
*/
static Ifmacro *ifStack = 0;
/*
|
| ︙ | | | ︙ | |
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
|
*/
static char *ReadFile(const char *zFilename){
struct stat sStat;
FILE *pIn;
char *zBuf;
int n;
if( stat(zFilename,&sStat)!=0
#ifndef WIN32
|| !S_ISREG(sStat.st_mode)
#endif
){
return 0;
}
pIn = fopen(zFilename,"r");
|
|
|
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
|
*/
static char *ReadFile(const char *zFilename){
struct stat sStat;
FILE *pIn;
char *zBuf;
int n;
if( stat(zFilename,&sStat)!=0
#ifndef WIN32
|| !S_ISREG(sStat.st_mode)
#endif
){
return 0;
}
pIn = fopen(zFilename,"r");
|
| ︙ | | | ︙ | |
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
|
}else{
isBlockComment = 0;
}
}
}
i++;
}
if( z[i] ){
i += 2;
}else{
isBlockComment = 0;
fprintf(stderr,"%s:%d: Unterminated comment\n",
zFilename, startLine);
nErr++;
}
pToken->eType = isBlockComment==2 ? TT_BlockComment : TT_Comment;
pToken->nText = i - pIn->i;
}else{
/* A divide operator */
pToken->eType = TT_Other;
pToken->nText = 1 + (z[i+1]=='+');
}
break;
case '0':
if( z[i+1]=='x' || z[i+1]=='X' ){
/* A hex constant */
i += 2;
while( isxdigit(z[i]) ){ i++; }
}else{
/* An octal constant */
while( isdigit(z[i]) ){ i++; }
|
|
|
|
|
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
|
}else{
isBlockComment = 0;
}
}
}
i++;
}
if( z[i] ){
i += 2;
}else{
isBlockComment = 0;
fprintf(stderr,"%s:%d: Unterminated comment\n",
zFilename, startLine);
nErr++;
}
pToken->eType = isBlockComment==2 ? TT_BlockComment : TT_Comment;
pToken->nText = i - pIn->i;
}else{
/* A divide operator */
pToken->eType = TT_Other;
pToken->nText = 1 + (z[i+1]=='+');
}
break;
case '0':
if( z[i+1]=='x' || z[i+1]=='X' ){
/* A hex constant */
i += 2;
while( isxdigit(z[i]) ){ i++; }
}else{
/* An octal constant */
while( isdigit(z[i]) ){ i++; }
|
| ︙ | | | ︙ | |
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
|
case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W':
case 'X': case 'Y': case 'Z': case '_':
while( isalnum(z[i]) || z[i]=='_' ){ i++; };
pToken->eType = TT_Id;
pToken->nText = i - pIn->i;
break;
case ':':
pToken->eType = TT_Other;
pToken->nText = 1 + (z[i+1]==':');
break;
case '=':
case '<':
case '>':
case '+':
case '-':
case '*':
case '%':
case '^':
case '&':
case '|':
pToken->eType = TT_Other;
pToken->nText = 1 + (z[i+1]=='=');
break;
default:
pToken->eType = TT_Other;
pToken->nText = 1;
|
|
|
|
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
|
case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W':
case 'X': case 'Y': case 'Z': case '_':
while( isalnum(z[i]) || z[i]=='_' ){ i++; };
pToken->eType = TT_Id;
pToken->nText = i - pIn->i;
break;
case ':':
pToken->eType = TT_Other;
pToken->nText = 1 + (z[i+1]==':');
break;
case '=':
case '<':
case '>':
case '+':
case '-':
case '*':
case '%':
case '^':
case '&':
case '|':
pToken->eType = TT_Other;
pToken->nText = 1 + (z[i+1]=='=');
break;
default:
pToken->eType = TT_Other;
pToken->nText = 1;
|
| ︙ | | | ︙ | |
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
|
}
break;
}
}
/* NOT REACHED */
}
/*
** This routine looks for identifiers (strings of contiguous alphanumeric
** characters) within a preprocessor directive and adds every such string
** found to the given identifier table
*/
static void FindIdentifiersInMacro(Token *pToken, IdentTable *pTable){
Token sToken;
InStream sIn;
|
|
|
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
|
}
break;
}
}
/* NOT REACHED */
}
/*
** This routine looks for identifiers (strings of contiguous alphanumeric
** characters) within a preprocessor directive and adds every such string
** found to the given identifier table
*/
static void FindIdentifiersInMacro(Token *pToken, IdentTable *pTable){
Token sToken;
InStream sIn;
|
| ︙ | | | ︙ | |
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
|
return nErr;
case TT_Id:
if( pTable ){
IdentTableInsert(pTable,pToken->zText,pToken->nText);
}
break;
case TT_Preprocessor:
if( pTable!=0 ){
FindIdentifiersInMacro(pToken,pTable);
}
break;
case TT_Other:
|
|
|
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
|
return nErr;
case TT_Id:
if( pTable ){
IdentTableInsert(pTable,pToken->zText,pToken->nText);
}
break;
case TT_Preprocessor:
if( pTable!=0 ){
FindIdentifiersInMacro(pToken,pTable);
}
break;
case TT_Other:
|
| ︙ | | | ︙ | |
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
|
if( zFile==0 ){
fprintf(stderr,"Can't read file \"%s\"\n",argv[1]);
exit(1);
}
pList = TokenizeFile(zFile,&sTable);
for(p=pList; p; p=p->pNext){
int j;
switch( p->eType ){
case TT_Space:
printf("%4d: Space\n",p->nLine);
break;
case TT_Id:
printf("%4d: Id %.*s\n",p->nLine,p->nText,p->zText);
break;
case TT_Preprocessor:
|
|
|
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
|
if( zFile==0 ){
fprintf(stderr,"Can't read file \"%s\"\n",argv[1]);
exit(1);
}
pList = TokenizeFile(zFile,&sTable);
for(p=pList; p; p=p->pNext){
int j;
switch( p->eType ){
case TT_Space:
printf("%4d: Space\n",p->nLine);
break;
case TT_Id:
printf("%4d: Id %.*s\n",p->nLine,p->nText,p->zText);
break;
case TT_Preprocessor:
|
| ︙ | | | ︙ | |
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
|
case TT_Number:
printf("%s%.*s", needSpace ? " " : "", pFirst->nText, pFirst->zText);
needSpace = 1;
break;
default:
c = pFirst->zText[0];
printf("%s%.*s",
(needSpace && (c=='*' || c=='{')) ? " " : "",
pFirst->nText, pFirst->zText);
needSpace = pFirst->zText[0]==',';
break;
}
pFirst = pFirst->pNext;
}
|
|
|
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
|
case TT_Number:
printf("%s%.*s", needSpace ? " " : "", pFirst->nText, pFirst->zText);
needSpace = 1;
break;
default:
c = pFirst->zText[0];
printf("%s%.*s",
(needSpace && (c=='*' || c=='{')) ? " " : "",
pFirst->nText, pFirst->zText);
needSpace = pFirst->zText[0]==',';
break;
}
pFirst = pFirst->pNext;
}
|
| ︙ | | | ︙ | |
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
|
int iSkip = 0;
int skipOne = 0;
StringInit(&str);
pLast = pLast->pNext;
while( pFirst!=pLast ){
if( pFirst==pSkip ){ iSkip = nSkip; }
if( iSkip>0 ){
iSkip--;
pFirst=pFirst->pNext;
continue;
}
switch( pFirst->eType ){
case TT_Preprocessor:
StringAppend(&str,"\n",1);
StringAppend(&str,pFirst->zText,pFirst->nText);
StringAppend(&str,"\n",1);
needSpace = 0;
break;
case TT_Id:
switch( pFirst->zText[0] ){
case 'E':
if( pFirst->nText==6 && strncmp(pFirst->zText,"EXPORT",6)==0 ){
skipOne = 1;
}
break;
case 'P':
switch( pFirst->nText ){
case 6: skipOne = !strncmp(pFirst->zText,"PUBLIC", 6); break;
|
|
|
|
|
|
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
|
int iSkip = 0;
int skipOne = 0;
StringInit(&str);
pLast = pLast->pNext;
while( pFirst!=pLast ){
if( pFirst==pSkip ){ iSkip = nSkip; }
if( iSkip>0 ){
iSkip--;
pFirst=pFirst->pNext;
continue;
}
switch( pFirst->eType ){
case TT_Preprocessor:
StringAppend(&str,"\n",1);
StringAppend(&str,pFirst->zText,pFirst->nText);
StringAppend(&str,"\n",1);
needSpace = 0;
break;
case TT_Id:
switch( pFirst->zText[0] ){
case 'E':
if( pFirst->nText==6 && strncmp(pFirst->zText,"EXPORT",6)==0 ){
skipOne = 1;
}
break;
case 'P':
switch( pFirst->nText ){
case 6: skipOne = !strncmp(pFirst->zText,"PUBLIC", 6); break;
|
| ︙ | | | ︙ | |
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
|
return 0;
}
pLast = pLast->pNext;
for(p=pFirst; p && p!=pLast; p=p->pNext){
if( p->eType==TT_Id ){
static IdentTable sReserved;
static int isInit = 0;
static char *aWords[] = { "char", "class",
"const", "double", "enum", "extern", "EXPORT", "ET_PROC",
"float", "int", "long",
"PRIVATE", "PROTECTED", "PUBLIC",
"register", "static", "struct", "sizeof", "signed", "typedef",
"union", "volatile", "virtual", "void", };
if( !isInit ){
int i;
for(i=0; i<sizeof(aWords)/sizeof(aWords[0]); i++){
IdentTableInsert(&sReserved,aWords[i],0);
}
isInit = 1;
}
|
|
|
|
|
|
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
|
return 0;
}
pLast = pLast->pNext;
for(p=pFirst; p && p!=pLast; p=p->pNext){
if( p->eType==TT_Id ){
static IdentTable sReserved;
static int isInit = 0;
static const char *aWords[] = { "char", "class",
"const", "double", "enum", "extern", "EXPORT", "ET_PROC",
"float", "int", "long",
"PRIVATE", "PROTECTED", "PUBLIC",
"register", "static", "struct", "sizeof", "signed", "typedef",
"union", "volatile", "virtual", "void", };
if( !isInit ){
int i;
for(i=0; i<sizeof(aWords)/sizeof(aWords[0]); i++){
IdentTableInsert(&sReserved,aWords[i],0);
}
isInit = 1;
}
|
| ︙ | | | ︙ | |
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
|
return 0;
}
pCode = pLast;
while( pLast && pLast!=pFirst && pLast->zText[0]!=')' ){
pLast = pLast->pPrev;
}
if( pLast==0 || pLast==pFirst || pFirst->pNext==pLast ){
fprintf(stderr,"%s:%d: Unrecognized syntax.\n",
zFilename, pFirst->nLine);
return 1;
}
if( flags & (PS_Interface|PS_Export|PS_Local) ){
fprintf(stderr,"%s:%d: Missing \"inline\" on function or procedure.\n",
zFilename, pFirst->nLine);
return 1;
|
|
|
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
|
return 0;
}
pCode = pLast;
while( pLast && pLast!=pFirst && pLast->zText[0]!=')' ){
pLast = pLast->pPrev;
}
if( pLast==0 || pLast==pFirst || pFirst->pNext==pLast ){
fprintf(stderr,"%s:%d: Unrecognized syntax.\n",
zFilename, pFirst->nLine);
return 1;
}
if( flags & (PS_Interface|PS_Export|PS_Local) ){
fprintf(stderr,"%s:%d: Missing \"inline\" on function or procedure.\n",
zFilename, pFirst->nLine);
return 1;
|
| ︙ | | | ︙ | |
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
|
fprintf(stderr,"%s:%d: malformed inline procedure definition\n",
zFilename, pFirst->nLine);
return 1;
}
#ifdef DEBUG
if( debugMask & PARSER ){
printf("**** Found inline routine: %.*s on line %d...\n",
pName->nText, pName->zText, pFirst->nLine);
PrintTokens(pFirst,pEnd);
printf("\n");
}
#endif
pDecl = CreateDecl(pName->zText,pName->nText);
pDecl->pComment = pFirst->pComment;
|
|
|
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
|
fprintf(stderr,"%s:%d: malformed inline procedure definition\n",
zFilename, pFirst->nLine);
return 1;
}
#ifdef DEBUG
if( debugMask & PARSER ){
printf("**** Found inline routine: %.*s on line %d...\n",
pName->nText, pName->zText, pFirst->nLine);
PrintTokens(pFirst,pEnd);
printf("\n");
}
#endif
pDecl = CreateDecl(pName->zText,pName->nText);
pDecl->pComment = pFirst->pComment;
|
| ︙ | | | ︙ | |
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
|
**
** If pEnd is ';', then the determination is more difficult. We have
** to search for an occurrence of an ID followed immediately by '('.
** If found, we have a prototype. Otherwise we are dealing with a
** variable definition.
*/
static int isVariableDef(Token *pFirst, Token *pEnd){
if( pEnd && pEnd->zText[0]=='=' &&
(pEnd->pPrev->nText!=8 || strncmp(pEnd->pPrev->zText,"operator",8)!=0)
){
return 1;
}
while( pFirst && pFirst!=pEnd && pFirst->pNext && pFirst->pNext!=pEnd ){
if( pFirst->eType==TT_Id && pFirst->pNext->zText[0]=='(' ){
return 0;
|
|
|
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
|
**
** If pEnd is ';', then the determination is more difficult. We have
** to search for an occurrence of an ID followed immediately by '('.
** If found, we have a prototype. Otherwise we are dealing with a
** variable definition.
*/
static int isVariableDef(Token *pFirst, Token *pEnd){
if( pEnd && pEnd->zText[0]=='=' &&
(pEnd->pPrev->nText!=8 || strncmp(pEnd->pPrev->zText,"operator",8)!=0)
){
return 1;
}
while( pFirst && pFirst!=pEnd && pFirst->pNext && pFirst->pNext!=pEnd ){
if( pFirst->eType==TT_Id && pFirst->pNext->zText[0]=='(' ){
return 0;
|
| ︙ | | | ︙ | |
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
|
** option was specified or the "LOCAL" keyword is used. */
return nErr;
}
while( pFirst!=0 && pFirst->pNext!=pEnd &&
((pFirst->nText==6 && strncmp(pFirst->zText,"static",6)==0)
|| (pFirst->nText==5 && strncmp(pFirst->zText,"LOCAL",6)==0))
){
/* Lose the initial "static" or local from local variables.
** We'll prepend "extern" later. */
pFirst = pFirst->pNext;
isLocal = 1;
}
if( pFirst==0 || !isLocal ){
return nErr;
}
}else if( flags & PS_Method ){
/* Methods are declared by their class. Don't declare separately. */
return nErr;
}
isVar = (flags & (PS_Typedef|PS_Method))==0 && isVariableDef(pFirst,pEnd);
if( isVar && (flags & (PS_Interface|PS_Export|PS_Local))!=0
&& (flags & PS_Extern)==0 ){
fprintf(stderr,"%s:%d: Can't define a variable in this context\n",
zFilename, pFirst->nLine);
nErr++;
}
pName = FindDeclName(pFirst,pEnd->pPrev);
if( pName==0 ){
|
|
|
|
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
|
** option was specified or the "LOCAL" keyword is used. */
return nErr;
}
while( pFirst!=0 && pFirst->pNext!=pEnd &&
((pFirst->nText==6 && strncmp(pFirst->zText,"static",6)==0)
|| (pFirst->nText==5 && strncmp(pFirst->zText,"LOCAL",6)==0))
){
/* Lose the initial "static" or local from local variables.
** We'll prepend "extern" later. */
pFirst = pFirst->pNext;
isLocal = 1;
}
if( pFirst==0 || !isLocal ){
return nErr;
}
}else if( flags & PS_Method ){
/* Methods are declared by their class. Don't declare separately. */
return nErr;
}
isVar = (flags & (PS_Typedef|PS_Method))==0 && isVariableDef(pFirst,pEnd);
if( isVar && (flags & (PS_Interface|PS_Export|PS_Local))!=0
&& (flags & PS_Extern)==0 ){
fprintf(stderr,"%s:%d: Can't define a variable in this context\n",
zFilename, pFirst->nLine);
nErr++;
}
pName = FindDeclName(pFirst,pEnd->pPrev);
if( pName==0 ){
|
| ︙ | | | ︙ | |
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
|
nCmd = 1;
while( isalpha(zCmd[nCmd]) ){
nCmd++;
}
if( nCmd==5 && strncmp(zCmd,"endif",5)==0 ){
/*
** Pop the if stack
*/
pIf = ifStack;
if( pIf==0 ){
fprintf(stderr,"%s:%d: extra '#endif'.\n",zFilename,pToken->nLine);
return 1;
}
ifStack = pIf->pNext;
SafeFree(pIf);
}else if( nCmd==6 && strncmp(zCmd,"define",6)==0 ){
/*
** Record a #define if we are in PS_Interface or PS_Export
*/
Decl *pDecl;
if( !(flags & (PS_Local|PS_Interface|PS_Export)) ){ return 0; }
zArg = &zCmd[6];
while( *zArg && isspace(*zArg) && *zArg!='\n' ){
zArg++;
}
|
|
|
|
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
|
nCmd = 1;
while( isalpha(zCmd[nCmd]) ){
nCmd++;
}
if( nCmd==5 && strncmp(zCmd,"endif",5)==0 ){
/*
** Pop the if stack
*/
pIf = ifStack;
if( pIf==0 ){
fprintf(stderr,"%s:%d: extra '#endif'.\n",zFilename,pToken->nLine);
return 1;
}
ifStack = pIf->pNext;
SafeFree(pIf);
}else if( nCmd==6 && strncmp(zCmd,"define",6)==0 ){
/*
** Record a #define if we are in PS_Interface or PS_Export
*/
Decl *pDecl;
if( !(flags & (PS_Local|PS_Interface|PS_Export)) ){ return 0; }
zArg = &zCmd[6];
while( *zArg && isspace(*zArg) && *zArg!='\n' ){
zArg++;
}
|
| ︙ | | | ︙ | |
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
|
if( flags & PS_Export ){
DeclSetProperty(pDecl,DP_Export);
}else if( flags & PS_Local ){
DeclSetProperty(pDecl,DP_Local);
}
}else if( nCmd==7 && strncmp(zCmd,"include",7)==0 ){
/*
** Record an #include if we are in PS_Interface or PS_Export
*/
Include *pInclude;
char *zIf;
if( !(flags & (PS_Interface|PS_Export)) ){ return 0; }
zArg = &zCmd[7];
while( *zArg && isspace(*zArg) ){ zArg++; }
|
|
|
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
|
if( flags & PS_Export ){
DeclSetProperty(pDecl,DP_Export);
}else if( flags & PS_Local ){
DeclSetProperty(pDecl,DP_Local);
}
}else if( nCmd==7 && strncmp(zCmd,"include",7)==0 ){
/*
** Record an #include if we are in PS_Interface or PS_Export
*/
Include *pInclude;
char *zIf;
if( !(flags & (PS_Interface|PS_Export)) ){ return 0; }
zArg = &zCmd[7];
while( *zArg && isspace(*zArg) ){ zArg++; }
|
| ︙ | | | ︙ | |
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
|
PushIfMacro(0,0,0,pToken->nLine,PS_Export);
}else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
PushIfMacro(0,0,0,pToken->nLine,PS_Local);
}else{
PushIfMacro(0,zArg,nArg,pToken->nLine,0);
}
}else if( nCmd==5 && strncmp(zCmd,"ifdef",5)==0 ){
/*
** Push an #ifdef.
*/
zArg = &zCmd[5];
while( *zArg && isspace(*zArg) && *zArg!='\n' ){
zArg++;
}
if( *zArg==0 || *zArg=='\n' ){ return 0; }
|
|
|
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
|
PushIfMacro(0,0,0,pToken->nLine,PS_Export);
}else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
PushIfMacro(0,0,0,pToken->nLine,PS_Local);
}else{
PushIfMacro(0,zArg,nArg,pToken->nLine,0);
}
}else if( nCmd==5 && strncmp(zCmd,"ifdef",5)==0 ){
/*
** Push an #ifdef.
*/
zArg = &zCmd[5];
while( *zArg && isspace(*zArg) && *zArg!='\n' ){
zArg++;
}
if( *zArg==0 || *zArg=='\n' ){ return 0; }
|
| ︙ | | | ︙ | |
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
|
zArg++;
}
if( *zArg==0 || *zArg=='\n' ){ return 0; }
nArg = pToken->nText + (int)(pToken->zText - zArg);
PushIfMacro("!defined",zArg,nArg,pToken->nLine,0);
}else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){
/*
** Invert the #if on the top of the stack
*/
if( ifStack==0 ){
fprintf(stderr,"%s:%d: '#else' without an '#if'\n",zFilename,
pToken->nLine);
return 1;
}
pIf = ifStack;
if( pIf->zCondition ){
ifStack = ifStack->pNext;
PushIfMacro("!",pIf->zCondition,strlen(pIf->zCondition),pIf->nLine,0);
SafeFree(pIf);
}else{
pIf->flags = 0;
}
}else{
/*
** This directive can be safely ignored
*/
return 0;
}
/*
** Recompute the preset flags
*/
*pPresetFlags = 0;
for(pIf = ifStack; pIf; pIf=pIf->pNext){
*pPresetFlags |= pIf->flags;
}
return nErr;
}
/*
** Parse an entire file. Return the number of errors.
**
** pList is a list of tokens in the file. Whitespace tokens have been
** eliminated, and text with {...} has been collapsed into a
** single TT_Brace token.
**
** initFlags are a set of parse flags that should always be set for this
** file. For .c files this is normally 0. For .h files it is PS_Interface.
*/
static int ParseFile(Token *pList, int initFlags){
int nErr = 0;
Token *pStart = 0;
int flags = initFlags;
|
|
|
|
|
|
|
|
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
|
zArg++;
}
if( *zArg==0 || *zArg=='\n' ){ return 0; }
nArg = pToken->nText + (int)(pToken->zText - zArg);
PushIfMacro("!defined",zArg,nArg,pToken->nLine,0);
}else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){
/*
** Invert the #if on the top of the stack
*/
if( ifStack==0 ){
fprintf(stderr,"%s:%d: '#else' without an '#if'\n",zFilename,
pToken->nLine);
return 1;
}
pIf = ifStack;
if( pIf->zCondition ){
ifStack = ifStack->pNext;
PushIfMacro("!",pIf->zCondition,strlen(pIf->zCondition),pIf->nLine,0);
SafeFree(pIf);
}else{
pIf->flags = 0;
}
}else{
/*
** This directive can be safely ignored
*/
return 0;
}
/*
** Recompute the preset flags
*/
*pPresetFlags = 0;
for(pIf = ifStack; pIf; pIf=pIf->pNext){
*pPresetFlags |= pIf->flags;
}
return nErr;
}
/*
** Parse an entire file. Return the number of errors.
**
** pList is a list of tokens in the file. Whitespace tokens have been
** eliminated, and text with {...} has been collapsed into a
** single TT_Brace token.
**
** initFlags are a set of parse flags that should always be set for this
** file. For .c files this is normally 0. For .h files it is PS_Interface.
*/
static int ParseFile(Token *pList, int initFlags){
int nErr = 0;
Token *pStart = 0;
int flags = initFlags;
|
| ︙ | | | ︙ | |
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
|
case ';':
nErr += ProcessDecl(pStart,pList,flags);
pStart = 0;
flags = presetFlags;
break;
case '=':
if( pList->pPrev->nText==8
&& strncmp(pList->pPrev->zText,"operator",8)==0 ){
break;
}
nErr += ProcessDecl(pStart,pList,flags);
pStart = 0;
while( pList && pList->zText[0]!=';' ){
pList = pList->pNext;
|
|
|
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
|
case ';':
nErr += ProcessDecl(pStart,pList,flags);
pStart = 0;
flags = presetFlags;
break;
case '=':
if( pList->pPrev->nText==8
&& strncmp(pList->pPrev->zText,"operator",8)==0 ){
break;
}
nErr += ProcessDecl(pStart,pList,flags);
pStart = 0;
while( pList && pList->zText[0]!=';' ){
pList = pList->pNext;
|
| ︙ | | | ︙ | |
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
|
pDecl->zDecl = StrDup(StringGet(&str), 0);
StringReset(&str);
pDecl->zExtra = 0;
}
/*
** Reset the DP_Forward and DP_Declared flags on all Decl structures.
** Set both flags for anything that is tagged as local and isn't
** in the file zFilename so that it won't be printing in other files.
*/
static void ResetDeclFlags(char *zFilename){
Decl *pDecl;
for(pDecl = pDeclFirst; pDecl; pDecl = pDecl->pNext){
DeclClearProperty(pDecl,DP_Forward|DP_Declared);
|
|
|
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
|
pDecl->zDecl = StrDup(StringGet(&str), 0);
StringReset(&str);
pDecl->zExtra = 0;
}
/*
** Reset the DP_Forward and DP_Declared flags on all Decl structures.
** Set both flags for anything that is tagged as local and isn't
** in the file zFilename so that it won't be printing in other files.
*/
static void ResetDeclFlags(char *zFilename){
Decl *pDecl;
for(pDecl = pDeclFirst; pDecl; pDecl = pDecl->pNext){
DeclClearProperty(pDecl,DP_Forward|DP_Declared);
|
| ︙ | | | ︙ | |
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
|
){
Decl *p; /* The object to be declared */
int flag;
int isCpp; /* True if generating C++ */
int doneTypedef = 0; /* True if a typedef has been done for this object */
/* printf("BEGIN %s of %s\n",needFullDecl?"FULL":"PROTOTYPE",pDecl->zName);*/
/*
** For any object that has a forward declaration, go ahead and do the
** forward declaration first.
*/
isCpp = (pState->flags & DP_Cplusplus) != 0;
for(p=pDecl; p; p=p->pSameName){
if( p->zFwd ){
if( !DeclHasProperty(p,DP_Forward) ){
|
|
|
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
|
){
Decl *p; /* The object to be declared */
int flag;
int isCpp; /* True if generating C++ */
int doneTypedef = 0; /* True if a typedef has been done for this object */
/* printf("BEGIN %s of %s\n",needFullDecl?"FULL":"PROTOTYPE",pDecl->zName);*/
/*
** For any object that has a forward declaration, go ahead and do the
** forward declaration first.
*/
isCpp = (pState->flags & DP_Cplusplus) != 0;
for(p=pDecl; p; p=p->pSameName){
if( p->zFwd ){
if( !DeclHasProperty(p,DP_Forward) ){
|
| ︙ | | | ︙ | |
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
|
** with the DP_Flag bit. We are only able to use DP_Flag in this
** way because we know we'll never execute this far into this
** function on a recursive call with the same pDecl. Hence, recursive
** calls to this function (through ScanText()) can never change the
** value of DP_Flag out from under us.
*/
for(p=pDecl; p; p=p->pSameName){
if( !DeclHasProperty(p,DP_Declared)
&& (p->zFwd==0 || needFullDecl)
&& p->zDecl!=0
){
DeclSetProperty(p,DP_Forward|DP_Declared|DP_Flag);
}else{
DeclClearProperty(p,DP_Flag);
}
}
|
|
|
|
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
|
** with the DP_Flag bit. We are only able to use DP_Flag in this
** way because we know we'll never execute this far into this
** function on a recursive call with the same pDecl. Hence, recursive
** calls to this function (through ScanText()) can never change the
** value of DP_Flag out from under us.
*/
for(p=pDecl; p; p=p->pSameName){
if( !DeclHasProperty(p,DP_Declared)
&& (p->zFwd==0 || needFullDecl)
&& p->zDecl!=0
){
DeclSetProperty(p,DP_Forward|DP_Declared|DP_Flag);
}else{
DeclClearProperty(p,DP_Flag);
}
}
|
| ︙ | | | ︙ | |
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
|
/*
** See if there is a declaration in the database with the name given
** by sToken.
*/
pDecl = FindDecl(sToken.zText,sToken.nText);
if( pDecl==0 ) continue;
/*
** If we get this far, we've found an identifier that has a
** declaration in the database. Now see if we the full declaration
** or just a forward declaration.
*/
GetNonspaceToken(&sIn,&sNext);
if( sNext.zText[0]=='*' ){
needFullDecl = 0;
}else{
|
|
|
|
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
|
/*
** See if there is a declaration in the database with the name given
** by sToken.
*/
pDecl = FindDecl(sToken.zText,sToken.nText);
if( pDecl==0 ) continue;
/*
** If we get this far, we've found an identifier that has a
** declaration in the database. Now see if we the full declaration
** or just a forward declaration.
*/
GetNonspaceToken(&sIn,&sNext);
if( sNext.zText[0]=='*' ){
needFullDecl = 0;
}else{
|
| ︙ | | | ︙ | |
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
|
static void CompleteForwardDeclarations(GenState *pState){
Decl *pDecl;
int progress;
do{
progress = 0;
for(pDecl=pDeclFirst; pDecl; pDecl=pDecl->pNext){
if( DeclHasProperty(pDecl,DP_Forward)
&& !DeclHasProperty(pDecl,DP_Declared)
){
DeclareObject(pDecl,pState,1);
progress = 1;
assert( DeclHasProperty(pDecl,DP_Declared) );
}
}
}while( progress );
|
|
|
|
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
|
static void CompleteForwardDeclarations(GenState *pState){
Decl *pDecl;
int progress;
do{
progress = 0;
for(pDecl=pDeclFirst; pDecl; pDecl=pDecl->pNext){
if( DeclHasProperty(pDecl,DP_Forward)
&& !DeclHasProperty(pDecl,DP_Declared)
){
DeclareObject(pDecl,pState,1);
progress = 1;
assert( DeclHasProperty(pDecl,DP_Declared) );
}
}
}while( progress );
|
| ︙ | | | ︙ | |
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
|
if( WriteFile(pFile->zHdr,zNewVersion) ){
fprintf(stderr,"%s: Can't write to file\n",pFile->zHdr);
nErr++;
}
}else if( report ){
fprintf(report,"unchanged\n");
}
SafeFree(zOldVersion);
IdentTableReset(&includeTable);
StringReset(&outStr);
return nErr;
}
/*
** Generate a global header file -- a header file that contains all
|
|
|
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
|
if( WriteFile(pFile->zHdr,zNewVersion) ){
fprintf(stderr,"%s: Can't write to file\n",pFile->zHdr);
nErr++;
}
}else if( report ){
fprintf(report,"unchanged\n");
}
SafeFree(zOldVersion);
IdentTableReset(&includeTable);
StringReset(&outStr);
return nErr;
}
/*
** Generate a global header file -- a header file that contains all
|
| ︙ | | | ︙ | |
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
|
DeclareObject(pDecl,&sState,1);
}
}
ChangeIfContext(0,&sState);
printf("%s",StringGet(&outStr));
IdentTableReset(&includeTable);
StringReset(&outStr);
return 0;
}
#ifdef DEBUG
/*
** Return the number of characters in the given string prior to the
** first newline.
*/
|
|
|
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
|
DeclareObject(pDecl,&sState,1);
}
}
ChangeIfContext(0,&sState);
printf("%s",StringGet(&outStr));
IdentTableReset(&includeTable);
StringReset(&outStr);
return 0;
}
#ifdef DEBUG
/*
** Return the number of characters in the given string prior to the
** first newline.
*/
|
| ︙ | | | ︙ | |
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
|
*/
static InFile *CreateInFile(char *zArg, int *pnErr){
int nSrc;
char *zSrc;
InFile *pFile;
int i;
/*
** Get the name of the input file to be scanned. The input file is
** everything before the first ':' or the whole file if no ':' is seen.
**
** Except, on windows, ignore any ':' that occurs as the second character
** since it might be part of the drive specifier. So really, the ":' has
** to be the 3rd or later character in the name. This precludes 1-character
** file names, which really should not be a problem.
|
|
|
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
|
*/
static InFile *CreateInFile(char *zArg, int *pnErr){
int nSrc;
char *zSrc;
InFile *pFile;
int i;
/*
** Get the name of the input file to be scanned. The input file is
** everything before the first ':' or the whole file if no ':' is seen.
**
** Except, on windows, ignore any ':' that occurs as the second character
** since it might be part of the drive specifier. So really, the ":' has
** to be the 3rd or later character in the name. This precludes 1-character
** file names, which really should not be a problem.
|
| ︙ | | | ︙ | |
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
|
SafeFree(pFile->zHdr);
pFile->zHdr = 0;
}
}
/*
** If pFile->zSrc contains no 'c' or 'C' in its extension, it
** must be a header file. In that case, we need to set the
** PS_Interface flag.
*/
pFile->flags |= PS_Interface;
for(i=nSrc-1; i>0 && zSrc[i]!='.'; i--){
if( zSrc[i]=='c' || zSrc[i]=='C' ){
pFile->flags &= ~PS_Interface;
break;
}
}
/* Done!
*/
return pFile;
}
/* MS-Windows and MS-DOS both have the following serious OS bug: the
** length of a command line is severely restricted. But this program
** occasionally requires long command lines. Hence the following
|
|
|
|
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
|
SafeFree(pFile->zHdr);
pFile->zHdr = 0;
}
}
/*
** If pFile->zSrc contains no 'c' or 'C' in its extension, it
** must be a header file. In that case, we need to set the
** PS_Interface flag.
*/
pFile->flags |= PS_Interface;
for(i=nSrc-1; i>0 && zSrc[i]!='.'; i--){
if( zSrc[i]=='c' || zSrc[i]=='C' ){
pFile->flags &= ~PS_Interface;
break;
}
}
/* Done!
*/
return pFile;
}
/* MS-Windows and MS-DOS both have the following serious OS bug: the
** length of a command line is severely restricted. But this program
** occasionally requires long command lines. Hence the following
|
| ︙ | | | ︙ | |
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
|
}
c = ' ';
while( c!=EOF ){
while( c!=EOF && isspace(c) ){
if( c=='\n' ){
startOfLine = 1;
}
c = getc(in);
if( startOfLine && c=='#' ){
while( c!=EOF && c!='\n' ){
c = getc(in);
}
}
}
n = 0;
|
|
|
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
|
}
c = ' ';
while( c!=EOF ){
while( c!=EOF && isspace(c) ){
if( c=='\n' ){
startOfLine = 1;
}
c = getc(in);
if( startOfLine && c=='#' ){
while( c!=EOF && c!='\n' ){
c = getc(in);
}
}
}
n = 0;
|
| ︙ | | | ︙ | |
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
|
nNew++;
if( nNew + argc > nAlloc ){
if( nAlloc==0 ){
nAlloc = 100 + argc;
zNew = malloc( sizeof(char*) * nAlloc );
}else{
nAlloc *= 2;
zNew = realloc( zNew, sizeof(char*) * nAlloc );
}
}
if( zNew ){
int j = nNew + index;
zNew[j] = malloc( n + 1 );
if( zNew[j] ){
strcpy( zNew[j], zBuf );
|
|
|
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
|
nNew++;
if( nNew + argc > nAlloc ){
if( nAlloc==0 ){
nAlloc = 100 + argc;
zNew = malloc( sizeof(char*) * nAlloc );
}else{
nAlloc *= 2;
zNew = realloc( zNew, sizeof(char*) * nAlloc );
}
}
if( zNew ){
int j = nNew + index;
zNew[j] = malloc( n + 1 );
if( zNew[j] ){
strcpy( zNew[j], zBuf );
|
| ︙ | | | ︙ | |
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
|
);
}
/*
** The following text contains a few simple #defines that we want
** to be available to every file.
*/
static char zInit[] =
"#define INTERFACE 0\n"
"#define EXPORT_INTERFACE 0\n"
"#define LOCAL_INTERFACE 0\n"
"#define EXPORT\n"
"#define LOCAL static\n"
"#define PUBLIC\n"
"#define PRIVATE\n"
|
|
|
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
|
);
}
/*
** The following text contains a few simple #defines that we want
** to be available to every file.
*/
static const char zInit[] =
"#define INTERFACE 0\n"
"#define EXPORT_INTERFACE 0\n"
"#define LOCAL_INTERFACE 0\n"
"#define EXPORT\n"
"#define LOCAL static\n"
"#define PUBLIC\n"
"#define PRIVATE\n"
|
| ︙ | | | ︙ | |