1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir #if defined(_MSC_VER) && (_MSC_VER > 1310) 28*cdf0e10cSrcweir #define _USE_32BIT_TIME_T 29*cdf0e10cSrcweir #endif 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <stdio.h> 32*cdf0e10cSrcweir #ifdef UNX 33*cdf0e10cSrcweir #include <stdlib.h> 34*cdf0e10cSrcweir #endif 35*cdf0e10cSrcweir #include <ctype.h> 36*cdf0e10cSrcweir #include "cppdef.h" 37*cdf0e10cSrcweir #include "cpp.h" 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #include "time.h" /* BP */ 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #ifndef _STRING_H 42*cdf0e10cSrcweir #include <string.h> 43*cdf0e10cSrcweir #endif 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir #ifndef _NO_PROTO 46*cdf0e10cSrcweir int AddInclude( char *pIncStr ); /* BP, 11.09.91, Forward-Deklaration */ 47*cdf0e10cSrcweir #endif 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) && (HOST == SYS_VMS || HOST == SYS_UNIX) 50*cdf0e10cSrcweir #include <signal.h> 51*cdf0e10cSrcweir #endif 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir void InitCpp3() 54*cdf0e10cSrcweir { 55*cdf0e10cSrcweir } 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir int 59*cdf0e10cSrcweir openfile(char* filename) 60*cdf0e10cSrcweir /* 61*cdf0e10cSrcweir * Open a file, add it to the linked list of open files. 62*cdf0e10cSrcweir * This is called only from openfile() above. 63*cdf0e10cSrcweir */ 64*cdf0e10cSrcweir { 65*cdf0e10cSrcweir register FILE *fp; 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir if ((fp = fopen(filename, "r")) == NULL) { 68*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 69*cdf0e10cSrcweir if ( debug || !bDumpDefs ) 70*cdf0e10cSrcweir perror(filename); 71*cdf0e10cSrcweir #endif 72*cdf0e10cSrcweir return (FALSE); 73*cdf0e10cSrcweir } 74*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 75*cdf0e10cSrcweir if (debug) 76*cdf0e10cSrcweir fprintf(stderr, "Reading from \"%s\"\n", filename); 77*cdf0e10cSrcweir #endif 78*cdf0e10cSrcweir addfile(fp, filename); 79*cdf0e10cSrcweir return (TRUE); 80*cdf0e10cSrcweir } 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir void addfile(FILE* fp, char* filename) 83*cdf0e10cSrcweir /* 84*cdf0e10cSrcweir * Initialize tables for this open file. This is called from openfile() 85*cdf0e10cSrcweir * above (for #include files), and from the entry to cpp to open the main 86*cdf0e10cSrcweir * input file. It calls a common routine, getfile() to build the FILEINFO 87*cdf0e10cSrcweir * structure which is used to read characters. (getfile() is also called 88*cdf0e10cSrcweir * to setup a macro replacement.) 89*cdf0e10cSrcweir */ 90*cdf0e10cSrcweir { 91*cdf0e10cSrcweir register FILEINFO *file; 92*cdf0e10cSrcweir /* #ifndef _NO_PROTO */ 93*cdf0e10cSrcweir extern FILEINFO *getfile( int bufsize, char *filename ); /* BP */ 94*cdf0e10cSrcweir /* #endif */ 95*cdf0e10cSrcweir file = getfile(NBUFF, filename); 96*cdf0e10cSrcweir file->fp = fp; /* Better remember FILE * */ 97*cdf0e10cSrcweir file->buffer[0] = EOS; /* Initialize for first read */ 98*cdf0e10cSrcweir line = 1; /* Working on line 1 now */ 99*cdf0e10cSrcweir wrongline = TRUE; /* Force out initial #line */ 100*cdf0e10cSrcweir } 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir void setincdirs() 103*cdf0e10cSrcweir /* 104*cdf0e10cSrcweir * Append system-specific directories to the include directory list. 105*cdf0e10cSrcweir * Called only when cpp is started. 106*cdf0e10cSrcweir */ 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir #ifdef CPP_INCLUDE 110*cdf0e10cSrcweir *incend++ = CPP_INCLUDE; 111*cdf0e10cSrcweir #define IS_INCLUDE 1 112*cdf0e10cSrcweir #else 113*cdf0e10cSrcweir #define IS_INCLUDE 0 114*cdf0e10cSrcweir #endif 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir #if HOST == SYS_UNIX 117*cdf0e10cSrcweir *incend++ = "/usr/include"; 118*cdf0e10cSrcweir #define MAXINCLUDE (NINCLUDE - 1 - IS_INCLUDE) 119*cdf0e10cSrcweir #endif 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir #if HOST == SYS_VMS 122*cdf0e10cSrcweir extern char *getenv(); 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir if (getenv("C$LIBRARY") != NULL) 125*cdf0e10cSrcweir *incend++ = "C$LIBRARY:"; 126*cdf0e10cSrcweir *incend++ = "SYS$LIBRARY:"; 127*cdf0e10cSrcweir #define MAXINCLUDE (NINCLUDE - 2 - IS_INCLUDE) 128*cdf0e10cSrcweir #endif 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir #if HOST == SYS_RSX 131*cdf0e10cSrcweir extern int $$rsts; /* TRUE on RSTS/E */ 132*cdf0e10cSrcweir extern int $$pos; /* TRUE on PRO-350 P/OS */ 133*cdf0e10cSrcweir extern int $$vms; /* TRUE on VMS compat. */ 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir if ($$pos) { /* P/OS? */ 136*cdf0e10cSrcweir *incend++ = "SY:[ZZDECUSC]"; /* C #includes */ 137*cdf0e10cSrcweir *incend++ = "LB:[1,5]"; /* RSX library */ 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir else if ($$rsts) { /* RSTS/E? */ 140*cdf0e10cSrcweir *incend++ = "SY:@"; /* User-defined account */ 141*cdf0e10cSrcweir *incend++ = "C:"; /* Decus-C library */ 142*cdf0e10cSrcweir *incend++ = "LB:[1,1]"; /* RSX library */ 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir else if ($$vms) { /* VMS compatibility? */ 145*cdf0e10cSrcweir *incend++ = "C:"; 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir else { /* Plain old RSX/IAS */ 148*cdf0e10cSrcweir *incend++ = "LB:[1,1]"; 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir #define MAXINCLUDE (NINCLUDE - 3 - IS_INCLUDE) 151*cdf0e10cSrcweir #endif 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir #if HOST == SYS_RT11 154*cdf0e10cSrcweir extern int $$rsts; /* RSTS/E emulation? */ 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir if ($$rsts) 157*cdf0e10cSrcweir *incend++ = "SY:@"; /* User-defined account */ 158*cdf0e10cSrcweir *incend++ = "C:"; /* Decus-C library disk */ 159*cdf0e10cSrcweir *incend++ = "SY:"; /* System (boot) disk */ 160*cdf0e10cSrcweir #define MAXINCLUDE (NINCLUDE - 3 - IS_INCLUDE) 161*cdf0e10cSrcweir #endif 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir #if HOST == SYS_UNKNOWN 164*cdf0e10cSrcweir /* 165*cdf0e10cSrcweir * BP: 25.07.91, Kontext: GenMake 166*cdf0e10cSrcweir * Unter DOS wird nun auch die Environment-Variable INCLUDE ausgewetet. 167*cdf0e10cSrcweir * Es kommt erschwerend hinzu, dass alle Eintraege, die mit ';' getrennt 168*cdf0e10cSrcweir * sind, mit in die Liste aufenommen werden muessen. 169*cdf0e10cSrcweir * Dies wird mit der Funktion strtok() realisiert. 170*cdf0e10cSrcweir * Vorsicht bei der Benutzung von malloc !!! 171*cdf0e10cSrcweir * In savestring wird naemlich getmem() verwendet. Vermutlich kommen sich 172*cdf0e10cSrcweir * die beiden Funktion in die Quere. Als ich malloc statt savestring 173*cdf0e10cSrcweir * verwendete knallte es in strcpy() ! 174*cdf0e10cSrcweir */ 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir #if !defined( ZTC ) && !defined( WNT ) && !defined(BLC) && ! defined UNX && ! defined OS2 177*cdf0e10cSrcweir extern char *getenv( char *pStr ); /* BP */ 178*cdf0e10cSrcweir #endif 179*cdf0e10cSrcweir char *pIncGetEnv = NULL; /* Pointer auf INCLUDE */ 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir if ( ( pIncGetEnv = getenv("INCLUDE") ) != NULL ) 182*cdf0e10cSrcweir AddInclude( pIncGetEnv ); 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir #define MAXINCLUDE (NINCLUDE - 3 - IS_INCLUDE) 185*cdf0e10cSrcweir #endif 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir /* BP: 11.09.91, Kontext: Erweiterung des INCLUDE-Services 191*cdf0e10cSrcweir * Bislang konnte der cpp keine Include-Angaben in der Kommandozeile 192*cdf0e10cSrcweir * vertragen, bei denen die directries mit ';' getrennt wurden. 193*cdf0e10cSrcweir * Dies ist auch verstaendlich, da dieses cpp fuer UNIX-Systeme 194*cdf0e10cSrcweir * massgeschneidert wurde und in UNI die ';' als Zeichen zum Abschluss 195*cdf0e10cSrcweir * von Kommandos gilt. 196*cdf0e10cSrcweir */ 197*cdf0e10cSrcweir 198*cdf0e10cSrcweir int AddInclude( char* pIncStr ) 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir char *pIncEnv = NULL; /* Kopie des INCLUDE */ 201*cdf0e10cSrcweir char *pIncPos; /* wandert zum naechsten */ 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir pIncEnv = savestring( pIncStr ); 204*cdf0e10cSrcweir pIncPos = strtok( pIncEnv, ";" ); 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir while( pIncPos != NULL ) 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir if (incend >= &incdir[MAXINCLUDE]) 209*cdf0e10cSrcweir cfatal("Too many include directories", NULLST); 210*cdf0e10cSrcweir *incend++ = pIncPos; 211*cdf0e10cSrcweir pIncPos = strtok( NULL, ";" ); 212*cdf0e10cSrcweir } 213*cdf0e10cSrcweir return( 1 ); 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir int 220*cdf0e10cSrcweir dooptions(int argc, char** argv) 221*cdf0e10cSrcweir /* 222*cdf0e10cSrcweir * dooptions is called to process command line arguments (-Detc). 223*cdf0e10cSrcweir * It is called only at cpp startup. 224*cdf0e10cSrcweir */ 225*cdf0e10cSrcweir { 226*cdf0e10cSrcweir register char *ap; 227*cdf0e10cSrcweir register DEFBUF *dp; 228*cdf0e10cSrcweir register int c; 229*cdf0e10cSrcweir int i, j; 230*cdf0e10cSrcweir char *arg; 231*cdf0e10cSrcweir SIZES *sizp; /* For -S */ 232*cdf0e10cSrcweir int size; /* For -S */ 233*cdf0e10cSrcweir int isdatum; /* FALSE for -S* */ 234*cdf0e10cSrcweir int endtest; /* For -S */ 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir for (i = j = 1; i < argc; i++) { 237*cdf0e10cSrcweir arg = ap = argv[i]; 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir if (*ap++ != '-' || *ap == EOS) 240*cdf0e10cSrcweir { 241*cdf0e10cSrcweir argv[j++] = argv[i]; 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir else { 244*cdf0e10cSrcweir c = *ap++; /* Option byte */ 245*cdf0e10cSrcweir if (islower(c)) /* Normalize case */ 246*cdf0e10cSrcweir c = toupper(c); 247*cdf0e10cSrcweir switch (c) { /* Command character */ 248*cdf0e10cSrcweir case 'C': /* Keep comments */ 249*cdf0e10cSrcweir cflag = TRUE; 250*cdf0e10cSrcweir keepcomments = TRUE; 251*cdf0e10cSrcweir break; 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir case 'D': /* Define symbol */ 254*cdf0e10cSrcweir #if HOST != SYS_UNIX 255*cdf0e10cSrcweir /* zap_uc(ap); */ /* Force define to U.C. */ 256*cdf0e10cSrcweir #endif 257*cdf0e10cSrcweir /* 258*cdf0e10cSrcweir * If the option is just "-Dfoo", make it -Dfoo=1 259*cdf0e10cSrcweir */ 260*cdf0e10cSrcweir while (*ap != EOS && *ap != '=') 261*cdf0e10cSrcweir ap++; 262*cdf0e10cSrcweir if (*ap == EOS) 263*cdf0e10cSrcweir ap = "1"; 264*cdf0e10cSrcweir else 265*cdf0e10cSrcweir *ap++ = EOS; 266*cdf0e10cSrcweir /* 267*cdf0e10cSrcweir * Now, save the word and its definition. 268*cdf0e10cSrcweir */ 269*cdf0e10cSrcweir dp = defendel(argv[i] + 2, FALSE); 270*cdf0e10cSrcweir dp->repl = savestring(ap); 271*cdf0e10cSrcweir dp->nargs = DEF_NOARGS; 272*cdf0e10cSrcweir break; 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir case 'E': /* Ignore non-fatal */ 275*cdf0e10cSrcweir eflag = TRUE; /* errors. */ 276*cdf0e10cSrcweir break; 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir case 'I': /* Include directory */ 279*cdf0e10cSrcweir AddInclude( ap ); /* BP, 11.09.91 */ 280*cdf0e10cSrcweir break; 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir case 'N': /* No predefineds */ 283*cdf0e10cSrcweir nflag++; /* Repeat to undefine */ 284*cdf0e10cSrcweir break; /* __LINE__, etc. */ 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir case 'S': 287*cdf0e10cSrcweir sizp = size_table; 288*cdf0e10cSrcweir if (0 != (isdatum = (*ap != '*'))) /* If it's just -S, */ 289*cdf0e10cSrcweir endtest = T_FPTR; /* Stop here */ 290*cdf0e10cSrcweir else { /* But if it's -S* */ 291*cdf0e10cSrcweir ap++; /* Step over '*' */ 292*cdf0e10cSrcweir endtest = 0; /* Stop at end marker */ 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir while (sizp->bits != endtest && *ap != EOS) { 295*cdf0e10cSrcweir if (!isdigit(*ap)) { /* Skip to next digit */ 296*cdf0e10cSrcweir ap++; 297*cdf0e10cSrcweir continue; 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir size = 0; /* Compile the value */ 300*cdf0e10cSrcweir while (isdigit(*ap)) { 301*cdf0e10cSrcweir size *= 10; 302*cdf0e10cSrcweir size += (*ap++ - '0'); 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir if (isdatum) 305*cdf0e10cSrcweir sizp->size = size; /* Datum size */ 306*cdf0e10cSrcweir else 307*cdf0e10cSrcweir sizp->psize = size; /* Pointer size */ 308*cdf0e10cSrcweir sizp++; 309*cdf0e10cSrcweir } 310*cdf0e10cSrcweir if (sizp->bits != endtest) 311*cdf0e10cSrcweir cwarn("-S, too few values specified in %s", argv[i]); 312*cdf0e10cSrcweir else if (*ap != EOS) 313*cdf0e10cSrcweir cwarn("-S, too many values, \"%s\" unused", ap); 314*cdf0e10cSrcweir break; 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir case 'U': /* Undefine symbol */ 317*cdf0e10cSrcweir #if HOST != SYS_UNIX 318*cdf0e10cSrcweir /* zap_uc(ap);*/ 319*cdf0e10cSrcweir #endif 320*cdf0e10cSrcweir if (defendel(ap, TRUE) == NULL) 321*cdf0e10cSrcweir cwarn("\"%s\" wasn't defined", ap); 322*cdf0e10cSrcweir break; 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 325*cdf0e10cSrcweir case 'X': /* Debug */ 326*cdf0e10cSrcweir debug = (isdigit(*ap)) ? atoi(ap) : 1; 327*cdf0e10cSrcweir #if (HOST == SYS_VMS || HOST == SYS_UNIX) 328*cdf0e10cSrcweir signal(SIGINT, (void (*)(int)) abort); /* Trap "interrupt" */ 329*cdf0e10cSrcweir #endif 330*cdf0e10cSrcweir fprintf(stderr, "Debug set to %d\n", debug); 331*cdf0e10cSrcweir break; 332*cdf0e10cSrcweir #endif 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 335*cdf0e10cSrcweir case 'P': /* #define's dump */ 336*cdf0e10cSrcweir bDumpDefs = 1; 337*cdf0e10cSrcweir fprintf(stderr, "Dump #define's is on\n"); 338*cdf0e10cSrcweir break; 339*cdf0e10cSrcweir #endif 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir default: /* What is this one? */ 342*cdf0e10cSrcweir cwarn("Unknown option \"%s\"", arg); 343*cdf0e10cSrcweir fprintf(stderr, "The following options are valid:\n\ 344*cdf0e10cSrcweir -C\t\t\tWrite source file comments to output\n\ 345*cdf0e10cSrcweir -Dsymbol=value\tDefine a symbol with the given (optional) value\n\ 346*cdf0e10cSrcweir -Idirectory\t\tAdd a directory to the #include search list\n\ 347*cdf0e10cSrcweir -N\t\t\tDon't predefine target-specific names\n\ 348*cdf0e10cSrcweir -Stext\t\tSpecify sizes for #if sizeof\n\ 349*cdf0e10cSrcweir -Usymbol\t\tUndefine symbol\n"); 350*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 351*cdf0e10cSrcweir fprintf(stderr, " -Xvalue\t\tSet internal debug flag\n"); 352*cdf0e10cSrcweir fprintf(stderr, " -P\t\t\tdump #define's\n"); 353*cdf0e10cSrcweir #endif 354*cdf0e10cSrcweir break; 355*cdf0e10cSrcweir } /* Switch on all options */ 356*cdf0e10cSrcweir } /* If it's a -option */ 357*cdf0e10cSrcweir } /* For all arguments */ 358*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 359*cdf0e10cSrcweir if ( (bDumpDefs ? j > 4 : j > 3) ) { 360*cdf0e10cSrcweir #else 361*cdf0e10cSrcweir if (j > 3) { 362*cdf0e10cSrcweir #endif 363*cdf0e10cSrcweir cerror( 364*cdf0e10cSrcweir "Too many file arguments. Usage: cpp [input [output]]", 365*cdf0e10cSrcweir NULLST); 366*cdf0e10cSrcweir } 367*cdf0e10cSrcweir return (j); /* Return new argc */ 368*cdf0e10cSrcweir } 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir int 371*cdf0e10cSrcweir readoptions(char* filename, char*** pfargv) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir FILE *fp; 374*cdf0e10cSrcweir int c; 375*cdf0e10cSrcweir int bInQuotes = 0; 376*cdf0e10cSrcweir char optbuff[1024], *poptbuff; 377*cdf0e10cSrcweir int fargc=0, back; 378*cdf0e10cSrcweir char *fargv[PARALIMIT], **pfa; 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir pfa=*pfargv=malloc(sizeof(fargv)); 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir poptbuff=&optbuff[0]; 383*cdf0e10cSrcweir filename++; 384*cdf0e10cSrcweir if ((fp = fopen(filename, "r")) == NULL) { 385*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 386*cdf0e10cSrcweir if ( debug || !bDumpDefs ) 387*cdf0e10cSrcweir perror(filename); 388*cdf0e10cSrcweir #endif 389*cdf0e10cSrcweir return (FALSE); 390*cdf0e10cSrcweir } 391*cdf0e10cSrcweir do 392*cdf0e10cSrcweir { 393*cdf0e10cSrcweir /* 394*cdf0e10cSrcweir * #i27914# double ticks '"' now have a duplicate function: 395*cdf0e10cSrcweir * 1. they define a string ( e.g. -DFOO="baz" ) 396*cdf0e10cSrcweir * 2. a string can contain spaces, so -DFOO="baz zum" defines one 397*cdf0e10cSrcweir * argument no two ! 398*cdf0e10cSrcweir */ 399*cdf0e10cSrcweir c=fgetc(fp); 400*cdf0e10cSrcweir if ( c != ' ' && c != CR && c != NL && c != HT && c != EOF) 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir *poptbuff++=(char)c; 403*cdf0e10cSrcweir if( c == '"' ) 404*cdf0e10cSrcweir bInQuotes = ~bInQuotes; 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir else 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir if( c != EOF && bInQuotes ) 409*cdf0e10cSrcweir *poptbuff++=(char)c; 410*cdf0e10cSrcweir else 411*cdf0e10cSrcweir { 412*cdf0e10cSrcweir *poptbuff=EOS; 413*cdf0e10cSrcweir if (strlen(optbuff)>0) 414*cdf0e10cSrcweir { 415*cdf0e10cSrcweir pfa[fargc+1]=malloc(strlen(optbuff)+1); 416*cdf0e10cSrcweir strcpy(pfa[fargc+1],optbuff); 417*cdf0e10cSrcweir fargc++; 418*cdf0e10cSrcweir pfa[fargc+1]=0; 419*cdf0e10cSrcweir poptbuff=&optbuff[0]; 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir } 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir } 424*cdf0e10cSrcweir while ( c != EOF ); 425*cdf0e10cSrcweir 426*cdf0e10cSrcweir fclose(fp); 427*cdf0e10cSrcweir back=dooptions(fargc+1,pfa); 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir return (back); 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir #if HOST != SYS_UNIX 435*cdf0e10cSrcweir FILE_LOCAL void 436*cdf0e10cSrcweir zap_uc(char* ap) 437*cdf0e10cSrcweir /* 438*cdf0e10cSrcweir * Dec operating systems mangle upper-lower case in command lines. 439*cdf0e10cSrcweir * This routine forces the -D and -U arguments to uppercase. 440*cdf0e10cSrcweir * It is called only on cpp startup by dooptions(). 441*cdf0e10cSrcweir */ 442*cdf0e10cSrcweir { 443*cdf0e10cSrcweir while (*ap != EOS) { 444*cdf0e10cSrcweir /* 445*cdf0e10cSrcweir * Don't use islower() here so it works with Multinational 446*cdf0e10cSrcweir */ 447*cdf0e10cSrcweir if (*ap >= 'a' && *ap <= 'z') 448*cdf0e10cSrcweir *ap = (char)toupper(*ap); 449*cdf0e10cSrcweir ap++; 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir #endif 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir void initdefines() 455*cdf0e10cSrcweir /* 456*cdf0e10cSrcweir * Initialize the built-in #define's. There are two flavors: 457*cdf0e10cSrcweir * #define decus 1 (static definitions) 458*cdf0e10cSrcweir * #define __FILE__ ?? (dynamic, evaluated by magic) 459*cdf0e10cSrcweir * Called only on cpp startup. 460*cdf0e10cSrcweir * 461*cdf0e10cSrcweir * Note: the built-in static definitions are supressed by the -N option. 462*cdf0e10cSrcweir * __LINE__, __FILE__, and __DATE__ are always present. 463*cdf0e10cSrcweir */ 464*cdf0e10cSrcweir { 465*cdf0e10cSrcweir register char **pp; 466*cdf0e10cSrcweir register char *tp; 467*cdf0e10cSrcweir register DEFBUF *dp; 468*cdf0e10cSrcweir int i; 469*cdf0e10cSrcweir long tvec; 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir #if !defined( ZTC ) && !defined( WNT ) && !defined(BLC) && !defined(G3) 472*cdf0e10cSrcweir extern char *ctime(); 473*cdf0e10cSrcweir #endif 474*cdf0e10cSrcweir 475*cdf0e10cSrcweir /* 476*cdf0e10cSrcweir * Predefine the built-in symbols. Allow the 477*cdf0e10cSrcweir * implementor to pre-define a symbol as "" to 478*cdf0e10cSrcweir * eliminate it. 479*cdf0e10cSrcweir */ 480*cdf0e10cSrcweir if (nflag == 0) { 481*cdf0e10cSrcweir for (pp = preset; *pp != NULL; pp++) { 482*cdf0e10cSrcweir if (*pp[0] != EOS) { 483*cdf0e10cSrcweir dp = defendel(*pp, FALSE); 484*cdf0e10cSrcweir dp->repl = savestring("1"); 485*cdf0e10cSrcweir dp->nargs = DEF_NOARGS; 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir } 489*cdf0e10cSrcweir /* 490*cdf0e10cSrcweir * The magic pre-defines (__FILE__ and __LINE__ are 491*cdf0e10cSrcweir * initialized with negative argument counts. expand() 492*cdf0e10cSrcweir * notices this and calls the appropriate routine. 493*cdf0e10cSrcweir * DEF_NOARGS is one greater than the first "magic" definition. 494*cdf0e10cSrcweir */ 495*cdf0e10cSrcweir if (nflag < 2) { 496*cdf0e10cSrcweir for (pp = magic, i = DEF_NOARGS; *pp != NULL; pp++) { 497*cdf0e10cSrcweir dp = defendel(*pp, FALSE); 498*cdf0e10cSrcweir dp->nargs = --i; 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir #if OK_DATE 501*cdf0e10cSrcweir /* 502*cdf0e10cSrcweir * Define __DATE__ as today's date. 503*cdf0e10cSrcweir */ 504*cdf0e10cSrcweir dp = defendel("__DATE__", FALSE); 505*cdf0e10cSrcweir dp->repl = tp = getmem(27); 506*cdf0e10cSrcweir dp->nargs = DEF_NOARGS; 507*cdf0e10cSrcweir time( (time_t*)&tvec); 508*cdf0e10cSrcweir *tp++ = '"'; 509*cdf0e10cSrcweir strcpy(tp, ctime((const time_t*)&tvec)); 510*cdf0e10cSrcweir tp[24] = '"'; /* Overwrite newline */ 511*cdf0e10cSrcweir #endif 512*cdf0e10cSrcweir } 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir 515*cdf0e10cSrcweir #if HOST == SYS_VMS 516*cdf0e10cSrcweir /* 517*cdf0e10cSrcweir * getredirection() is intended to aid in porting C programs 518*cdf0e10cSrcweir * to VMS (Vax-11 C) which does not support '>' and '<' 519*cdf0e10cSrcweir * I/O redirection. With suitable modification, it may 520*cdf0e10cSrcweir * useful for other portability problems as well. 521*cdf0e10cSrcweir */ 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir int 524*cdf0e10cSrcweir getredirection(argc, argv) 525*cdf0e10cSrcweir int argc; 526*cdf0e10cSrcweir char **argv; 527*cdf0e10cSrcweir /* 528*cdf0e10cSrcweir * Process vms redirection arg's. Exit if any error is seen. 529*cdf0e10cSrcweir * If getredirection() processes an argument, it is erased 530*cdf0e10cSrcweir * from the vector. getredirection() returns a new argc value. 531*cdf0e10cSrcweir * 532*cdf0e10cSrcweir * Warning: do not try to simplify the code for vms. The code 533*cdf0e10cSrcweir * presupposes that getredirection() is called before any data is 534*cdf0e10cSrcweir * read from stdin or written to stdout. 535*cdf0e10cSrcweir * 536*cdf0e10cSrcweir * Normal usage is as follows: 537*cdf0e10cSrcweir * 538*cdf0e10cSrcweir * main(argc, argv) 539*cdf0e10cSrcweir * int argc; 540*cdf0e10cSrcweir * char *argv[]; 541*cdf0e10cSrcweir * { 542*cdf0e10cSrcweir * argc = getredirection(argc, argv); 543*cdf0e10cSrcweir * } 544*cdf0e10cSrcweir */ 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir register char *ap; /* Argument pointer */ 547*cdf0e10cSrcweir int i; /* argv[] index */ 548*cdf0e10cSrcweir int j; /* Output index */ 549*cdf0e10cSrcweir int file; /* File_descriptor */ 550*cdf0e10cSrcweir extern int errno; /* Last vms i/o error */ 551*cdf0e10cSrcweir 552*cdf0e10cSrcweir for (j = i = 1; i < argc; i++) { /* Do all arguments */ 553*cdf0e10cSrcweir switch (*(ap = argv[i])) { 554*cdf0e10cSrcweir case '<': /* <file */ 555*cdf0e10cSrcweir if (freopen(++ap, "r", stdin) == NULL) { 556*cdf0e10cSrcweir perror(ap); /* Can't find file */ 557*cdf0e10cSrcweir exit(errno); /* Is a fatal error */ 558*cdf0e10cSrcweir } 559*cdf0e10cSrcweir break; 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir case '>': /* >file or >>file */ 562*cdf0e10cSrcweir if (*++ap == '>') { /* >>file */ 563*cdf0e10cSrcweir /* 564*cdf0e10cSrcweir * If the file exists, and is writable by us, 565*cdf0e10cSrcweir * call freopen to append to the file (using the 566*cdf0e10cSrcweir * file's current attributes). Otherwise, create 567*cdf0e10cSrcweir * a new file with "vanilla" attributes as if the 568*cdf0e10cSrcweir * argument was given as ">filename". 569*cdf0e10cSrcweir * access(name, 2) returns zero if we can write on 570*cdf0e10cSrcweir * the specified file. 571*cdf0e10cSrcweir */ 572*cdf0e10cSrcweir if (access(++ap, 2) == 0) { 573*cdf0e10cSrcweir if (freopen(ap, "a", stdout) != NULL) 574*cdf0e10cSrcweir break; /* Exit case statement */ 575*cdf0e10cSrcweir perror(ap); /* Error, can't append */ 576*cdf0e10cSrcweir exit(errno); /* After access test */ 577*cdf0e10cSrcweir } /* If file accessable */ 578*cdf0e10cSrcweir } 579*cdf0e10cSrcweir /* 580*cdf0e10cSrcweir * On vms, we want to create the file using "standard" 581*cdf0e10cSrcweir * record attributes. creat(...) creates the file 582*cdf0e10cSrcweir * using the caller's default protection mask and 583*cdf0e10cSrcweir * "variable length, implied carriage return" 584*cdf0e10cSrcweir * attributes. dup2() associates the file with stdout. 585*cdf0e10cSrcweir */ 586*cdf0e10cSrcweir if ((file = creat(ap, 0, "rat=cr", "rfm=var")) == -1 587*cdf0e10cSrcweir || dup2(file, fileno(stdout)) == -1) { 588*cdf0e10cSrcweir perror(ap); /* Can't create file */ 589*cdf0e10cSrcweir exit(errno); /* is a fatal error */ 590*cdf0e10cSrcweir } /* If '>' creation */ 591*cdf0e10cSrcweir break; /* Exit case test */ 592*cdf0e10cSrcweir 593*cdf0e10cSrcweir default: 594*cdf0e10cSrcweir argv[j++] = ap; /* Not a redirector */ 595*cdf0e10cSrcweir break; /* Exit case test */ 596*cdf0e10cSrcweir } 597*cdf0e10cSrcweir } /* For all arguments */ 598*cdf0e10cSrcweir argv[j] = NULL; /* Terminate argv[] */ 599*cdf0e10cSrcweir return (j); /* Return new argc */ 600*cdf0e10cSrcweir } 601*cdf0e10cSrcweir #endif 602