time_t ar_member_date (const char *name) { char *arname; char *memname; long int val; ar_parse_name (name, &arname, &memname); /* Make sure we know the modtime of the archive itself because we are likely to be called just before commands to remake a member are run, and they will change the archive itself. But we must be careful not to enter_file the archive itself if it does not exist, because pattern_search assumes that files found in the data base exist or can be made. */ { struct file *arfile; arfile = lookup_file (arname); if (arfile == 0 && file_exists_p (arname)) arfile = enter_file (strcache_add (arname)); if (arfile != 0) (void) f_mtime (arfile, 0); } val = ar_scan (arname, ar_member_date_1, memname); free (arname); return (val <= 0 ? (time_t) -1 : (time_t) val); }
void install_default_suffix_rules (void) { char **s; if (no_builtin_rules_flag) return; for (s = default_suffix_rules; *s != 0; s += 2) { struct file *f = enter_file (strcache_add (s[0])); /* Don't clobber cmds given in a makefile if there were any. */ if (f->cmds == 0) { #ifndef CONFIG_WITH_ALLOC_CACHES f->cmds = xmalloc (sizeof (struct commands)); #else f->cmds = alloccache_alloc (&commands_cache); #endif f->cmds->fileinfo.filenm = 0; f->cmds->commands = s[1]; f->cmds->command_lines = 0; #ifdef CONFIG_WITH_MEMORY_OPTIMIZATIONS f->cmds->refs = 1000; #endif } } }
FILE*enter_file2(const char*name, const char*filename, void*state) { enter_file(name, filename, state); FILE*fi = fopen(filename, "rb"); if(!fi) { as3_error("Couldn't find file %s: %s", filename, strerror(errno)); } return fi; }
static void initialize_ucpp(struct lexer_state *ls, FILE *in) { int i; /* * This code is an adaption of ucpp's sample.c */ /* step 1 */ init_cpp(); /* step 2 */ no_special_macros = 0; emit_defines = emit_assertions = 0; /* step 3 -- with assertions */ init_tables(1); /* step 4 -- no default include path */ init_include_path(0); /* step 5 -- no need to reset the two emit_* variables set in 2 */ emit_dependencies = 0; /* step 6 -- we work with stdin, this is not a real filename */ set_init_filename("[stdin]", 0); /* step 7 -- we make sure that assertions are on, and pragma are handled */ init_lexer_state(ls); init_lexer_mode(ls); ls->flags |= HANDLE_ASSERTIONS | HANDLE_PRAGMA | LINE_NUM; /* step 8 -- input is from specified FILE stream */ ls->input = in; /* step 9 -- we do not have any macro to define, but we add any argument as an include path */ /* for (i = 1; i < argc; i ++) add_incpath(argv[i]);*/ add_incpath("/usr/local/nwcc/include"); /* XXXXXXXXXXXXXXXX */ add_incpath("/usr/include"); /* XXXXXXXXXXXXXXXX */ for (i = 0; cpp_args[i] != NULL; ++i ){ if (strncmp(cpp_args[i], "-I", 2) == 0) { add_incpath(cpp_args[i]+2); } else if (strncmp(cpp_args[i], "-D", 2) == 0) { define_macro(ls, cpp_args[i]+2); } else if (strncmp(cpp_args[i], "-U", 2) == 0) { undef_macro(ls, cpp_args[i]+2); } } /* step 10 -- we are a lexer and we want CONTEXT tokens */ enter_file(ls, ls->flags); }
/* Similar to record_files in read.c, only much much simpler. */ static void incdep_commit_recorded_file (const char *filename, struct dep *deps, const struct floc *flocp) { struct file *f; /* Perform some validations. */ if (filename[0] == '.' && ( streq(filename, ".POSIX") || streq(filename, ".EXPORT_ALL_VARIABLES") || streq(filename, ".INTERMEDIATE") || streq(filename, ".LOW_RESOLUTION_TIME") || streq(filename, ".NOTPARALLEL") || streq(filename, ".ONESHELL") || streq(filename, ".PHONY") || streq(filename, ".PRECIOUS") || streq(filename, ".SECONDARY") || streq(filename, ".SECONDTARGETEXPANSION") || streq(filename, ".SILENT") || streq(filename, ".SHELLFLAGS") || streq(filename, ".SUFFIXES") ) ) { error (flocp, _("reserved filename '%s' used in dependency file, ignored"), filename); return; } /* Lookup or create an entry in the database. */ f = enter_file (filename); if (f->double_colon) { error (flocp, _("dependency file '%s' has a double colon entry already, ignoring"), filename); return; } f->is_target = 1; /* Append dependencies. */ deps = enter_prereqs (deps, NULL); if (deps) { struct dep *last = f->deps; if (!last) f->deps = deps; else { while (last->next) last = last->next; last->next = deps; } } }
void set_default_suffixes (void) { suffix_file = enter_file (".SUFFIXES"); if (no_builtin_rules_flag) (void) define_variable ("SUFFIXES", 8, "", o_default, 0); else { char *p = default_suffixes; suffix_file->deps = (struct dep *) multi_glob (parse_file_seq (&p, '\0', sizeof (struct dep), 1), sizeof (struct dep)); (void) define_variable ("SUFFIXES", 8, default_suffixes, o_default, 0); } }
void set_default_suffixes (void) { suffix_file = enter_file (strcache_add (".SUFFIXES")); if (no_builtin_rules_flag) define_variable_cname ("SUFFIXES", "", o_default, 0); else { char *p = default_suffixes; suffix_file->deps = enter_prereqs(PARSE_FILE_SEQ (&p, struct dep, '\0', NULL, 0), NULL); define_variable_cname ("SUFFIXES", default_suffixes, o_default, 0); } }
int ar_touch (const char *name) { char *arname, *memname; int val; ar_parse_name (name, &arname, &memname); /* Make sure we know the modtime of the archive itself before we touch the member, since this will change the archive modtime. */ { struct file *arfile; arfile = enter_file (strcache_add (arname)); f_mtime (arfile, 0); } val = 1; switch (ar_member_touch (arname, memname)) { case -1: error (NILF, _("touch: Archive `%s' does not exist"), arname); break; case -2: error (NILF, _("touch: `%s' is not a valid archive"), arname); break; case -3: perror_with_name ("touch: ", arname); break; case 1: error (NILF, _("touch: Member `%s' does not exist in `%s'"), memname, arname); break; case 0: val = 0; break; default: error (NILF, _("touch: Bad return code from ar_member_touch on `%s'"), name); } free (arname); return val; }
void set_default_suffixes (void) { suffix_file = enter_file (strcache_add (".SUFFIXES")); suffix_file->builtin = 1; if (no_builtin_rules_flag) define_variable_cname ("SUFFIXES", "", o_default, 0); else { struct dep *d; const char *p = default_suffixes; suffix_file->deps = enter_prereqs (PARSE_SIMPLE_SEQ ((char **)&p, struct dep), NULL); for (d = suffix_file->deps; d; d = d->next) d->file->builtin = 1; define_variable_cname ("SUFFIXES", default_suffixes, o_default, 0); } }
void install_default_suffix_rules (void) { register char **s; if (no_builtin_rules_flag) return; for (s = default_suffix_rules; *s != 0; s += 2) { register struct file *f = enter_file (s[0]); /* Don't clobber cmds given in a makefile if there were any. */ if (f->cmds == 0) { f->cmds = (struct commands *) xmalloc (sizeof (struct commands)); f->cmds->fileinfo.filenm = 0; f->cmds->commands = s[1]; f->cmds->command_lines = 0; } } }
void install_default_suffix_rules (void) { const char **s; if (no_builtin_rules_flag) return; for (s = default_suffix_rules; *s != 0; s += 2) { struct file *f = enter_file (strcache_add (s[0])); /* This function should run before any makefile is parsed. */ assert (f->cmds == 0); f->cmds = xmalloc (sizeof (struct commands)); f->cmds->fileinfo.filenm = 0; f->cmds->commands = xstrdup (s[1]); f->cmds->command_lines = 0; f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT; f->builtin = 1; } }
void install_default_suffix_rules (void) { char **s; if (no_builtin_rules_flag) return; for (s = default_suffix_rules; *s != 0; s += 2) { struct file *f = enter_file (strcache_add (s[0])); /* Don't clobber cmds given in a makefile if there were any. */ if (f->cmds == 0) { f->cmds = xmalloc (sizeof (struct commands)); f->cmds->fileinfo.filenm = 0; f->cmds->commands = s[1]; f->cmds->command_lines = 0; f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT; } } }
h_core_bool_t write_entry_to_all_files(h_audit_log_t *log, char *formatted_entry) { assert(log); assert(formatted_entry); h_core_bool_t success; FILE *file; success = h_core_bool_true; pthread_mutex_lock(&log->mutex); { h_container_set_iterate_start(log->files); while ((file = h_container_set_iterate_next(log->files))) { if (!enter_file(formatted_entry, file)) { h_core_trace("enter_file"); success = h_core_bool_false; } } } pthread_mutex_unlock(&log->mutex); return success; }
FILE_TIMESTAMP f_mtime (struct file *file, int search) { FILE_TIMESTAMP mtime; /* File's mtime is not known; must get it from the system. */ #ifndef NO_ARCHIVES if (ar_name (file->name)) { /* This file is an archive-member reference. */ char *arname, *memname; struct file *arfile; time_t member_date; /* Find the archive's name. */ ar_parse_name (file->name, &arname, &memname); /* Find the modification time of the archive itself. Also allow for its name to be changed via VPATH search. */ arfile = lookup_file (arname); if (arfile == 0) arfile = enter_file (strcache_add (arname)); mtime = f_mtime (arfile, search); check_renamed (arfile); if (search && strcmp (arfile->hname, arname)) { /* The archive's name has changed. Change the archive-member reference accordingly. */ char *name; unsigned int arlen, memlen; arlen = strlen (arfile->hname); memlen = strlen (memname); name = xmalloc (arlen + 1 + memlen + 2); memcpy (name, arfile->hname, arlen); name[arlen] = '('; memcpy (name + arlen + 1, memname, memlen); name[arlen + 1 + memlen] = ')'; name[arlen + 1 + memlen + 1] = '\0'; /* If the archive was found with GPATH, make the change permanent; otherwise defer it until later. */ if (arfile->name == arfile->hname) rename_file (file, name); else rehash_file (file, name); check_renamed (file); } free (arname); file->low_resolution_time = 1; if (mtime == NONEXISTENT_MTIME) /* The archive doesn't exist, so its members don't exist either. */ return NONEXISTENT_MTIME; member_date = ar_member_date (file->hname); mtime = (member_date == (time_t) -1 ? NONEXISTENT_MTIME : file_timestamp_cons (file->hname, member_date, 0)); } else #endif { mtime = name_mtime (file->name); if (mtime == NONEXISTENT_MTIME && search && !file->ignore_vpath) { /* If name_mtime failed, search VPATH. */ const char *name = vpath_search (file->name, &mtime, NULL, NULL); if (name /* Last resort, is it a library (-lxxx)? */ || (file->name[0] == '-' && file->name[1] == 'l' && (name = library_search (file->name, &mtime)) != 0)) { if (mtime != UNKNOWN_MTIME) /* vpath_search and library_search store UNKNOWN_MTIME if they didn't need to do a stat call for their work. */ file->last_mtime = mtime; /* If we found it in VPATH, see if it's in GPATH too; if so, change the name right now; if not, defer until after the dependencies are updated. */ if (gpath_search (name, strlen(name) - strlen(file->name) - 1)) { rename_file (file, name); check_renamed (file); return file_mtime (file); } rehash_file (file, name); check_renamed (file); /* If the result of a vpath search is -o or -W, preserve it. Otherwise, find the mtime of the resulting file. */ if (mtime != OLD_MTIME && mtime != NEW_MTIME) mtime = name_mtime (name); } } } /* Files can have bogus timestamps that nothing newly made will be "newer" than. Updating their dependents could just result in loops. So notify the user of the anomaly with a warning. We only need to do this once, for now. */ if (!clock_skew_detected && mtime != NONEXISTENT_MTIME && mtime != NEW_MTIME && !file->updated) { static FILE_TIMESTAMP adjusted_now; FILE_TIMESTAMP adjusted_mtime = mtime; #if defined(WINDOWS32) || defined(__MSDOS__) /* Experimentation has shown that FAT filesystems can set file times up to 3 seconds into the future! Play it safe. */ #define FAT_ADJ_OFFSET (FILE_TIMESTAMP) 3 FILE_TIMESTAMP adjustment = FAT_ADJ_OFFSET << FILE_TIMESTAMP_LO_BITS; if (ORDINARY_MTIME_MIN + adjustment <= adjusted_mtime) adjusted_mtime -= adjustment; #elif defined(__EMX__) /* FAT filesystems round time to the nearest even second! Allow for any file (NTFS or FAT) to perhaps suffer from this brain damage. */ FILE_TIMESTAMP adjustment = (((FILE_TIMESTAMP_S (adjusted_mtime) & 1) == 0 && FILE_TIMESTAMP_NS (adjusted_mtime) == 0) ? (FILE_TIMESTAMP) 1 << FILE_TIMESTAMP_LO_BITS : 0); #endif /* If the file's time appears to be in the future, update our concept of the present and try once more. */ if (adjusted_now < adjusted_mtime) { int resolution; FILE_TIMESTAMP now = file_timestamp_now (&resolution); adjusted_now = now + (resolution - 1); if (adjusted_now < adjusted_mtime) { #ifdef NO_FLOAT error (NILF, _("Warning: File '%s' has modification time in the future"), file->name); #else double from_now = (FILE_TIMESTAMP_S (mtime) - FILE_TIMESTAMP_S (now) + ((FILE_TIMESTAMP_NS (mtime) - FILE_TIMESTAMP_NS (now)) / 1e9)); char from_now_string[100]; if (from_now >= 99 && from_now <= ULONG_MAX) sprintf (from_now_string, "%lu", (unsigned long) from_now); else sprintf (from_now_string, "%.2g", from_now); error (NILF, _("Warning: File '%s' has modification time %s s in the future"), file->name, from_now_string); #endif clock_skew_detected = 1; } } } /* Store the mtime into all the entries for this file. */ if (file->double_colon) file = file->double_colon; do { /* If this file is not implicit but it is intermediate then it was made so by the .INTERMEDIATE target. If this file has never been built by us but was found now, it existed before make started. So, turn off the intermediate bit so make doesn't delete it, since it didn't create it. */ if (mtime != NONEXISTENT_MTIME && file->command_state == cs_not_started && file->command_state == cs_not_started && !file->tried_implicit && file->intermediate) file->intermediate = 0; file->last_mtime = mtime; file = file->prev; } while (file != 0); return mtime; }
void set_file_variables (struct file *file) { struct dep *d; const char *at, *percent, *star, *less; #ifndef NO_ARCHIVES /* If the target is an archive member `lib(member)', then $@ is `lib' and $% is `member'. */ if (ar_name (file->name)) { unsigned int len; const char *cp; char *p; cp = strchr (file->name, '('); p = alloca (cp - file->name + 1); memcpy (p, file->name, cp - file->name); p[cp - file->name] = '\0'; at = p; len = strlen (cp + 1); p = alloca (len); memcpy (p, cp + 1, len - 1); p[len - 1] = '\0'; percent = p; } else #endif /* NO_ARCHIVES. */ { at = file->name; percent = ""; } /* $* is the stem from an implicit or static pattern rule. */ if (file->stem == 0) { /* In Unix make, $* is set to the target name with any suffix in the .SUFFIXES list stripped off for explicit rules. We store this in the `stem' member. */ const char *name; unsigned int len; #ifndef NO_ARCHIVES if (ar_name (file->name)) { name = strchr (file->name, '(') + 1; len = strlen (name) - 1; } else #endif { name = file->name; len = strlen (name); } for (d = enter_file (strcache_add (".SUFFIXES"))->deps; d ; d = d->next) { unsigned int slen = strlen (dep_name (d)); if (len > slen && strneq (dep_name (d), name + (len - slen), slen)) { file->stem = strcache_add_len (name, len - slen); break; } } if (d == 0) file->stem = ""; } star = file->stem; /* $< is the first not order-only dependency. */ less = ""; for (d = file->deps; d != 0; d = d->next) if (!d->ignore_mtime) { if (!d->need_2nd_expansion) less = dep_name (d); break; } if (file->cmds == default_file->cmds) /* This file got its commands from .DEFAULT. In this case $< is the same as $@. */ less = at; #define DEFINE_VARIABLE(name, len, value) \ (void) define_variable_for_file (name,len,value,o_automatic,0,file) /* Define the variables. */ DEFINE_VARIABLE ("<", 1, less); DEFINE_VARIABLE ("*", 1, star); DEFINE_VARIABLE ("@", 1, at); DEFINE_VARIABLE ("%", 1, percent); /* Compute the values for $^, $+, $?, and $|. */ { static char *plus_value=0, *bar_value=0, *qmark_value=0; static unsigned int plus_max=0, bar_max=0, qmark_max=0; unsigned int qmark_len, plus_len, bar_len; char *cp; char *caret_value; char *qp; char *bp; unsigned int len; struct hash_table dep_hash; void **slot; /* Compute first the value for $+, which is supposed to contain duplicate dependencies as they were listed in the makefile. */ plus_len = 0; bar_len = 0; for (d = file->deps; d != 0; d = d->next) { if (!d->need_2nd_expansion) { if (d->ignore_mtime) bar_len += strlen (dep_name (d)) + 1; else plus_len += strlen (dep_name (d)) + 1; } } if (bar_len == 0) bar_len++; if (plus_len == 0) plus_len++; if (plus_len > plus_max) plus_value = xrealloc (plus_value, plus_max = plus_len); cp = plus_value; qmark_len = plus_len + 1; /* Will be this or less. */ for (d = file->deps; d != 0; d = d->next) if (! d->ignore_mtime && ! d->need_2nd_expansion) { const char *c = dep_name (d); #ifndef NO_ARCHIVES if (ar_name (c)) { c = strchr (c, '(') + 1; len = strlen (c) - 1; } else #endif len = strlen (c); memcpy (cp, c, len); cp += len; *cp++ = FILE_LIST_SEPARATOR; if (! (d->changed || always_make_flag)) qmark_len -= len + 1; /* Don't space in $? for this one. */ } /* Kill the last space and define the variable. */ cp[cp > plus_value ? -1 : 0] = '\0'; DEFINE_VARIABLE ("+", 1, plus_value); /* Compute the values for $^, $?, and $|. */ cp = caret_value = plus_value; /* Reuse the buffer; it's big enough. */ if (qmark_len > qmark_max) qmark_value = xrealloc (qmark_value, qmark_max = qmark_len); qp = qmark_value; if (bar_len > bar_max) bar_value = xrealloc (bar_value, bar_max = bar_len); bp = bar_value; /* Make sure that no dependencies are repeated in $^, $?, and $|. It would be natural to combine the next two loops but we can't do it because of a situation where we have two dep entries, the first is order-only and the second is normal (see below). */ hash_init (&dep_hash, 500, dep_hash_1, dep_hash_2, dep_hash_cmp); for (d = file->deps; d != 0; d = d->next) { if (d->need_2nd_expansion) continue; slot = hash_find_slot (&dep_hash, d); if (HASH_VACANT (*slot)) hash_insert_at (&dep_hash, d, slot); else { /* Check if the two prerequisites have different ignore_mtime. If so then we need to "upgrade" one that is order-only. */ struct dep* hd = (struct dep*) *slot; if (d->ignore_mtime != hd->ignore_mtime) d->ignore_mtime = hd->ignore_mtime = 0; } } for (d = file->deps; d != 0; d = d->next) { const char *c; if (d->need_2nd_expansion || hash_find_item (&dep_hash, d) != d) continue; c = dep_name (d); #ifndef NO_ARCHIVES if (ar_name (c)) { c = strchr (c, '(') + 1; len = strlen (c) - 1; } else #endif len = strlen (c); if (d->ignore_mtime) { memcpy (bp, c, len); bp += len; *bp++ = FILE_LIST_SEPARATOR; } else { memcpy (cp, c, len); cp += len; *cp++ = FILE_LIST_SEPARATOR; if (d->changed || always_make_flag) { memcpy (qp, c, len); qp += len; *qp++ = FILE_LIST_SEPARATOR; } } } hash_free (&dep_hash, 0); /* Kill the last spaces and define the variables. */ cp[cp > caret_value ? -1 : 0] = '\0'; DEFINE_VARIABLE ("^", 1, caret_value); qp[qp > qmark_value ? -1 : 0] = '\0'; DEFINE_VARIABLE ("?", 1, qmark_value); bp[bp > bar_value ? -1 : 0] = '\0'; DEFINE_VARIABLE ("|", 1, bar_value); } #undef DEFINE_VARIABLE }
int main(int argc, char *argv[]) { int i, r; struct lexer_state ls; /* step 1 */ init_cpp(); /* step 2 */ no_special_macros = 0; emit_defines = emit_assertions = 0; /* step 3 -- with assertions */ init_tables(1); /* step 4 -- no default include path */ init_include_path(0); /* step 5 -- no need to reset the two emit_* variables set in 2 */ emit_dependencies = 0; /* step 6 -- we work with stdin, this is not a real filename */ set_init_filename("[stdin]", 0); /* step 7 -- we make sure that assertions are on, and pragma are handled */ init_lexer_state(&ls); init_lexer_mode(&ls); ls.flags |= HANDLE_ASSERTIONS | HANDLE_PRAGMA | LINE_NUM; /* step 8 -- input is from stdin */ ls.input = stdin; /* step 9 -- we do not have any macro to define, but we add any argument as an include path */ for (i = 1; i < argc; i ++) add_incpath(argv[i]); /* step 10 -- we are a lexer and we want CONTEXT tokens */ enter_file(&ls, ls.flags); /* read tokens until end-of-input is reached -- errors (non-zero return values different from CPPERR_EOF) are ignored */ while ((r = lex(&ls)) < CPPERR_EOF) { if (r) { /* error condition -- no token was retrieved */ continue; } /* we print each token: its numerical value, and its string content; if this is a PRAGMA token, the string content is in fact a compressed token list, that we uncompress and print. */ if (ls.ctok->type == PRAGMA) { unsigned char *c = (unsigned char *)(ls.ctok->name); printf("line %ld: <#pragma>\n", ls.line); for (; *c; c ++) { int t = *c; if (STRING_TOKEN(t)) { printf(" <%2d> ", t); for (c ++; *c != PRAGMA_TOKEN_END; c ++) putchar(*c); putchar('\n'); } else { printf(" <%2d> `%s'\n", t, operators_name[t]); } } } else if (ls.ctok->type == CONTEXT) { printf("new context: file '%s', line %ld\n", ls.ctok->name, ls.ctok->line); } else if (ls.ctok->type == NEWLINE) { printf("[newline]\n"); } else { printf("line %ld: <%2d> `%s'\n", ls.ctok->line, ls.ctok->type, STRING_TOKEN(ls.ctok->type) ? ls.ctok->name : operators_name[ls.ctok->type]); } } return 0; }