1255715Sdb/*- 2255715Sdb * Copyright (c) 2013 Diane Bruce 3255715Sdb * All rights reserved. 4255715Sdb * 5255715Sdb * Redistribution and use in source and binary forms, with or without 6255715Sdb * modification, are permitted provided that the following conditions 7255715Sdb * are met: 8255715Sdb * 1. Redistributions of source code must retain the above copyright 9255715Sdb * notice, this list of conditions and the following disclaimer. 10255715Sdb * 2. Redistributions in binary form must reproduce the above copyright 11255715Sdb * notice, this list of conditions and the following disclaimer in the 12255715Sdb * documentation and/or other materials provided with the distribution. 13255715Sdb * 14255715Sdb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15255715Sdb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16255715Sdb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17255715Sdb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18255715Sdb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19255715Sdb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20255715Sdb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21255715Sdb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22255715Sdb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23255715Sdb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24255715Sdb * SUCH DAMAGE. 25255715Sdb * 26255715Sdb * $FreeBSD$ 27255715Sdb */ 28255715Sdb 29255715Sdb/* calendar fake cpp does a very limited cpp version */ 30255715Sdb 31255715Sdb#include <sys/param.h> 32255715Sdb#include <sys/stat.h> 33255715Sdb#include <sys/wait.h> 34255715Sdb#include <assert.h> 35255715Sdb#include <ctype.h> 36255715Sdb#include <err.h> 37255715Sdb#include <errno.h> 38255715Sdb#include <langinfo.h> 39255715Sdb#include <locale.h> 40255715Sdb#include <pwd.h> 41255715Sdb#include <stdio.h> 42255715Sdb#include <stdlib.h> 43255715Sdb#include <string.h> 44255715Sdb#include <unistd.h> 45255715Sdb 46255715Sdb#include "pathnames.h" 47255715Sdb#include "calendar.h" 48255715Sdb 49255715Sdb#define MAXFPSTACK 50 50255715Sdbstatic FILE *fpstack[MAXFPSTACK]; 51255715Sdbstatic int curfpi; 52255715Sdbstatic void pushfp(FILE *fp); 53255715Sdbstatic FILE *popfp(void); 54255715Sdbstatic int tokenscpp(char *buf, char *string); 55255715Sdb 56255715Sdb#define T_INVALID -1 57255715Sdb#define T_INCLUDE 0 58255715Sdb#define T_DEFINE 1 59255715Sdb#define T_IFNDEF 2 60255715Sdb#define T_ENDIF 3 61255715Sdb 62255715Sdb#define MAXSYMS 100 63255715Sdbstatic char *symtable[MAXSYMS]; 64255715Sdbstatic void addsym(const char *name); 65255715Sdbstatic int findsym(const char *name); 66255715Sdb 67255715SdbFILE * 68255715Sdbfincludegets(char *buf, int size, FILE *fp) 69255715Sdb{ 70255715Sdb char name[MAXPATHLEN]; 71255715Sdb FILE *nfp=NULL; 72255715Sdb char *p; 73255715Sdb int ch; 74255715Sdb 75255715Sdb if (fp == NULL) 76255715Sdb return(NULL); 77255715Sdb 78255715Sdb if (fgets(buf, size, fp) == NULL) { 79255715Sdb *buf = '\0'; 80255715Sdb fclose(fp); 81255715Sdb fp = popfp(); 82255715Sdb return (fp); 83255715Sdb } 84255715Sdb if ((p = strchr(buf, '\n')) != NULL) 85255715Sdb *p = '\0'; 86255715Sdb else { 87255715Sdb /* Flush this line */ 88255715Sdb while ((ch = fgetc(fp)) != '\n' && ch != EOF); 89255715Sdb if (ch == EOF) { 90255715Sdb *buf = '\0'; 91255715Sdb fclose(fp); 92255715Sdb fp = popfp(); 93255715Sdb return(fp); 94255715Sdb } 95255715Sdb } 96255715Sdb switch (tokenscpp(buf, name)) { 97255715Sdb case T_INCLUDE: 98255715Sdb *buf = '\0'; 99255715Sdb if ((nfp = fopen(name, "r")) != NULL) { 100255715Sdb pushfp(fp); 101255715Sdb fp = nfp; 102255715Sdb } 103255715Sdb break; 104255715Sdb case T_DEFINE: 105255715Sdb addsym(name); 106255715Sdb break; 107255715Sdb case T_IFNDEF: 108255715Sdb if (findsym(name)) { 109255715Sdb fclose(fp); 110255715Sdb fp = popfp(); 111255715Sdb *buf = '\0'; 112255715Sdb } 113255715Sdb break; 114255715Sdb case T_ENDIF: 115255715Sdb *buf = '\0'; 116255715Sdb break; 117255715Sdb default: 118255715Sdb break; 119255715Sdb } 120255715Sdb return (fp); 121255715Sdb} 122255715Sdb 123255715Sdbstatic int 124255715Sdbtokenscpp(char *buf, char *string) 125255715Sdb{ 126255715Sdb char *p; 127255715Sdb char *s; 128255715Sdb 129255715Sdb if ((p = strstr(buf, "#define")) != NULL) { 130255715Sdb p += 8; 131255715Sdb while (isspace((unsigned char)*p)) 132255715Sdb p++; 133255715Sdb s = p; 134255715Sdb while(!isspace((unsigned char)*p)) 135255715Sdb p++; 136255715Sdb strncpy(string, s, MAXPATHLEN); 137255715Sdb return(T_DEFINE); 138255715Sdb } else if ((p = strstr(buf, "#ifndef")) != NULL) { 139255715Sdb p += 8; 140255715Sdb while (isspace((unsigned char)*p)) 141255715Sdb p++; 142255715Sdb s = p; 143255715Sdb while(!isspace((unsigned char)*p)) 144255715Sdb p++; 145255715Sdb *p = '\0'; 146255715Sdb strncpy(string, s, MAXPATHLEN); 147255715Sdb return(T_IFNDEF); 148255715Sdb } else if ((p = strstr(buf, "#endif")) != NULL) { 149255715Sdb return(T_ENDIF); 150255715Sdb } if ((p = strstr(buf, "#include")) != NULL) { 151255715Sdb p += 8; 152255715Sdb while (isspace((unsigned char)*p)) 153255715Sdb p++; 154255715Sdb if (*p == '<') { 155255715Sdb s = p+1; 156255715Sdb if ((p = strchr(s, '>')) != NULL) 157255715Sdb *p = '\0'; 158255715Sdb snprintf (string, MAXPATHLEN, "%s/%s", 159255715Sdb _PATH_INCLUDE, s); 160255715Sdb } else if (*p == '(') { 161255715Sdb s = p+1; 162255715Sdb if ((p = strchr(p, '>')) != NULL) 163255715Sdb *p = '\0'; 164255715Sdb snprintf (string, MAXPATHLEN, "%s", s); 165255715Sdb } 166255715Sdb return(T_INCLUDE); 167255715Sdb } 168255715Sdb return(T_INVALID); 169255715Sdb} 170255715Sdb 171255715Sdbstatic void 172255715Sdbpushfp(FILE *fp) 173255715Sdb{ 174255715Sdb curfpi++; 175255715Sdb if (curfpi == MAXFPSTACK) 176255715Sdb errx(1, "Max #include reached"); 177255715Sdb fpstack[curfpi] = fp; 178255715Sdb} 179255715Sdb 180255715Sdbstatic 181255715SdbFILE *popfp(void) 182255715Sdb{ 183255715Sdb FILE *tmp; 184255715Sdb 185255715Sdb assert(curfpi >= 0); 186255715Sdb tmp = fpstack[curfpi]; 187255715Sdb curfpi--; 188255715Sdb return(tmp); 189255715Sdb} 190255715Sdb 191255715Sdbvoid 192255715Sdbinitcpp(void) 193255715Sdb{ 194255715Sdb int i; 195255715Sdb 196255715Sdb for (i=0; i < MAXSYMS; i++) 197255715Sdb symtable[i] = NULL; 198255715Sdb fpstack[0] = NULL; 199255715Sdb curfpi = 0; 200255715Sdb} 201255715Sdb 202255715Sdb 203255715Sdbstatic void 204255715Sdbaddsym(const char *name) 205255715Sdb{ 206255715Sdb int i; 207255715Sdb 208255715Sdb if (!findsym(name)) 209255715Sdb for (i=0; i < MAXSYMS; i++) { 210255715Sdb if (symtable[i] == NULL) { 211255715Sdb symtable[i] = strdup(name); 212255715Sdb if (symtable[i] == NULL) 213255715Sdb errx(1, "malloc error in addsym"); 214255715Sdb return; 215255715Sdb } 216255715Sdb } 217255715Sdb errx(1, "symbol table full\n"); 218255715Sdb} 219255715Sdb 220255715Sdbstatic int 221255715Sdbfindsym(const char *name) 222255715Sdb{ 223255715Sdb int i; 224255715Sdb 225255715Sdb for (i=0; i < MAXSYMS; i++) 226255715Sdb if (symtable[i] != NULL && strcmp(symtable[i],name) == 0) 227255715Sdb return (1); 228255715Sdb return (0); 229255715Sdb} 230