static void TargPrintNode(GNode *gn, bool full) { if (OP_NOP(gn->type)) return; switch((gn->special & SPECIAL_MASK)) { case SPECIAL_SUFFIXES: case SPECIAL_PHONY: case SPECIAL_ORDER: case SPECIAL_NOTHING: case SPECIAL_MAIN: case SPECIAL_IGNORE: return; default: break; } if (full) { printf("# %d unmade prerequisites\n", gn->unmade); if (! (gn->type & (OP_JOIN|OP_USE|OP_EXEC))) { if (!is_out_of_date(gn->mtime)) { printf("# last modified %s: %s\n", time_to_string(&gn->mtime), status_to_string(gn)); } else if (gn->built_status != UNKNOWN) { printf("# non-existent (maybe): %s\n", status_to_string(gn)); } else { printf("# unmade\n"); } } } if (!Lst_IsEmpty(&gn->parents)) { printf("# parent targets: "); Lst_Every(&gn->parents, TargPrintName); fputc('\n', stdout); } if (gn->impliedsrc) printf("# implied prerequisite: %s\n", gn->impliedsrc->name); printf("%-16s", gn->name); switch (gn->type & OP_OPMASK) { case OP_DEPENDS: printf(": "); break; case OP_FORCE: printf("! "); break; case OP_DOUBLEDEP: printf(":: "); break; } Targ_PrintType(gn->type); Lst_Every(&gn->children, TargPrintName); fputc('\n', stdout); Lst_Every(&gn->commands, Targ_PrintCmd); printf("\n\n"); if (gn->type & OP_DOUBLEDEP) { LstNode ln; for (ln = Lst_First(&gn->cohorts); ln != NULL; ln = Lst_Adv(ln)) TargPrintNode((GNode *)Lst_Datum(ln), full); } }
//store the lsa into the lsdb void accept_lsa_into_lsdb(struct backbone_eth* bb_link, struct link_state_adv *ic_lsa) { struct cr_lsdb_link_state lsa; lsa_to_lsdb_info(ic_lsa, &lsa); if(check_local_lsdb(bb_link, &lsa) == TRUE) return; struct cr_lsdb_link_state link; id_t lsdb = lsdb_get_eth_handle(bb_link); int err_code = cr_lsdb_link_state_find(&lsa.key, &link, lsdb); if(err_code == NOT_FOUND_ERR) { cr_lsdb_link_state_add(&lsa, lsdb); DEBUG(INFO,"<LSA>\t\t%d:%d--%d:%d seq(%d)\tADD (ITEM NOT EXISTS)", lsa.key.rt_id, lsa.key.if_id, lsa.key.n_rt_id, lsa.key.n_if_id, lsa.seq); #ifndef __EXCHANGE_DEBUG__ flood_lsa_forward(ic_lsa, bb_link); #endif }else if(err_code == NO_ERR) { if(is_out_of_date(&link)) { cr_lsdb_link_state_update(&lsa, lsdb); DEBUG(INFO,"<LSA>\t\t%d:%d--%d:%d seq(%d)\tSTATE ACCEPT (LOCAL STATE OVERTIME)", lsa.key.rt_id, lsa.key.if_id, lsa.key.n_rt_id, lsa.key.n_if_id, lsa.seq); #ifndef __EXCHANGE_DEBUG__ flood_lsa_forward(ic_lsa, bb_link); #endif return; } int ra = link_state_compare(&link, &lsa); if(ra < 0) { cr_lsdb_link_state_update(&lsa, lsdb); DEBUG(INFO,"<LSA>\t\t%d:%d--%d:%d seq(%d)\tSTATE ACCEPT (NEWER SEQ RECEIVED)", lsa.key.rt_id, lsa.key.if_id, lsa.key.n_rt_id, lsa.key.n_if_id, lsa.seq); #ifndef __EXCHANGE_DEBUG__ flood_lsa_forward(ic_lsa, bb_link); #endif }else if(ra > 0){ DEBUG(INFO,"<LSA>\t\t%d:%d--%d:%d seq(%d)\tFLOOD BACK(OLDER SEQ RECEIVED)", lsa.key.rt_id, lsa.key.if_id,lsa.key.n_rt_id, lsa.key.n_if_id, lsa.seq); #ifndef __EXCHANGE_DEBUG__ lsdb_to_lsa_info(&link, ic_lsa); flood_add_flood_lsa(ic_lsa, bb_link); #endif }else{ DEBUG(INFO,"<LSA>\t\t%d:%d--%d:%d seq(%d)\tDROP(SAME SEQ RECEIVED)", lsa.key.rt_id, lsa.key.if_id, lsa.key.n_rt_id, lsa.key.n_if_id, lsa.seq); } } }
bool Job_CheckCommands(GNode *gn) { /* Alter our type to tell if errors should be ignored or things * should not be printed so setup_and_run_command knows what to do. */ if (Targ_Ignore(gn)) gn->type |= OP_IGNORE; if (Targ_Silent(gn)) gn->type |= OP_SILENT; if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands) && (gn->type & OP_LIB) == 0) { /* * No commands. Look for .DEFAULT rule from which we might infer * commands */ if ((gn->type & OP_NODEFAULT) == 0 && (DEFAULT->type & OP_DUMMY) == 0 && !Lst_IsEmpty(&DEFAULT->commands)) { /* * Make only looks for a .DEFAULT if the node was never * the target of an operator, so that's what we do too. * If a .DEFAULT was given, we substitute its commands * for gn's commands and set the IMPSRC variable to be * the target's name The DEFAULT node acts like a * transformation rule, in that gn also inherits any * attributes or sources attached to .DEFAULT itself. */ Make_HandleUse(DEFAULT, gn); Var(IMPSRC_INDEX, gn) = Var(TARGET_INDEX, gn); } else if (is_out_of_date(Dir_MTime(gn))) { /* * The node wasn't the target of an operator we have no * .DEFAULT rule to go on and the target doesn't * already exist. There's nothing more we can do for * this branch. */ return false; } } return true; }
/*- *----------------------------------------------------------------------- * Make_Update -- * Perform update on the parents of a node. Used by JobFinish once * a node has been dealt with and by MakeStartJobs if it finds an * up-to-date node. * * Results: * Always returns 0 * * Side Effects: * The unmade field of pgn is decremented and pgn may be placed on * the toBeMade queue if this field becomes 0. * * If the child was made, the parent's childMade field will be set true * and its cmtime set to now. * * If the child wasn't made, the cmtime field of the parent will be * altered if the child's mtime is big enough. * *----------------------------------------------------------------------- */ void Make_Update(GNode *cgn) /* the child node */ { GNode *pgn; /* the parent node */ LstNode ln; /* Element in parents list */ /* * If the child was actually made, see what its modification time is * now -- some rules won't actually update the file. If the file still * doesn't exist, make its mtime now. */ if (cgn->built_status != UPTODATE) { /* * This is what Make does and it's actually a good thing, as it * allows rules like * * cmp -s y.tab.h parse.h || cp y.tab.h parse.h * * to function as intended. Unfortunately, thanks to the * stateless nature of NFS, there are times when the * modification time of a file created on a remote machine * will not be modified before the local stat() implied by * the Dir_MTime occurs, thus leading us to believe that the * file is unchanged, wreaking havoc with files that depend * on this one. */ if (noExecute || is_out_of_date(Dir_MTime(cgn))) ts_set_from_now(cgn->mtime); if (DEBUG(MAKE)) printf("update time: %s\n", time_to_string(cgn->mtime)); } /* SIB: this is where I should mark the build as finished */ cgn->build_lock = false; for (ln = Lst_First(&cgn->parents); ln != NULL; ln = Lst_Adv(ln)) { pgn = (GNode *)Lst_Datum(ln); /* SIB: there should be a siblings loop there */ pgn->unmade--; if (pgn->must_make) { if (DEBUG(MAKE)) printf("%s--=%d ", pgn->name, pgn->unmade); if ( ! (cgn->type & (OP_EXEC|OP_USE))) { if (cgn->built_status == MADE) { pgn->childMade = true; if (is_strictly_before(pgn->cmtime, cgn->mtime)) pgn->cmtime = cgn->mtime; } else { (void)Make_TimeStamp(pgn, cgn); } } if (pgn->unmade == 0) { /* * Queue the node up -- any unmade * predecessors will be dealt with in * MakeStartJobs. */ if (DEBUG(MAKE)) printf("QUEUING "); Array_Push(&toBeMade, pgn); } else if (pgn->unmade < 0) { Error("Child %s discovered graph cycles through %s", cgn->name, pgn->name); } } } if (DEBUG(MAKE)) printf("\n"); requeue_successors(cgn); }
bool Make_OODate(GNode *gn) { bool oodate; /* * Certain types of targets needn't even be sought as their datedness * doesn't depend on their modification time... */ if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_PHONY)) == 0) { (void)Dir_MTime(gn); if (DEBUG(MAKE)) { if (!is_out_of_date(gn->mtime)) printf("modified %s...", time_to_string(gn->mtime)); else printf("non-existent..."); } } /* * A target is remade in one of the following circumstances: * - its modification time is smaller than that of its youngest child * and it would actually be run (has commands or type OP_NOP) * - it's the object of a force operator * - it has no children, was on the lhs of an operator and doesn't * exist already. * * Libraries are only considered out-of-date if the archive module says * they are. */ if (gn->type & OP_USE) { /* * If the node is a USE node it is *never* out of date * no matter *what*. */ if (DEBUG(MAKE)) printf(".USE node..."); oodate = false; } else if ((gn->type & OP_LIB) && Arch_IsLib(gn)) { if (DEBUG(MAKE)) printf("library..."); /* always out of date if no children and :: target */ oodate = Arch_LibOODate(gn) || (is_out_of_date(gn->cmtime) && (gn->type & OP_DOUBLEDEP)); } else if (gn->type & OP_JOIN) { /* * A target with the .JOIN attribute is only considered * out-of-date if any of its children was out-of-date. */ if (DEBUG(MAKE)) printf(".JOIN node..."); oodate = gn->childMade; } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) { /* * A node which is the object of the force (!) operator or which * has the .EXEC attribute is always considered out-of-date. */ if (DEBUG(MAKE)) { if (gn->type & OP_FORCE) printf("! operator..."); else if (gn->type & OP_PHONY) printf(".PHONY node..."); else printf(".EXEC node..."); } oodate = true; } else if (is_strictly_before(gn->mtime, gn->cmtime) || (is_out_of_date(gn->cmtime) && (is_out_of_date(gn->mtime) || (gn->type & OP_DOUBLEDEP)))) { /* * A node whose modification time is less than that of its * youngest child or that has no children (cmtime == * OUT_OF_DATE) and either doesn't exist (mtime == OUT_OF_DATE) * or was the object of a :: operator is out-of-date. */ if (DEBUG(MAKE)) { if (is_strictly_before(gn->mtime, gn->cmtime)) printf("modified before source..."); else if (is_out_of_date(gn->mtime)) printf("non-existent and no sources..."); else printf(":: operator and no sources..."); } oodate = true; } else { oodate = false; } /* * If the target isn't out-of-date, the parents need to know its * modification time. Note that targets that appear to be out-of-date * but aren't, because they have no commands and aren't of type OP_NOP, * have their mtime stay below their children's mtime to keep parents * from thinking they're out-of-date. */ if (!oodate) Lst_ForEach(&gn->parents, MakeTimeStamp, gn); return oodate; }
/*- *----------------------------------------------------------------------- * CompatMake -- * Make a target. * * Side Effects: * If an error is detected and not being ignored, the process exits. *----------------------------------------------------------------------- */ static void CompatMake(void *gnp, /* The node to make */ void *pgnp) /* Parent to abort if necessary */ { GNode *gn = (GNode *)gnp; GNode *pgn = (GNode *)pgnp; GNode *sib; bool cmdsOk; if (DEBUG(MAKE)) printf("CompatMake(%s, %s)\n", pgn ? pgn->name : "NULL", gn->name); /* XXX some loops are not loops, people write dependencies * between siblings to make sure they get built. * Also, we don't recognize direct loops. */ if (gn == pgn) return; /* handle .USE right away */ if (gn->type & OP_USE) { Make_HandleUse(gn, pgn); return; } look_harder_for_target(gn); if (pgn != NULL && is_sibling(gn, pgn)) return; if (pgn == NULL) pgn = gn; if (pgn->type & OP_MADE) { sib = gn; do { sib->mtime = gn->mtime; sib->built_status = UPTODATE; sib = sib->sibling; } while (sib != gn); } switch(gn->built_status) { case UNKNOWN: /* First mark ourselves to be made, then apply whatever * transformations the suffix module thinks are necessary. * Once that's done, we can descend and make all our children. * If any of them has an error but the -k flag was given, * our 'must_make' field will be set false again. This is our * signal to not attempt to do anything but abort our * parent as well. */ gn->must_make = true; gn->built_status = BEINGMADE; /* note that, in case we have siblings, we only check all * children for all siblings, but we don't try to apply * any other rule. */ sib = gn; do { Suff_FindDeps(sib); Lst_ForEach(&sib->children, CompatMake, gn); sib = sib->sibling; } while (sib != gn); if (!gn->must_make) { Error("Build for %s aborted", gn->name); gn->built_status = ABORTED; pgn->must_make = false; return; } /* All the children were made ok. Now youngest points to * the newest child, we need to find out * if we exist and when we were modified last. The criteria * for datedness are defined by the Make_OODate function. */ if (DEBUG(MAKE)) printf("Examining %s...", gn->name); if (!Make_OODate(gn)) { gn->built_status = UPTODATE; if (DEBUG(MAKE)) printf("up-to-date.\n"); return; } else if (DEBUG(MAKE)) printf("out-of-date.\n"); /* If the user is just seeing if something is out-of-date, * exit now to tell him/her "yes". */ if (queryFlag) exit(1); /* normally, we run the job, but if we can't find any * commands, we defer to siblings instead. */ sib = gn; do { /* We need to be re-made. We also have to make sure * we've got a $? variable. To be nice, we also define * the $> variable using Make_DoAllVar(). */ Make_DoAllVar(sib); cmdsOk = node_find_valid_commands(sib); if (cmdsOk || (gn->type & OP_OPTIONAL)) break; sib = sib->sibling; } while (sib != gn); if (cmdsOk) { /* Our commands are ok, but we still have to worry * about the -t flag... */ if (!touchFlag) run_gnode(sib); else { Job_Touch(sib); if (gn != sib) Job_Touch(gn); } } else { node_failure(gn); sib->built_status = ERROR; } /* copy over what we just did */ gn->built_status = sib->built_status; if (gn->built_status != ERROR) { /* If the node was made successfully, mark it so, * update its modification time and timestamp all * its parents. * This is to keep its state from affecting that of * its parent. */ gn->built_status = MADE; sib->built_status = MADE; /* This is what Make does and it's actually a good * thing, as it allows rules like * * cmp -s y.tab.h parse.h || cp y.tab.h parse.h * * to function as intended. Unfortunately, thanks to * the stateless nature of NFS (and the speed of * this program), there are times when the * modification time of a file created on a remote * machine will not be modified before the stat() * implied by the Dir_MTime occurs, thus leading us * to believe that the file is unchanged, wreaking * havoc with files that depend on this one. */ if (noExecute || is_out_of_date(Dir_MTime(gn))) clock_gettime(CLOCK_REALTIME, &gn->mtime); if (is_strictly_before(gn->mtime, gn->youngest->mtime)) gn->mtime = gn->youngest->mtime; if (sib != gn) { if (noExecute || is_out_of_date(Dir_MTime(sib))) clock_gettime(CLOCK_REALTIME, &sib->mtime); if (is_strictly_before(sib->mtime, sib->youngest->mtime)) sib->mtime = sib->youngest->mtime; } if (DEBUG(MAKE)) printf("update time: %s\n", time_to_string(&gn->mtime)); if (!(gn->type & OP_EXEC)) { pgn->childMade = true; Make_TimeStamp(pgn, gn); } } else if (keepgoing) pgn->must_make = false; else { print_errors(); exit(1); } break; case ERROR: /* Already had an error when making this beastie. Tell the * parent to abort. */ pgn->must_make = false; break; case BEINGMADE: Error("Graph cycles through %s", gn->name); gn->built_status = ERROR; pgn->must_make = false; break; case MADE: if ((gn->type & OP_EXEC) == 0) { pgn->childMade = true; Make_TimeStamp(pgn, gn); } break; case UPTODATE: if ((gn->type & OP_EXEC) == 0) Make_TimeStamp(pgn, gn); break; default: break; } }
int main (int argc, char *argv[]) { int i; gboolean do_template = FALSE; gboolean do_xml = FALSE; gboolean auto_dependencies = TRUE; const char *read_template_file = NULL; const char *write_template_file = NULL; const char *output_doc_filename = NULL; CODatabase *database = NULL; gboolean template_exists; GString *cpp_options; GSList *subdirs = NULL; const char *cpp_flags; g_set_prgname(argv[0]); cpp_options = g_string_new (""); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { const char *mode = NULL; if (strcmp (argv[i], "--help") == 0) usage(); if (strcmp (argv[i], "--version") == 0) version(); else if (strcmp (argv[i], "--force") == 0) { do_template = TRUE; do_xml = TRUE; continue; } else if (strcmp (argv[i], "--xml") == 0) { output_doc_filename = argv[++i]; if (output_doc_filename == NULL) g_error("--xml needs argument"); continue; } else if (argv[i][1] == 'I' || argv[i][1] == 'D') { g_string_sprintfa (cpp_options, "%s ", argv[i]); continue; } else if (strcmp (argv[i], "--subdir") == 0) { char *subdir = argv[++i]; if (subdir == NULL) g_error ("--subdir needs argument"); subdirs = g_slist_append (subdirs, subdir); continue; } else if (strcmp (argv[i], "--template") == 0) { read_template_file = argv[++i]; write_template_file = read_template_file; if (read_template_file == NULL) g_error("--template needs argument"); continue; } else if (strcmp (argv[i], "--mode") == 0) { mode = argv[++i]; if (mode == NULL) g_error ("--mode needs argument"); } else if (strncmp (argv[i], "--mode=", 7) == 0) { mode = argv[i] + 7; } else g_error("unrecognized option: %s", argv[i]); if (mode != NULL) { if (strcmp (mode, "auto") == 0) { /* this is the default: nothing to do */ } else if (strcmp (mode, "xml") == 0) { auto_dependencies = FALSE; do_xml = TRUE; } else if (strcmp (mode, "template") == 0) { auto_dependencies = FALSE; do_template = TRUE; } else if (strcmp (mode, "force") == 0) { auto_dependencies = FALSE; do_xml = TRUE; do_template = TRUE; } else { g_error ("unrecognized mode: %s, " "must be auto,xml,template or force", mode); } } } } if (read_template_file == NULL && write_template_file == NULL) { gboolean template_exists = file_exists ("codoc.template"); gboolean xml_template_exists = file_exists ("codoc.template.xml"); if (template_exists && xml_template_exists) { g_warning ("you should get rid of codoc.template: it is replaced " "by codoc.template.xml"); read_template_file = "codoc.template.xml"; write_template_file = "codoc.template.xml"; } else if (template_exists) { g_warning ("You have just a deprecated codoc.template"); g_warning ("I will read from it and output a codoc.template.xml"); read_template_file = "codoc.template"; write_template_file = "codoc.template.xml"; } else if (xml_template_exists) { read_template_file = "codoc.template.xml"; write_template_file = "codoc.template.xml"; } else { g_message ("will create a new codoc.template.xml"); write_template_file = "codoc.template.xml"; } } if (cpp_options->len == 0) cpp_flags = NULL; else cpp_flags = cpp_options->str; if (auto_dependencies) { /* check whether we need to regenerate the template. */ if (older_than_h_files (read_template_file)) do_template = TRUE; /* check whether we need to regenerate the xml. */ if (do_template || is_out_of_date (output_doc_filename, write_template_file)) do_xml = TRUE; } if (write_template_file != NULL && read_template_file != NULL && strcmp (write_template_file, read_template_file) != 0) { do_template = TRUE; } if (read_template_file != NULL) { char *ext = strrchr (read_template_file, '.'); if (strcmp (ext, ".template") == 0) database = co_database_load_old (read_template_file); else database = co_database_load_xml (read_template_file); if (database == NULL) g_error("error loading template %s", read_template_file); } if (database == NULL) database = co_database_new (); if (cpp_flags != NULL) co_database_set_cpp_flags (database, cpp_flags); { GSList *at; for (at = subdirs; at != NULL; at = at->next) co_database_add_subdir (database, (char*) (at->data)); g_slist_free (subdirs); } if (do_template) { if (! co_database_merge (database, cpp_flags)) { g_warning ("error merging database with .h files"); exit (1); } if (! co_database_safe_save (database, write_template_file)) { g_warning ("error saving template %s", write_template_file); exit (1); } } if (do_xml) { if (output_doc_filename != NULL) { g_free (database->output_doc_filename); database->output_doc_filename = g_strdup (output_doc_filename); } if (!co_database_render (database)) g_error ("error writing the xml file"); } return 0; }