1*7ce20373SAndrew Rist /************************************************************** 2*7ce20373SAndrew Rist * 3*7ce20373SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*7ce20373SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*7ce20373SAndrew Rist * distributed with this work for additional information 6*7ce20373SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*7ce20373SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*7ce20373SAndrew Rist * "License"); you may not use this file except in compliance 9*7ce20373SAndrew Rist * with the License. You may obtain a copy of the License at 10*7ce20373SAndrew Rist * 11*7ce20373SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*7ce20373SAndrew Rist * 13*7ce20373SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*7ce20373SAndrew Rist * software distributed under the License is distributed on an 15*7ce20373SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*7ce20373SAndrew Rist * KIND, either express or implied. See the License for the 17*7ce20373SAndrew Rist * specific language governing permissions and limitations 18*7ce20373SAndrew Rist * under the License. 19*7ce20373SAndrew Rist * 20*7ce20373SAndrew Rist *************************************************************/ 21*7ce20373SAndrew Rist 22cdf0e10cSrcweir #if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__)) 23cdf0e10cSrcweir # include <io.h> 24cdf0e10cSrcweir #else 25cdf0e10cSrcweir # include <unistd.h> 26cdf0e10cSrcweir #endif 27cdf0e10cSrcweir 28cdf0e10cSrcweir #ifdef _MSC_VER 29cdf0e10cSrcweir # define _POSIX_ 30cdf0e10cSrcweir #endif 31cdf0e10cSrcweir #include <stdio.h> 32cdf0e10cSrcweir #include <stdlib.h> 33cdf0e10cSrcweir #include <string.h> 34cdf0e10cSrcweir #include <fcntl.h> 35cdf0e10cSrcweir 36cdf0e10cSrcweir 37cdf0e10cSrcweir #ifdef __hpux 38cdf0e10cSrcweir # define _HPUX_SOURCE 39cdf0e10cSrcweir #endif 40cdf0e10cSrcweir #if defined(__IBMC__) || defined(__EMX__) 41cdf0e10cSrcweir # include <fcntl.h> 42cdf0e10cSrcweir # define PATH_MAX _MAX_PATH 43cdf0e10cSrcweir #endif 44cdf0e10cSrcweir #include <limits.h> 45cdf0e10cSrcweir 46cdf0e10cSrcweir #include "cpp.h" 47cdf0e10cSrcweir 48cdf0e10cSrcweir Includelist includelist[NINCLUDE]; 49cdf0e10cSrcweir Wraplist wraplist[NINCLUDE]; 50cdf0e10cSrcweir 51cdf0e10cSrcweir void doinclude(Tokenrow * trp,int depth,int import)52cdf0e10cSrcweir doinclude(Tokenrow * trp, int depth, int import) 53cdf0e10cSrcweir { 54cdf0e10cSrcweir char fname[PATH_MAX], iname[PATH_MAX]; 55cdf0e10cSrcweir Includelist *ip; 56cdf0e10cSrcweir int angled, fd, i; 57cdf0e10cSrcweir size_t len; 58cdf0e10cSrcweir 59cdf0e10cSrcweir trp->tp += 1; 60cdf0e10cSrcweir if (trp->tp >= trp->lp) 61cdf0e10cSrcweir goto syntax; 62cdf0e10cSrcweir if (trp->tp->type != STRING && trp->tp->type != LT) 63cdf0e10cSrcweir { 64cdf0e10cSrcweir len = trp->tp - trp->bp; 65cdf0e10cSrcweir expandrow(trp, "<include>"); 66cdf0e10cSrcweir trp->tp = trp->bp + len; 67cdf0e10cSrcweir } 68cdf0e10cSrcweir if (trp->tp->type == STRING) 69cdf0e10cSrcweir { 70cdf0e10cSrcweir len = trp->tp->len - 2; 71cdf0e10cSrcweir if (len > sizeof(fname) - 1) 72cdf0e10cSrcweir len = sizeof(fname) - 1; 73cdf0e10cSrcweir strncpy(fname, (char *) trp->tp->t + 1, len); 74cdf0e10cSrcweir angled = 0; 75cdf0e10cSrcweir } 76cdf0e10cSrcweir else 77cdf0e10cSrcweir { 78cdf0e10cSrcweir if (trp->tp->type == LT) 79cdf0e10cSrcweir { 80cdf0e10cSrcweir len = 0; 81cdf0e10cSrcweir trp->tp++; 82cdf0e10cSrcweir while (trp->tp->type != GT) 83cdf0e10cSrcweir { 84cdf0e10cSrcweir if (trp->tp > trp->lp || len + trp->tp->len + 2 >= sizeof(fname)) 85cdf0e10cSrcweir goto syntax; 86cdf0e10cSrcweir strncpy(fname + len, (char *) trp->tp->t, trp->tp->len); 87cdf0e10cSrcweir len += trp->tp->len; 88cdf0e10cSrcweir trp->tp++; 89cdf0e10cSrcweir } 90cdf0e10cSrcweir angled = 1; 91cdf0e10cSrcweir } 92cdf0e10cSrcweir else 93cdf0e10cSrcweir goto syntax; 94cdf0e10cSrcweir } 95cdf0e10cSrcweir trp->tp += 2; 96cdf0e10cSrcweir if (trp->tp < trp->lp || len == 0) 97cdf0e10cSrcweir goto syntax; 98cdf0e10cSrcweir fname[len] = '\0'; 99cdf0e10cSrcweir if (fname[0] == '/') 100cdf0e10cSrcweir { 101cdf0e10cSrcweir fd = open(fname, O_RDONLY); 102cdf0e10cSrcweir strcpy(iname, fname); 103cdf0e10cSrcweir } 104cdf0e10cSrcweir else 105cdf0e10cSrcweir { 106cdf0e10cSrcweir for (fd = -1, i = (depth < 0) ? (NINCLUDE - 1) : (depth - 1); i >= 0; i--) 107cdf0e10cSrcweir { 108cdf0e10cSrcweir ip = &includelist[i]; 109cdf0e10cSrcweir if (ip->file == NULL || ip->deleted || (angled && ip->always == 0)) 110cdf0e10cSrcweir continue; 111cdf0e10cSrcweir if (strlen(fname) + strlen(ip->file) + 2 > sizeof(iname)) 112cdf0e10cSrcweir continue; 113cdf0e10cSrcweir strcpy(iname, ip->file); 114cdf0e10cSrcweir strcat(iname, "/"); 115cdf0e10cSrcweir strcat(iname, fname); 116cdf0e10cSrcweir if ((fd = open(iname, O_RDONLY)) >= 0) 117cdf0e10cSrcweir break; 118cdf0e10cSrcweir } 119cdf0e10cSrcweir } 120cdf0e10cSrcweir 121cdf0e10cSrcweir if (fd >= 0) 122cdf0e10cSrcweir { 123cdf0e10cSrcweir if (++incdepth > NINC ) 124cdf0e10cSrcweir error(FATAL, "#%s too deeply nested", import ? "import" : "include"); 125cdf0e10cSrcweir if (Xflag) 126cdf0e10cSrcweir genimport(fname, angled, iname, import); 127cdf0e10cSrcweir if (Iflag) 128cdf0e10cSrcweir error(INFO, "Open %s file [%s]", import ? "import" : "include", iname ); 129cdf0e10cSrcweir 130cdf0e10cSrcweir for (i = NINCLUDE - 1; i >= 0; i--) 131cdf0e10cSrcweir { 132cdf0e10cSrcweir if ((wraplist[i].file != NULL) && 133cdf0e10cSrcweir (strncmp(wraplist[i].file, iname, strlen(wraplist[i].file)) == 0)) 134cdf0e10cSrcweir break; 135cdf0e10cSrcweir } 136cdf0e10cSrcweir 137cdf0e10cSrcweir setsource((char *) newstring((uchar *) iname, strlen(iname), 0), i, fd, NULL, (i >= 0) ? 1 : 0); 138cdf0e10cSrcweir 139cdf0e10cSrcweir if (!Pflag) 140cdf0e10cSrcweir genline(); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir else 143cdf0e10cSrcweir { 144cdf0e10cSrcweir trp->tp = trp->bp + 2; 145cdf0e10cSrcweir error(ERROR, "Could not find %s file %r", import ? "import" : "include", trp); 146cdf0e10cSrcweir } 147cdf0e10cSrcweir return; 148cdf0e10cSrcweir syntax: 149cdf0e10cSrcweir error(ERROR, "Syntax error in #%s", import ? "import" : "include"); 150cdf0e10cSrcweir return; 151cdf0e10cSrcweir } 152cdf0e10cSrcweir 153cdf0e10cSrcweir /* 154cdf0e10cSrcweir * Generate a line directive for cursource 155cdf0e10cSrcweir */ 156cdf0e10cSrcweir void genline(void)157cdf0e10cSrcweir genline(void) 158cdf0e10cSrcweir { 159cdf0e10cSrcweir static Token ta = {UNCLASS, 0, 0, 0, NULL, 0}; 160cdf0e10cSrcweir static Tokenrow tr = {&ta, &ta, &ta + 1, 1}; 161cdf0e10cSrcweir uchar *p; 162cdf0e10cSrcweir 163cdf0e10cSrcweir ta.t = p = (uchar *) outptr; 164cdf0e10cSrcweir strcpy((char *) p, "#line "); 165cdf0e10cSrcweir p += sizeof("#line ") - 1; 166cdf0e10cSrcweir p = (uchar *) outnum((char *) p, cursource->line); 167cdf0e10cSrcweir *p++ = ' '; 168cdf0e10cSrcweir *p++ = '"'; 169cdf0e10cSrcweir if (cursource->filename[0] != '/' && wd[0]) 170cdf0e10cSrcweir { 171cdf0e10cSrcweir strcpy((char *) p, wd); 172cdf0e10cSrcweir p += strlen(wd); 173cdf0e10cSrcweir *p++ = '/'; 174cdf0e10cSrcweir } 175cdf0e10cSrcweir strcpy((char *) p, cursource->filename); 176cdf0e10cSrcweir p += strlen((char *) p); 177cdf0e10cSrcweir *p++ = '"'; 178cdf0e10cSrcweir *p++ = '\n'; 179cdf0e10cSrcweir ta.len = (char *) p - outptr; 180cdf0e10cSrcweir outptr = (char *) p; 181cdf0e10cSrcweir tr.tp = tr.bp; 182cdf0e10cSrcweir puttokens(&tr); 183cdf0e10cSrcweir } 184cdf0e10cSrcweir 185cdf0e10cSrcweir /* 186cdf0e10cSrcweir * Generate a pragma import/include directive 187cdf0e10cSrcweir */ 188cdf0e10cSrcweir void genimport(char * fname,int angled,char * iname,int import)189cdf0e10cSrcweir genimport(char *fname, int angled, char *iname, int import) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir static Token ta = {UNCLASS, 0, 0, 0, NULL, 0}; 192cdf0e10cSrcweir static Tokenrow tr = {&ta, &ta, &ta + 1, 1}; 193cdf0e10cSrcweir uchar *p; 194cdf0e10cSrcweir 195cdf0e10cSrcweir ta.t = p = (uchar *) outptr; 196cdf0e10cSrcweir 197cdf0e10cSrcweir if (import) 198cdf0e10cSrcweir strcpy((char *) p, "#pragma import"); 199cdf0e10cSrcweir else 200cdf0e10cSrcweir strcpy((char *) p, "#pragma include"); 201cdf0e10cSrcweir 202cdf0e10cSrcweir p += strlen((char *) p); 203cdf0e10cSrcweir 204cdf0e10cSrcweir *p++ = '('; 205cdf0e10cSrcweir 206cdf0e10cSrcweir *p++ = angled ? '<' : '"'; 207cdf0e10cSrcweir strcpy((char *) p, fname); 208cdf0e10cSrcweir p += strlen(fname); 209cdf0e10cSrcweir *p++ = angled ? '>' : '"'; 210cdf0e10cSrcweir 211cdf0e10cSrcweir *p++ = ','; 212cdf0e10cSrcweir 213cdf0e10cSrcweir *p++ = '"'; 214cdf0e10cSrcweir strcpy((char *) p, iname); 215cdf0e10cSrcweir p += strlen(iname); 216cdf0e10cSrcweir *p++ = '"'; 217cdf0e10cSrcweir 218cdf0e10cSrcweir *p++ = ')'; 219cdf0e10cSrcweir *p++ = '\n'; 220cdf0e10cSrcweir 221cdf0e10cSrcweir ta.len = (char *) p - outptr; 222cdf0e10cSrcweir outptr = (char *) p; 223cdf0e10cSrcweir tr.tp = tr.bp; 224cdf0e10cSrcweir puttokens(&tr); 225cdf0e10cSrcweir } 226cdf0e10cSrcweir 227cdf0e10cSrcweir /* 228cdf0e10cSrcweir * Generate a extern C directive 229cdf0e10cSrcweir */ 230cdf0e10cSrcweir void genwrap(int end)231cdf0e10cSrcweir genwrap(int end) 232cdf0e10cSrcweir { 233cdf0e10cSrcweir static Token ta = {UNCLASS, 0, 0, 0, NULL, 0}; 234cdf0e10cSrcweir static Tokenrow tr = {&ta, &ta, &ta + 1, 1}; 235cdf0e10cSrcweir uchar *p; 236cdf0e10cSrcweir 237cdf0e10cSrcweir if (Cplusplus) 238cdf0e10cSrcweir { 239cdf0e10cSrcweir ta.t = p = (uchar *) outptr; 240cdf0e10cSrcweir 241cdf0e10cSrcweir if (! end) 242cdf0e10cSrcweir strcpy((char *) p, "extern \"C\" {"); 243cdf0e10cSrcweir else 244cdf0e10cSrcweir strcpy((char *) p, "}"); 245cdf0e10cSrcweir 246cdf0e10cSrcweir p += strlen((char *) p); 247cdf0e10cSrcweir 248cdf0e10cSrcweir *p++ = '\n'; 249cdf0e10cSrcweir 250cdf0e10cSrcweir ta.len = (char *) p - outptr; 251cdf0e10cSrcweir outptr = (char *) p; 252cdf0e10cSrcweir tr.tp = tr.bp; 253cdf0e10cSrcweir puttokens(&tr); 254cdf0e10cSrcweir } 255cdf0e10cSrcweir } 256cdf0e10cSrcweir 257