usecpp.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. /******************************************************************************
  2. Copyright (c) 1999 Daniel Stenberg
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  17. SOFTWARE.
  18. ******************************************************************************/
  19. /******************************************************************************
  20. * FREXXWARE
  21. * ----------------------------------------------------------------------------
  22. *
  23. * Project: Frexx C Preprocessor
  24. * $Source: /home/user/start/cpp/RCS/usecpp.c,v $
  25. * $Revision: 1.6 $
  26. * $Date: 1994/06/02 09:11:01 $
  27. * $Author: start $
  28. * $State: Exp $
  29. * $Locker: start $
  30. *
  31. * ----------------------------------------------------------------------------
  32. * $Log: usecpp.c,v $
  33. * Revision 1.6 1994/06/02 09:11:01 start
  34. * Added the '-n' option!
  35. *
  36. * Revision 1.5 1994/06/02 08:51:49 start
  37. * Added three more command line parameters
  38. * Made -h invokes exit nice
  39. *
  40. * Revision 1.4 1994/01/24 09:37:17 start
  41. * Major difference.
  42. *
  43. * Revision 1.3 1993/12/06 13:51:20 start
  44. * A lot of new stuff (too much to mention)
  45. *
  46. * Revision 1.2 1993/11/11 07:16:39 start
  47. * New stuff
  48. *
  49. * Revision 1.1 1993/11/03 09:13:08 start
  50. * Initial revision
  51. *
  52. *
  53. *****************************************************************************/
  54. /**********************************************************************
  55. *
  56. * usecpp.c
  57. *
  58. * This is a routine that is should be used to call functions in the
  59. * fpp.library. We supply the own_input() and own_output() functions to
  60. * the preprocessor to remain flexible.
  61. */
  62. #include <stdlib.h>
  63. #ifdef AMIGA
  64. #include <proto/exec.h>
  65. #include <exec/types.h>
  66. #if defined(SHARED)
  67. #include <exec/libraries.h>
  68. #include <libraries/dos.h>
  69. #include "fpp_pragmas.h"
  70. #include "fpp_protos.h"
  71. #include "FPPBase.h"
  72. struct Library *FPPBase=NULL;
  73. #define PREFIX __saveds
  74. #define REG(x) register __ ## x
  75. #else
  76. #define PREFIX
  77. #define REG(x)
  78. #endif
  79. #elif defined(UNIX)
  80. #if defined(OS9)
  81. #include <types.h>
  82. #else
  83. #include <sys/types.h>
  84. #ifdef BSD
  85. #include <sys/unistd.h> /* for BSD systems (SUN OS at least) */
  86. #endif
  87. #endif
  88. #define PREFIX
  89. #define REG(x)
  90. #endif
  91. #include <stdio.h>
  92. #include <string.h>
  93. #include <stdlib.h>
  94. #include <ctype.h>
  95. #ifndef OS9
  96. #include <stdarg.h>
  97. #else
  98. #define va_list void *
  99. #endif
  100. #include "fpp.h"
  101. #define MAX_TAGS 40 /* maximum number of tags allowed! */
  102. #define FILE_LOCAL static
  103. #define CPP_PREFS_FILE "cpp.prefs"
  104. #ifdef AMIGA
  105. #define DEFAULT_CPP_PREFS_FILE "s:cpp.prefs"
  106. #else
  107. #define DEFAULT_CPP_PREFS_FILE "$HOME/cpp.prefs"
  108. #endif
  109. FILE_LOCAL char PREFIX *own_input(char *, int, void *);
  110. FILE_LOCAL void PREFIX own_output(int, void *);
  111. FILE_LOCAL void PREFIX own_error(void *, char *, va_list);
  112. FILE_LOCAL int SetOptions(int, char **, struct fppTag **);
  113. FILE_LOCAL char GetPrefs(struct fppTag **, char **);
  114. FILE_LOCAL char DoString(struct fppTag **, char *);
  115. #ifdef AMIGA
  116. extern long __stack=8000;
  117. #endif
  118. FILE_LOCAL char ignore=FPP_FALSE; /* if we should ignore strange flags! */
  119. FILE_LOCAL char display=FPP_FALSE; /* display all options in use! */
  120. FILE_LOCAL char dontreadprefs; /* set if only the command line is valid */
  121. int main(int argc, char **argv)
  122. {
  123. struct fppTag tags[MAX_TAGS];
  124. int i;
  125. struct fppTag *tagptr = tags;
  126. char *dealloc;
  127. /*
  128. * Append system-specific directories to the include directory list.
  129. * The include directories will be searched through in the same order
  130. * as you add them in the taglist!
  131. * The directory _must_ end with a proper directory speparator!
  132. */
  133. tagptr->tag=FPPTAG_INCLUDE_DIR;
  134. #if defined (AMIGA)
  135. tagptr->data = "INCLUDE:";
  136. #elif defined (OS9)
  137. tagptr->data = "/dd/defs/";
  138. #else
  139. tagptr->data = "/usr/include/";
  140. #endif
  141. tagptr++;
  142. if(GetPrefs(&tagptr, &dealloc))
  143. return(0);
  144. if( !(i = SetOptions(argc, argv, &tagptr)))
  145. return(0);
  146. if (argc - i >2) {
  147. printf("Too many file arguments. Usage: cpp [options] [input [output]]\n");
  148. return(-1);
  149. }
  150. tagptr->tag=FPPTAG_INPUT;
  151. tagptr->data=(void *)own_input;
  152. tagptr++;
  153. if(i<argc) {
  154. /*
  155. * Open input file, "-" means use stdin.
  156. */
  157. if (strcmp(argv[i], "-")) {
  158. if (freopen(argv[i], "r", stdin) == NULL) {
  159. perror(argv[i]);
  160. fprintf(stderr, "Can't open input file \"%s\"", argv[i]);
  161. return(-2);
  162. }
  163. tagptr->tag=FPPTAG_INPUT_NAME;
  164. tagptr->data=argv[i];
  165. tagptr++;
  166. if(display)
  167. fprintf(stderr, "cpp: input: %s\n", argv[i]);
  168. } else /* Else, just get stdin */
  169. if(display)
  170. fprintf(stderr, "cpp: input: [stdin]\n");
  171. i++;
  172. } else
  173. if(display)
  174. fprintf(stderr, "cpp: input: [stdin]\n");
  175. if(i<argc) {
  176. /*
  177. * Get output file, "-" means use stdout.
  178. */
  179. if (strcmp(argv[i], "-")) {
  180. if (freopen(argv[i], "w", stdout) == NULL) {
  181. perror(argv[i]);
  182. fprintf(stderr, "Can't open output file \"%s\"", argv[i]);
  183. return(-1);
  184. }
  185. if(display)
  186. fprintf(stderr, "cpp: output: %s\n", argv[i]);
  187. } else
  188. if(display)
  189. fprintf(stderr, "cpp: output: [stdout]\n");
  190. } else
  191. if(display)
  192. fprintf(stderr, "cpp: output: [stdout]\n");
  193. tagptr->tag=FPPTAG_OUTPUT;
  194. tagptr->data=(void *)own_output;
  195. tagptr++;
  196. tagptr->tag=FPPTAG_ERROR;
  197. tagptr->data=(void *)own_error;
  198. tagptr++;
  199. /* The LAST tag: */
  200. tagptr->tag=FPPTAG_END;
  201. tagptr->data=0;
  202. tagptr++;
  203. #if defined(SHARED) && defined(AMIGA)
  204. if(!(FPPBase=OpenLibrary(FPPNAME, 1))) {
  205. printf("Error opening %s!\n", FPPNAME);
  206. return(-1);
  207. }
  208. #endif
  209. fppPreProcess(tags);
  210. #if defined(SHARED) && defined(AMIGA)
  211. CloseLibrary((struct Library *)FPPBase);
  212. #endif
  213. /*
  214. * Preprocess ready!
  215. */
  216. if( dealloc )
  217. free( dealloc );
  218. return(0);
  219. }
  220. FILE_LOCAL
  221. char PREFIX *own_input(char *buffer, int size, void *userdata)
  222. {
  223. return(fgets(buffer, size, stdin));
  224. }
  225. FILE_LOCAL
  226. void PREFIX own_output(int c, void *userdata)
  227. {
  228. putchar(c);
  229. }
  230. FILE_LOCAL
  231. void PREFIX own_error(void *userdata, char *format, va_list arg)
  232. {
  233. vfprintf(stderr, format, arg);
  234. }
  235. FILE_LOCAL
  236. char GetPrefs(struct fppTag **tagptr, char **string)
  237. {
  238. FILE *PrefsFile_PF;
  239. unsigned Length_U;
  240. char *PrefsBuffer_PC;
  241. char ret= 0;
  242. char *env;
  243. *string = NULL;
  244. /* Open prefs file for read */
  245. if ( (PrefsFile_PF = fopen(CPP_PREFS_FILE, "r")) ||
  246. (PrefsFile_PF = fopen(DEFAULT_CPP_PREFS_FILE, "r"))) {
  247. fseek(PrefsFile_PF, 0 , SEEK_END);
  248. Length_U = ftell(PrefsFile_PF);
  249. fseek(PrefsFile_PF, 0, SEEK_SET);
  250. if (*string = (char *)malloc(Length_U+1)) {
  251. fread(*string, 1, Length_U, PrefsFile_PF);
  252. (*string)[Length_U] = '\0';
  253. ret = !DoString(tagptr, *string);
  254. }
  255. fclose(PrefsFile_PF);
  256. if(ret) {
  257. free( *string );
  258. return ret;
  259. }
  260. }
  261. if((env = getenv("CPP_PREFS"))) {
  262. ret= !DoString(tagptr, env);
  263. if(ret && *string)
  264. free( *string );
  265. }
  266. return ret;
  267. }
  268. FILE_LOCAL
  269. char DoString(struct fppTag **tagptr, char *string)
  270. {
  271. char *argv[MAX_TAGS];
  272. int argc=1;
  273. do {
  274. while(*string && *string != '-')
  275. string++;
  276. if(!*string)
  277. break;
  278. argv[argc]=string;
  279. do {
  280. string++;
  281. if(*string=='\"') {
  282. do
  283. string++;
  284. while(*string != '\"');
  285. string++;
  286. }
  287. } while(*string && *string!=' ' && *string != '\n' && *string != '\t');
  288. argc++;
  289. if(*string) {
  290. *string='\0';
  291. string++;
  292. } else
  293. break;
  294. } while(1);
  295. return (SetOptions(argc, argv, tagptr));
  296. }
  297. FILE_LOCAL
  298. int SetOptions(int argc, char **argv, struct fppTag **tagptr)
  299. {
  300. int i;
  301. char *ap;
  302. for (i = 1; i < argc; i++) {
  303. ap = argv[i];
  304. if (*ap++ != '-' || *ap == '\0')
  305. break;
  306. else {
  307. char c = *ap++;
  308. if(display)
  309. fprintf(stderr, "cpp: option: %s\n", ap-2);
  310. switch (c) { /* Command character */
  311. case 'Q': /* ignore unknown flags but */
  312. ignore=1; /* output them on stderr */
  313. break;
  314. case 'q': /* ignore unknown flags */
  315. ignore=2;
  316. break;
  317. case 'H': /* display all whitespaces */
  318. (*tagptr)->tag = FPPTAG_OUTPUTSPACE;
  319. (*tagptr)->data= (void *)FPP_TRUE;
  320. (*tagptr)++;
  321. break;
  322. case 'b': /* display unbalance */
  323. (*tagptr)->tag = FPPTAG_OUTPUTBALANCE;
  324. (*tagptr)->data= (void *)FPP_TRUE;
  325. (*tagptr)++;
  326. break;
  327. case 'f': /* output all defined functions! */
  328. (*tagptr)->tag = FPPTAG_DISPLAYFUNCTIONS;
  329. (*tagptr)->data= (void *)FPP_TRUE;
  330. (*tagptr)++;
  331. break;
  332. case 'F': /* output all included files! */
  333. (*tagptr)->tag = FPPTAG_OUTPUTINCLUDES;
  334. (*tagptr)->data= (void *)FPP_TRUE;
  335. (*tagptr)++;
  336. break;
  337. case 'V': /* do not output version */
  338. (*tagptr)->tag = FPPTAG_SHOWVERSION;
  339. (*tagptr)->data= (void *)FPP_FALSE;
  340. (*tagptr)++;
  341. break;
  342. case 'C': /* Keep comments */
  343. (*tagptr)->tag = FPPTAG_KEEPCOMMENTS;
  344. (*tagptr)->data= (void *)FPP_TRUE;
  345. (*tagptr)++;
  346. break;
  347. case 'D': /* Define symbol */
  348. (*tagptr)->tag=FPPTAG_DEFINE;
  349. (*tagptr)->data=argv[i]+2;
  350. (*tagptr)++;
  351. break;
  352. case 'd': /* Display all options */
  353. fprintf(stderr, "FOUND -d flag!\n");
  354. display = FPP_TRUE;
  355. break;
  356. case 'E': /* Ignore non-fatal errors */
  357. (*tagptr)->tag=FPPTAG_IGNORE_NONFATAL;
  358. (*tagptr)->data=(void *)FPP_TRUE;
  359. (*tagptr)++;
  360. break;
  361. case 'I': /* Include directory */
  362. (*tagptr)->tag=FPPTAG_INCLUDE_DIR;
  363. (*tagptr)->data=ap;
  364. (*tagptr)++;
  365. break;
  366. case 'J': /* Allow nested comments */
  367. (*tagptr)->tag=FPPTAG_NESTED_COMMENTS;
  368. (*tagptr)->data=ap;
  369. (*tagptr)++;
  370. break;
  371. case 'j': /* Warn at nested comments */
  372. (*tagptr)->tag=FPPTAG_WARN_NESTED_COMMENTS;
  373. (*tagptr)->data=ap;
  374. (*tagptr)++;
  375. break;
  376. case 'L':
  377. if(*ap == 'L') { /* Do not output #line */
  378. (*tagptr)->tag=FPPTAG_LINE;
  379. } else {
  380. /* Do not output the 'line' keyword */
  381. (*tagptr)->tag=FPPTAG_OUTPUTLINE;
  382. }
  383. (*tagptr)->data=(void *)FPP_FALSE;
  384. (*tagptr)++;
  385. break;
  386. case 'M': /* Do not warn at missing includes */
  387. (*tagptr)->tag=FPPTAG_WARNMISSINCLUDE;
  388. (*tagptr)->data=(void *)FPP_FALSE;
  389. (*tagptr)++;
  390. break;
  391. case 'n':
  392. dontreadprefs^=1; /* toggle prefsreading, default is read prefs */
  393. /*
  394. * This flag should reset all previously added tags!
  395. */
  396. break;
  397. case 'N': /* No machine specific built-ins */
  398. (*tagptr)->tag=FPPTAG_BUILTINS;
  399. (*tagptr)->data=(void *)FPP_FALSE;
  400. (*tagptr)++;
  401. break;
  402. case 'B': /* No predefines like __LINE__, etc. */
  403. (*tagptr)->tag=FPPTAG_PREDEFINES;
  404. (*tagptr)->data=(void *)FPP_FALSE;
  405. (*tagptr)++;
  406. break;
  407. case 'P': /* No C++ comments */
  408. (*tagptr)->tag=FPPTAG_IGNORE_CPLUSPLUS;
  409. (*tagptr)->data=(void *)FPP_TRUE;
  410. (*tagptr)++;
  411. break;
  412. case 'p': /* warn about illegal # - instructions */
  413. (*tagptr)->tag = FPPTAG_WARNILLEGALCPP;
  414. (*tagptr)->data= (void *)FPP_TRUE;
  415. (*tagptr)++;
  416. break;
  417. case 'R':
  418. (*tagptr)->tag = FPPTAG_RIGHTCONCAT;
  419. (*tagptr)->data= (void *)FPP_TRUE;
  420. (*tagptr)++;
  421. break;
  422. case 's': /* sizeof table */
  423. (*tagptr)->tag=FPPTAG_INITFUNC;
  424. (*tagptr)->data=ap;
  425. (*tagptr)++;
  426. break;
  427. case 't': /* excluded functions */
  428. (*tagptr)->tag=FPPTAG_EXCLFUNC;
  429. (*tagptr)->data=ap;
  430. (*tagptr)++;
  431. break;
  432. case 'S': /* sizeof table */
  433. (*tagptr)->tag=FPPTAG_SIZEOF_TABLE;
  434. (*tagptr)->data=ap;
  435. (*tagptr)++;
  436. break;
  437. case 'U': /* Undefine symbol */
  438. (*tagptr)->tag=FPPTAG_UNDEFINE;
  439. (*tagptr)->data=ap;
  440. (*tagptr)++;
  441. break;
  442. case 'w': /* Output all #defines but not the
  443. main file */
  444. (*tagptr)->tag=FPPTAG_OUTPUTMAIN;
  445. (*tagptr)->data=(void *)FPP_FALSE;
  446. (*tagptr)++;
  447. case 'W': /* Output all #defines */
  448. if(!strncmp(ap, "WW", 2)) {
  449. (*tagptr)->tag=FPPTAG_WEBMODE;
  450. (*tagptr)->data=(void *)FPP_TRUE;
  451. (*tagptr)++;
  452. }
  453. else {
  454. (*tagptr)->tag=FPPTAG_OUTPUT_DEFINES;
  455. (*tagptr)->data=(void *)FPP_TRUE;
  456. (*tagptr)++;
  457. }
  458. break;
  459. case 'X':
  460. (*tagptr)->tag=FPPTAG_INCLUDE_FILE;
  461. (*tagptr)->data=ap;
  462. (*tagptr)++;
  463. break;
  464. /*
  465. case 'x':
  466. tags[tag]->tag=FPPTAG_INCLUDE_MACRO_FILE;
  467. tags[tag++]->data=ap;
  468. break;
  469. */
  470. case 'h':
  471. case '?': /* if a question mark is possible to specify! */
  472. default: /* What is this one? */
  473. if( ignore < 2 && c != 'h') {
  474. fprintf(stderr, "cpp: unknown option: -%s\n", ap-1);
  475. }
  476. if(!ignore || c == 'h') {
  477. fprintf(stderr,
  478. "Usage: cpp [options] [infile [outfile] ]\n\n"
  479. "The following options are valid:\n"
  480. " -B\tNo machine specific built-in symbols\n"
  481. " -b\tOutput any parentheses, brace or bracket unbalance\n"
  482. " -C\tWrite source file comments to output\n"
  483. " -D\tDefine a symbol with the given (optional) value \"symbol[=value]\"\n"
  484. " -d\tDisplay all specified options\n"
  485. " -E\tIgnore non-fatal errors\n"
  486. " -F\tOutput all included file names on stderr\n"
  487. " -f\tOutput all defined functions' names on stderr\n"
  488. " -H\tOutput all whitespaces from the source file\n"
  489. " -h\tOutput this help text\n"
  490. " -I\tAdd directory to the #include search list\n"
  491. " -J\tAllow nested comments\n"
  492. " -j\tEnable warnings for nested comments\n"
  493. " -LL\tDon't output #line instructions\n"
  494. " -L\tDon't output the 'line' keyword in \"#line\" instructions\n"
  495. " -M\tDon't warn for missing include files\n"
  496. " -N\tDon't predefine target-specific names\n"
  497. " -n\tToggle prefs usage\n"
  498. " -P\tDon't recognize C++ comment style\n"
  499. " -p\tEnable warnings on non ANSI preprocessor instructions\n"
  500. " -Q\tIgnore but visualize undefined flags\n"
  501. " -q\tIgnore all undefined flags\n"
  502. " -R\tEvaluate the right part first in symbol concatenations\n"
  503. " -s\tInclude the following string at the top of each function\n"
  504. " -S\tSpecify sizes for #if sizeof\n"
  505. " -t\tThis function should not get an initial function\n"
  506. " -U\tUndefine symbol\n"
  507. " -V\tDon't output version information\n"
  508. " -W\tOutput all #defines\n"
  509. " -WWW\tWeb mode preprocessing\n"
  510. " -w\tOnly output #defines\n"
  511. " -X\tInclude file\n");
  512. return(0);
  513. } /* if (!ignore) */
  514. } /* Switch on all options */
  515. } /* If it's a -option */
  516. } /* For all arguments */
  517. return i;
  518. } /* end of function */