1262918Simp/*- 2262918Simp * Copyright (c) 2013 Diane Bruce 3262918Simp * All rights reserved. 4262918Simp * 5262918Simp * Redistribution and use in source and binary forms, with or without 6262918Simp * modification, are permitted provided that the following conditions 7262918Simp * are met: 8262918Simp * 1. Redistributions of source code must retain the above copyright 9262918Simp * notice, this list of conditions and the following disclaimer. 10262918Simp * 2. Redistributions in binary form must reproduce the above copyright 11262918Simp * notice, this list of conditions and the following disclaimer in the 12262918Simp * documentation and/or other materials provided with the distribution. 13262918Simp * 14262918Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15262918Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16262918Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17262918Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18262918Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19262918Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20262918Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21262918Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22262918Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23262918Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24262918Simp * SUCH DAMAGE. 25262918Simp * 26262918Simp * $FreeBSD$ 27262918Simp */ 28262918Simp 29262918Simp/* calendar fake cpp does a very limited cpp version */ 30262918Simp 31262918Simp#include <sys/param.h> 32262918Simp#include <sys/stat.h> 33262918Simp#include <sys/wait.h> 34262918Simp#include <assert.h> 35262918Simp#include <ctype.h> 36262918Simp#include <err.h> 37262918Simp#include <errno.h> 38262918Simp#include <langinfo.h> 39262918Simp#include <locale.h> 40262918Simp#include <pwd.h> 41262918Simp#include <stdio.h> 42262918Simp#include <stdlib.h> 43262918Simp#include <string.h> 44262918Simp#include <unistd.h> 45 46#include "pathnames.h" 47#include "calendar.h" 48 49#define MAXFPSTACK 50 50static FILE *fpstack[MAXFPSTACK]; 51static int curfpi; 52static void pushfp(FILE *fp); 53static FILE *popfp(void); 54static int tokenscpp(char *buf, char *string); 55 56#define T_INVALID -1 57#define T_INCLUDE 0 58#define T_DEFINE 1 59#define T_IFNDEF 2 60#define T_ENDIF 3 61 62#define MAXSYMS 100 63static char *symtable[MAXSYMS]; 64static void addsym(const char *name); 65static int findsym(const char *name); 66 67FILE * 68fincludegets(char *buf, int size, FILE *fp) 69{ 70 char name[MAXPATHLEN]; 71 FILE *nfp=NULL; 72 char *p; 73 int ch; 74 75 if (fp == NULL) 76 return(NULL); 77 78 if (fgets(buf, size, fp) == NULL) { 79 *buf = '\0'; 80 fclose(fp); 81 fp = popfp(); 82 return (fp); 83 } 84 if ((p = strchr(buf, '\n')) != NULL) 85 *p = '\0'; 86 else { 87 /* Flush this line */ 88 while ((ch = fgetc(fp)) != '\n' && ch != EOF); 89 if (ch == EOF) { 90 *buf = '\0'; 91 fclose(fp); 92 fp = popfp(); 93 return(fp); 94 } 95 } 96 switch (tokenscpp(buf, name)) { 97 case T_INCLUDE: 98 *buf = '\0'; 99 if ((nfp = fopen(name, "r")) != NULL) { 100 pushfp(fp); 101 fp = nfp; 102 } 103 break; 104 case T_DEFINE: 105 addsym(name); 106 break; 107 case T_IFNDEF: 108 if (findsym(name)) { 109 fclose(fp); 110 fp = popfp(); 111 *buf = '\0'; 112 } 113 break; 114 case T_ENDIF: 115 *buf = '\0'; 116 break; 117 default: 118 break; 119 } 120 return (fp); 121} 122 123static int 124tokenscpp(char *buf, char *string) 125{ 126 char *p; 127 char *s; 128 129 if ((p = strstr(buf, "#define")) != NULL) { 130 p += 8; 131 while (isspace((unsigned char)*p)) 132 p++; 133 s = p; 134 while(!isspace((unsigned char)*p)) 135 p++; 136 strncpy(string, s, MAXPATHLEN); 137 return(T_DEFINE); 138 } else if ((p = strstr(buf, "#ifndef")) != NULL) { 139 p += 8; 140 while (isspace((unsigned char)*p)) 141 p++; 142 s = p; 143 while(!isspace((unsigned char)*p)) 144 p++; 145 *p = '\0'; 146 strncpy(string, s, MAXPATHLEN); 147 return(T_IFNDEF); 148 } else if ((p = strstr(buf, "#endif")) != NULL) { 149 return(T_ENDIF); 150 } if ((p = strstr(buf, "#include")) != NULL) { 151 p += 8; 152 while (isspace((unsigned char)*p)) 153 p++; 154 if (*p == '<') { 155 s = p+1; 156 if ((p = strchr(s, '>')) != NULL) 157 *p = '\0'; 158 snprintf (string, MAXPATHLEN, "%s/%s", 159 _PATH_INCLUDE, s); 160 } else if (*p == '(') { 161 s = p+1; 162 if ((p = strchr(p, '>')) != NULL) 163 *p = '\0'; 164 snprintf (string, MAXPATHLEN, "%s", s); 165 } 166 return(T_INCLUDE); 167 } 168 return(T_INVALID); 169} 170 171static void 172pushfp(FILE *fp) 173{ 174 curfpi++; 175 if (curfpi == MAXFPSTACK) 176 errx(1, "Max #include reached"); 177 fpstack[curfpi] = fp; 178} 179 180static 181FILE *popfp(void) 182{ 183 FILE *tmp; 184 185 assert(curfpi >= 0); 186 tmp = fpstack[curfpi]; 187 curfpi--; 188 return(tmp); 189} 190 191void 192initcpp(void) 193{ 194 int i; 195 196 for (i=0; i < MAXSYMS; i++) 197 symtable[i] = NULL; 198 fpstack[0] = NULL; 199 curfpi = 0; 200} 201 202 203static void 204addsym(const char *name) 205{ 206 int i; 207 208 if (!findsym(name)) 209 for (i=0; i < MAXSYMS; i++) { 210 if (symtable[i] == NULL) { 211 symtable[i] = strdup(name); 212 if (symtable[i] == NULL) 213 errx(1, "malloc error in addsym"); 214 return; 215 } 216 } 217 errx(1, "symbol table full\n"); 218} 219 220static int 221findsym(const char *name) 222{ 223 int i; 224 225 for (i=0; i < MAXSYMS; i++) 226 if (symtable[i] != NULL && strcmp(symtable[i],name) == 0) 227 return (1); 228 return (0); 229} 230