static void pre_include(char *file) { FILE *f; if ((f = fopen(file, "r")) != NULL) { pp_notesource(file, f); preprocess_only(); } else cc_msg("can't open pre-include file %s (ignored)\n", file); }
static char *new_synalloc_segment(void) { char *w; if (synsegcnt >= segmax) expand_segmax(segmax * SEGMAX_FACTOR); if (bindsegcur < bindsegcnt) { w = bindsegbase[--bindsegcnt]; if (debugging(DEBUG_2STORE) && synsegcnt>0) cc_msg("Syntax store %d from binder size %ld at %p\n", (int)synsegcnt, (long)SEGSIZE, w); } else { w = (char *)cc_alloc(SEGSIZE); if (debugging(DEBUG_STORE)) cc_msg("Syntax store alloc %d size %ld at %p (%s in $r)\n", (int)synsegcnt, (long)SEGSIZE, w, phasename, currentfunction.symstr); } return synsegbase[synsegcnt++] = w; }
static PathElement *mk_path_element(PathElement *link, int flags, char *name) { PathElement *p; if (debugging(DEBUG_FILES)) cc_msg("mk_path_element(%s)\n", name); p = (PathElement *) ccom_alloc((int32)strlen(name) + sizeof(PathElement)); p->link = link; p->flags = flags; strcpy(p->name, name); return p; }
void test_hashset_new() { HashSetConf conf; hashset_conf_init(&conf); conf.initial_capacity = 7; HashSet *set = hashset_new_conf(&conf); cc_assert(hashset_size(set) == 0, cc_msg("hashset_new: Initial size not 0")); size_t capacity = hashset_capacity(set); /* power of 2 rounding */ cc_assert(capacity == 8, cc_msg("hashset_new: Expected capactity was 8, but got %d", capacity)); hashset_destroy(set); }
void test_stack_pop() { Stack *s = stack_new(); int a = 1; int b = 2; int c = 3; stack_push(s, &a); stack_push(s, &b); stack_push(s, &c); cc_assert(stack_pop(s) == &c, cc_msg("stack_pop: Top stack element not as expected")); cc_assert(stack_peek(s) == &b, cc_msg("stack_pop: Top stack element not as expected")); stack_destroy(s); }
static char *new_global_segment(void) { char *w; /* I will recycle a segment that had been used for local space if there */ /* are any such available. */ if (bindsegcur < bindsegcnt) { w = bindsegbase[--bindsegcnt]; if (debugging(DEBUG_STORE)) cc_msg("Global store %d from binder size %ld at %p\n", (int)globallcnt, (long)SEGSIZE, w); } else { w = (char *)cc_alloc(SEGSIZE); if (debugging(DEBUG_STORE)) cc_msg("Global store alloc %d size %ld at %p (in $r)\n", (int)globallcnt, (long)SEGSIZE, w, currentfunction.symstr); } globallcnt++; globallp = w, globalltop = w + SEGSIZE; return w; }
void show_store_use(void) { #ifdef ENABLE_STORE cc_msg( "Total store use (excluding stdio buffers/stack) %ld bytes\n", (long)stuse_total); cc_msg("Global store use %ld/%ld + %ld bytes\n", (long)((int32)globallcnt*SEGSIZE - (globalltop - globallp)), (long)((int32)globallcnt*SEGSIZE), (long)globallxtra); cc_msg( " thereof %ld+%ld bytes pended relocation, %ld bytes pended data\n", (long)stuse[(int)SU_Xref], (long)stuse[(int)SU_Xsym], (long)stuse[(int)SU_Data]); cc_msg( " %ld bytes symbols, %ld bytes top-level vars, %ld bytes types\n", (long)stuse[(int)SU_Sym], (long)stuse[(int)SU_Bind], (long)stuse[(int)SU_Type]); cc_msg( " %ld bytes constants, %ld bytes pre-processor, %ld bytes wasted\n", (long)stuse[(int)SU_Const], (long)stuse[(int)SU_PP], (long)stuse_waste); cc_msg( "Local store use %ld+%ld/%ld bytes - front end max %ld\n", (long)synallmax, (long)bindallmax, (long)((int32)(int)(synsegcnt+bindsegcnt)*SEGSIZE), (long)maxAEstore); #endif /* ENABLE_STORE */ }
static char *new_bindalloc_segment(void) { if (bindsegcur >= bindsegcnt) { char *w = (char *)cc_alloc(SEGSIZE); if (bindsegcnt >= segmax) expand_segmax(segmax * SEGMAX_FACTOR); if (debugging(DEBUG_STORE)) cc_msg("Binder store alloc %d size %ld at %p (%s in $r)\n", (int)bindsegcnt, (long)SEGSIZE, w, phasename, currentfunction.symstr); bindsegbase[bindsegcnt++] = w; } return bindsegbase[bindsegcur++]; }
static FILE *try_instore_file(char *file, bool *sf) { FILE *include_file; if (debugging(DEBUG_FILES)) cc_msg("Try instore file '%s'\n", file); include_file = open_builtin_header(file, sf); if (include_file != NULL) { show_h_line(1, file, NO); #ifdef TARGET_IS_HELIOS push_include(NULL, file, PE_SYS); #else push_include(NULL, file); #endif } return include_file; }
void alloc_mark(void) /* @@@ not used essentially for C */ { Mark *p; if ((p = freemarks) != NULL) freemarks = p->prev; else p = (Mark *) GlobAlloc(SU_Other, sizeof(Mark)); p->prev = marklist; marklist = p; p->syn_segno = synsegcnt; p->syn_allp = synallp; p->syn_hwm = synallhwm; p->bind_segno = bindsegcur; p->bind_allp = bindallp; p->bind_hwm = bindallhwm; if (debugging(DEBUG_STORE)) cc_msg("Mark %d, %p, %lx :: %d, %p, %lx\n", synsegcnt, synallp, (long)synallhwm, bindsegcur, bindallp, (long)bindallhwm); }
static void rtcheck_set(char *opts) { int opt; int32 new_rtcheck; for (opt = *opts; opt != 0; opt = *++opts) { new_rtcheck = 0; switch (safe_toupper(opt)) { case 'A': new_rtcheck = RTCHECK_ARRAY; break; case 'C': new_rtcheck = RTCHECK_CASE; break; case 'N': new_rtcheck = RTCHECK_NIL; break; case 'R': new_rtcheck = RTCHECK_REFERENCE; break; case 'P': new_rtcheck = RTCHECK_ASSERT; break; case 'D': new_rtcheck = RTCHECK_DEADCODE; break; default: cc_msg("unknown option -r%c: ignored\n", opt); } rtcheck ^= new_rtcheck; } }
static void disable_warnings(char *opts) { int opt = *opts; int32 new_suppress; if (opt == 0) { var_warn_implicit_fns = 0; var_warn_deprecated = 0; feature |= FEATURE_NOWARNINGS; suppress |= D_ASSIGNTEST | D_IMPLICITNARROWING | D_IMPLICITVOID | D_PPNOSYSINCLUDECHECK; } else { while (opt) { new_suppress = 0L; switch (safe_toupper(opt)) { case 'A': new_suppress = D_ASSIGNTEST; break; case 'N': new_suppress = D_IMPLICITNARROWING; break; case 'P': new_suppress = D_PPNOSYSINCLUDECHECK; break; case 'V': new_suppress = D_IMPLICITVOID; break; case 'D': var_warn_deprecated = 0; break; case 'F': var_warn_implicit_fns = 0; break; /* Do I really want to put this in the new version ??? Tony 3/1/95 */ #if 0 #ifdef TARGET_IS_C40 case 'X': new_suppress = D_VOIDRETURN; break; #endif #endif /* 0 */ default: cc_msg("unknown option -w%c: ignored\n", opt); } suppress |= new_suppress; opt = *++opts; } } }
VoidStar GlobAlloc(StoreUse t, int32 n) { char *p = globallp; n = n + 3 & ~(int32)3; /* make n a multiple of sizeof(int) */ if (n > SEGSIZE) { /* Big global store requests get a single oversize page. */ p = (char *)cc_alloc(n); if (debugging(DEBUG_STORE)) cc_msg("Global overlarge store alloc size %ld at %p (in $r)\n", (long)n, p, currentfunction.symstr); globallxtra += n; /* could update globallcnt? */ } else { if (p+n > globalltop) stuse_waste += globalltop-p, p = new_global_segment(); globallp = p + n; } stuse[(int)t] += n; return p; }
/* #ifdef PASCAL_OR_FORTRAN -- comment out? */ void alloc_unmark(void) { Mark *p = marklist; if (p->prev == NULL) syserr(syserr_alloc_unmark); if (synsegcnt > p->syn_segno) syserr(syserr_alloc_unmark1); marklist = p->prev; p->prev = freemarks; freemarks = p; synsegcnt = p->syn_segno; synallp = p->syn_allp; synalltop = (synallp == DUFF_ADDR) ? (char *)DUFF_ADDR : synsegbase[synsegcnt-1] + SEGSIZE; synallhwm = p->syn_hwm; bindsegcur = p->bind_segno; bindallp = p->bind_allp; bindalltop = (bindallp == DUFF_ADDR) ? (char *)DUFF_ADDR : bindsegbase[bindsegcur-1] + SEGSIZE; bindallhwm = p->bind_hwm; if (debugging(DEBUG_STORE)) cc_msg("Unmark %d, %p, %lx :: %d, %p, %lx\n", synsegcnt, synallp, (long)synallhwm, bindsegcur, bindallp, (long)bindallhwm); }
void test_hashset_iter_next() { HashSet *hs = hashset_new(); char *a = "foo"; char *b = "bar"; char *c = "baz"; hashset_add(hs, a); hashset_add(hs, b); hashset_add(hs, c); size_t x = 0; size_t y = 0; size_t z = 0; HashSetIter iter; hashset_iter_init(&iter, hs); while (hashset_iter_has_next(&iter)) { char const *e = hashset_iter_next(&iter); if (!strcmp(e, "foo")) x++; if (!strcmp(e, "bar")) y++; if (!strcmp(e, "baz")) z++; } cc_assert((x == 1) && (y == 1) && (z == 1), cc_msg("hashset_iter: Unexpected number of " "elements returned by the iterator")); hashset_destroy(hs); }
VoidStar BindAlloc(int32 n) { char *p = bindallp; n = n + 3 & ~(int32)3; /* make n a multiple of sizeof(int) */ if (n > SEGSIZE) syserr(syserr_overlarge_store1, (long)n); if (p + n > bindalltop) { int i; /* 0..segmax */ if (bindsegcur > 0) bindsegptr[bindsegcur-1] = p; /* stash highest used */ for (i = marklist->bind_segno;; i++) /* search for scraps */ { if (i == bindsegcur) /* nowhere big enough */ { p = new_bindalloc_segment(); bindalltop = p + SEGSIZE; break; } p = bindsegptr[i]; /* hope springs eternal */ bindalltop = bindsegbase[i] + SEGSIZE; if (p+n <= bindalltop) /* fingers crossed */ { /* we have scavenged something useful - swap to current */ char *t = bindsegbase[i]; bindsegbase[i] = bindsegbase[bindsegcur-1]; bindsegbase[bindsegcur-1] = t; bindsegptr[i] = bindsegptr[bindsegcur-1]; if (debugging(DEBUG_2STORE)) { cc_msg("Scavenge binder %d (%p), %ld left\n", (int)i, t, (long)(bindalltop-(p+n))); } break; } } bindsegptr[bindsegcur-1] = (char *)DUFF_ADDR; } bindallp = p + n; if ((bindallhwm += n) > bindallmax) bindallmax = bindallhwm; return p; }
extern void driver_abort(char *message) { cc_msg("Compilation aborted: %s\n",message ); exit(EXIT_error); }
static void set_compile_options(int argc, char *argv[]) { int count, files = 0; char message[MAX_NAME]; /* AM: the following code is intended to deal with things like */ /* __CLK_TCK (see <time.h>) being different for different targets. */ /* It probably needs better amalgamation into Acorn's code for predefs */ #ifdef TARGET_PREDEFINES { static char *predefs[] = TARGET_PREDEFINES; int i; for (i=0; i < sizeof(predefs)/sizeof(predefs[0]); i++) /* note that the arg may be of the form "name" or "name=toks" */ /* the "name" for is equivalent to "name=1". */ pp_predefine(predefs[i]); } #endif for (count=1; count < argc; ++count) { char *current = argv[count]; if (current[0] == '-' && current[1] != 0) { switch (safe_toupper(current[1])) { case 'C': if (ccom_flags & FLG_PREPROCESS) feature |= FEATURE_PPCOMMENT; else ccom_flags |= FLG_NO_OBJECT_OUTPUT; break; case 'D': pp_predefine(current+2); break; case 'E': /* do we wish to fault -Exxx more generally? */ #ifdef DISABLE_ERRORS if (current[2]) { disable_errors(current+2); break; } #endif #ifdef COMPILING_ON_MVS if (current[2]) { cc_msg( "Obsolete use of '%s' to suppress errors -- use '-zu' for PCC mode\n", current); break; } #endif ccom_flags = (ccom_flags | FLG_PREPROCESS) & ~FLG_COMPILE; break; case 'F': feature_set(current+2); break; #ifdef TARGET_HAS_DEBUGGER case 'G': usrdbg_set(current+2); break; #endif case 'I': set_include_path(current+2, PE_USER); break; case 'J': ccom_flags &= ~FLG_INSTORE_FILES_IMPLICITLY; set_include_path(current+2, PE_SYS); break; case 'K': ccom_flags |= FLG_COUNTS; break; #ifndef NO_LISTING_OUTPUT case 'L': ccom_flags |= FLG_LISTING; listingfile = current + 2; break; #endif case 'M': ccom_flags |= FLG_MAKEFILE; if (current[2] == '<' || current[2] == 0) { ccom_flags &= ~(FLG_COMPILE+FLG_NOSYSINCLUDES); if (current[2] == '<') ccom_flags |= FLG_NOSYSINCLUDES; } else makefile = current+2; break; case 'O': /* * Hum, really we should never get here because this * this should be done by -zpz1. */ break; /* Paranoid define check. Tony 3/1/95 */ #ifdef TARGET_HAS_PROFILE #error Old style define TARGET_HAS_PROFILE (replaced by TARGET_HAS_PROFILER) #endif #ifdef TARGET_HAS_PROFILER case 'P': { int ch = safe_toupper(current[2]); int32 profile = 1L; if (ch == 0) /* do nothing */; else if (ch == 'G' || ch == 'X' && current[3] == 0) profile = 2L; else cc_msg("unknown profile option %s: -p assumed\n",current); var_profile_option = profile; } break; #endif /* TARGET_HAS_PROFILER */ case 'R': #ifdef PASCAL /*ECN*/ rtcheck_set(current+2); #else feature &= ~FEATURE_WR_STR_LITS; #endif break; case 'S': asmfile = current+2; /* "" for -S */ #ifdef COMPILING_ON_MVS /* pesky cc163 compatibility */ if (*asmfile == 0 && count+1<argc) asmfile = argv[++count]; #endif break; #ifdef TARGET_IS_XPUTER case 'T': /* -tn sets processor type == -tn */ pragma_set(current + 1); break; #endif case 'U': pp_preundefine(current+2); break; case 'W': disable_warnings(current+2); break; #ifdef TARGET_IS_MVS /* TARGET_USES_CCOM_INTERFACE ??? */ /* The following case provides -Xcsectname for CC 163 compatibility. */ /* It may be that the CCOM-style interface should stuff ALL unknown */ /* options to mcdep_config_option()? */ case 'X': if (!mcdep_config_option(current[1], current+2)) cc_msg("unknown option %s: ignored\n", current); break; #endif case 'Z': switch(safe_toupper(current[2])) { case 'B': target_lsbitfirst = !target_lsbytefirst; if (isdigit(current[3])) target_lsbitfirst = (current[3]-'0'); break; #ifdef TARGET_ENDIANNESS_CONFIGURABLE case 'E': { int lsbytefirst = current[3] - '0'; if (lsbytefirst) config &= ~CONFIG_BIG_ENDIAN; else config |= CONFIG_BIG_ENDIAN; target_lsbitfirst = lsbytefirst; } break; #endif case 'C': feature |= FEATURE_SIGNED_CHAR; break; case 'F': feature = (feature | FEATURE_FUSSY) & ~FEATURE_LIMITED_PCC; break; case 'I': pre_include(current+3); break; case 'J': config |= CONFIG_INDIRECT_SETJMP; /* related to -fR */ break; case 'P': pragma_set(current+3); break; case 'O': feature |= FEATURE_AOF_AREA_PER_FN; break; case 'Q': debug_set(current+3); break; #ifndef TARGET_IS_HELIOS case 'S': system_flavour = current+3; break; #endif case 'U': feature |= pcc_features(); break; #ifdef TARGET_IS_TRAN /* * Addition to remove C++ warnings (for fussy IGM people). * Tony 8/2/95. */ case 'W': feature |= FEATURE_NO_CPLUSPLUS_WARNINGS; break; #endif /* TARGET_IS_TRAN */ #ifdef PASCAL /*ECN*/ case 'Z': feature |= FEATURE_ISO; break; #endif default: if (!mcdep_config_option(current[2], current+3)) cc_msg("unknown option %s: ignored\n", current); break; } break; default: cc_msg("unknown option %s: ignored\n", current); break; } } else { switch (++files) { case 1: if (strcmp(current, "-") == 0) { /* then just leave as stdin */ #ifdef COMPILING_ON_RISC_OS # ifndef OBSOLETE_ARM_NAMES /* Hack round default no-buffering library. */ setvbuf(stdin, NULL, _IOLBF, 256); # endif #endif } else if (freopen(current,"r",stdin) != NULL) { UnparsedName unparse; char new_dir[MAX_NAME]; ccom_flags &= ~FLG_STDIN; sourcefile = current; /* * Add path name of source file to the -I list. */ translate_fname(current, &unparse, new_dir); new_dir[unparse.un_pathlen] = '\0'; path_hd = mk_path_element(path_hd, PE_USER, new_dir); /* Make sure path_tl is always the tail, even if file precedes -I */ if (path_hd->link == 0) path_tl = path_hd; } else { sprintf(message, "couldn't read file '%s'", current); driver_abort(message); } break; case 2: objectfile = current; break; default: driver_abort("too many file arguments"); } } } if (ccom_flags & FLG_STDIN) { path_hd = mk_path_element(path_hd, PE_USER, ""); if (path_hd->link == 0) path_tl = path_hd; } #ifdef TARGET_HAS_SEPARATE_CODE_DATA_SEGS /* On machines like amd29000 code and data buses are separate */ /* so that all non-instruction data must go in the data segment. */ #if defined TARGET_IS_C40 /* * Ho Hum * * The problem is that programs built with the -Zr option, (such as * the kernel and device drivers), do not have a static data area. * This means that strings MUST be placed into the code segment. BUT * on the C40 data pointers can only address 1/4 of the address map, and * so they may not be able to reach the code segment. (This is especially * true when you consider that the C40 has two address buses, and the plan * is to have data on one bus and code on the other). HENCE by default we * want to disable placing strings in the code segment, but for -Zr programs * we have no choice ... */ if (suppress_module != 1) { feature |= FEATURE_WR_STR_LITS; } else { feature &= ~FEATURE_WR_STR_LITS; } #else feature |= FEATURE_WR_STR_LITS; #endif /* TARGET_IS_C40 */ #endif /* TARGET_HAS_SEPARATE_CODE_DATA_SEGS */ if (ccom_flags & FLG_COMPILE) { /* under the driver.c interface at most one of the following is true */ #ifndef NO_OBJECT_OUTPUT if (objectfile[0] != '\0' && !(ccom_flags & FLG_NO_OBJECT_OUTPUT)) { objstream = cc_open(objectfile, BINARY_FILE); # ifdef COMPILING_ON_RISC_OS set_time_stamp(objectfile, NO); # endif } #endif #ifndef NO_ASSEMBLER_OUTPUT if (asmfile[0] != '\0') asmstream = cc_open(asmfile, TEXT_FILE); #endif if (objectfile[0] == '\0' && asmfile[0] == '\0') { asmstream = stdout; feature |= FEATURE_ANNOTATE; /* simple test use */ } #ifndef NO_LISTING_OUTPUT if (ccom_flags & FLG_LISTING) { if (listingfile[0] != '\0') { listingstream = cc_open(listingfile, TEXT_FILE); if (listingstream != stdout) /* @@@ get rid of this hack */ fprintf(listingstream, " 1 "); } else listingstream = stdout; if (ccom_flags & FLG_COUNTS) { FILE *map = fopen("counts", "rb"); if (map == NULL) driver_abort("couldn't read \"counts\" file"); if (!map_init(map)) driver_abort("malformed \"counts\" file"); } } #endif } if (ccom_flags & FLG_MAKEFILE) { if (makefile[0] == 0) makestream = stdout; else { makestream = cc_open(makefile, TEXT_FILE); } /* * Print out source file and object file for -M option */ fprintf(makestream, DEPEND_FORMAT, objectfile, sourcefile); } }
static void debug_set(char *opts) { int opt; long debugmask = 0L; for (opt = *opts; opt != 0; opt = *++opts) { debugmask = 0L; switch (safe_toupper(opt)) { #ifdef ENABLE_AETREE case 'A': debugmask = DEBUG_AETREE; break; #endif #ifdef ENABLE_BIND case 'B': debugmask = DEBUG_BIND; break; #endif #ifdef ENABLE_CSE case 'C': cse_debugcount++; debugmask = DEBUG_CSE; break; #endif #ifdef ENABLE_DATA case 'D': debugmask = DEBUG_DATA; break; #endif #ifdef ENABLE_FNAMES case 'F': debugmask = DEBUG_FNAMES; break; #endif #ifdef ENABLE_CG case 'G': debugmask = DEBUG_CG; break; #endif #ifdef ENABLE_SPILL case 'H': debugmask = DEBUG_SPILL; break; #endif #ifdef ENABLE_FILES case 'I': debugmask = DEBUG_FILES; break; #endif #ifdef ENABLE_LOCALCG case 'K': localcg_debugcount++; debugmask = DEBUG_LOCALCG; break; #endif #ifdef ENABLE_LEX case 'L': debugmask = DEBUG_LEX; break; #endif #ifdef ENABLE_MAPSTORE case 'M': debugmask = DEBUG_MAPSTORE; break; #endif #ifdef ENABLE_OBJ case 'O': debugmask = DEBUG_OBJ; break; #endif #ifdef ENABLE_PP case 'P': debugmask = DEBUG_PP; break; #endif #ifdef ENABLE_Q case 'Q': debugmask = DEBUG_Q; break; #endif #ifdef ENABLE_REGS case 'R': debugmask = DEBUG_REGS; break; #endif #ifdef ENABLE_SYN case 'S': debugmask = DEBUG_SYN; break; #endif #ifdef ENABLE_TYPE case 'T': debugmask = DEBUG_TYPE; break; #endif #ifdef ENABLE_STORE case 'U': debugmask = DEBUG_STORE; break; #endif #ifdef ENABLE_2STORE case 'W': debugmask = DEBUG_2STORE; break; #endif #ifdef ENABLE_X case 'X': debugmask = DEBUG_X; break; #endif #ifdef ENABLE_LOOP case 'Y': debugmask = DEBUG_LOOP; break; #endif /* * -Qz to modify syserr behaviour is always available */ case 'Z': syserr_behaviour++; #ifndef COMPILING_ON_MSDOS #ifdef __CC_NORCROFT (void) signal(SIGINT, SIG_DFL); /* permit NorCroft backtrace */ #endif #endif break; default: cc_msg("unknown option -zq%c: ignored\n", opt); } sysdebugmask |= debugmask; } }
static void feature_set(char *opts) { int opt; #define UNUSED 0 static int32 feature_flags[] = { /* 'A' */ FEATURE_ANOMALY, /* 'B' */ FEATURE_VERBOSE, /* 'C' */ FEATURE_LIMITED_PCC, #ifdef TARGET_IS_C40 /* 'D' */ FEATURE_OLD_STUBS, #else /* 'D' */ UNUSED, #endif /* 'E' */ FEATURE_6CHARMONOCASE, /* 'F' */ 0L-FEATURE_SAVENAME, /* N.B. -ve */ /* 'G' */ UNUSED, /* 'H' */ FEATURE_PREDECLARE, /* 'I' */ FEATURE_USERINCLUDE_LISTING, /* 'J' */ FEATURE_SYSINCLUDE_LISTING, /* 'K' */ FEATURE_KANDR_INCLUDE, /* 'L' */ FEATURE_DONTUSE_LINKREG, /* 'M' */ FEATURE_PPNOUSE, /* 'N' */ FEATURE_SAVENAME, /* 'O' */ FEATURE_WARNOLDFNS, /* 'P' */ FEATURE_TELL_PTRINT, /* 'Q' */ FEATURE_ALLOWCOUNTEDSTRINGS, /* 'R' */ FEATURE_LET_LONGJMP_CORRUPT_REGVARS, /* 'S' */ FEATURE_ANNOTATE, #ifdef TARGET_IS_C40 /* 'T' */ 0L - FEATURE_WARNOLDFNS, #else /* 'T' */ UNUSED, #endif /* 'U' */ FEATURE_UNEXPANDED_LISTING, /* 'V' */ FEATURE_NOUSE, /* 'W' */ FEATURE_WR_STR_LITS, /* 'X' */ UNUSED, /* 'Y' */ UNUSED, /* 'Z' */ FEATURE_INLINE_CALL_KILLS_LINKREG }; #undef UNUSED for (opt = *opts; opt != 0; opt = *++opts) { int ch = safe_toupper(opt); if (ch >= 'A') { int n = ASCII(ch) - ASCII('A'); if (n < sizeof(feature_flags)/sizeof(int32)) { int32 flag = feature_flags[n]; if (flag < 0) feature &= ~-flag; else if (flag > 0) feature |= flag; else goto unknown; } else if (ch == 'X') suppress &= ~D_SUPPRESSED; else if (ch == 'Z') ccom_flags |= FLG_USE_SYSTEM_PATH; else unknown: cc_msg("unknown option -f%c: ignored\n", opt); } } }
extern FILE *pp_inclopen(char *file, bool systemheader, bool *sf, char **hostname) { FILE *new_include_file; UnparsedName unparse; char new_file[MAX_NAME]; *hostname = file; translate_fname(file, &unparse, new_file); if (!(unparse.type & FNAME_ROOTED)) { PathElement *p; #ifndef NO_INSTORE_FILES if ((ccom_flags & FLG_INSTORE_FILES_IMPLICITLY) && systemheader) { /* Note that it is important for portability (even across unix/riscos) */ /* to have the original 'file' and not the munged 'new_file' instore. */ new_include_file = try_instore_file(file, sf); if (new_include_file != NULL) return new_include_file; } #endif p = path_hd; if (systemheader || (ccom_flags & FLG_USE_SYSTEM_PATH)) p = p->link; while (p != NULL) { char current[MAX_NAME]; if (p->flags & INSTORE_FILE) { #ifndef NO_INSTORE_FILES /* Note that it is important for portability (even across unix/riscos) */ /* to have the original 'file' and not the munged 'new_file' instore. */ new_include_file = try_instore_file(file, sf); if (new_include_file != NULL) return new_include_file; #endif } #ifdef TARGET_IS_HELIOS /* * XXX - NC - 14/5/93 (Day after official C40 release!) * * The code appears to just skip the first element in the * include path list if the file is a system file. This * is wierd, since the flags field encodes whether the * directory has been added to the list as a user or a * system file. */ else if (((p->flags & PE_USER) && !systemheader) || ((p->flags & PE_SYS) && systemheader) ) #else else /* current path is not :mem */ #endif { strcpy(current, p->name); if (strlen(current) + strlen(new_file) + 1 <= MAX_NAME) { strcat(current, new_file); if (debugging(DEBUG_FILES)) cc_msg("Try file '%s'\n", current); if ((new_include_file = fopen(current, "r")) != 0) { if (!(systemheader && (ccom_flags & FLG_NOSYSINCLUDES))) show_h_line(1, current, YES); #ifdef TARGET_IS_HELIOS *hostname = push_include(current, current, p->flags); #else *hostname = push_include(current, current); #endif return new_include_file; } else if (debugging(DEBUG_FILES)) cc_msg("Open attempt failed, errno = %d\n", errno ); } } p = p->link; } #ifndef NO_INSTORE_FILES /* Not found - ANSI require looking for "stdio.h" as <stdio.h> when all */ /* else has failed. */ /* Note that it is important for portability (even across unix/riscos) */ /* to have the original 'file' and not the munged 'new_file' instore. */ return try_instore_file(file, sf); #endif }