static int update_format_list ( char *origin, FF_BUFSIZE_PTR desc_buffer, FORMAT_LIST_HANDLE hf_list ) { FORMAT_PTR format = NULL; int error; error = make_format(origin, desc_buffer, &format); if (!error) { if (!*hf_list) { *hf_list = dll_init(); if (!*hf_list) error = ERR_MEM_LACK; } } if (!error) { if (dll_add(*hf_list)) dll_assign(format, DLL_FMT, dll_last(*hf_list)); else error = ERR_MEM_LACK; } if (error && format) ff_destroy_format(format); return(error); }
static int append_EOL_to_format ( FORMAT_PTR format ) { VARIABLE_PTR EOL_var = NULL; EOL_var = ff_create_variable("EOL"); if (!EOL_var) return(ERR_MEM_LACK); if (!dll_add(format->variables)) { ff_destroy_variable(EOL_var); return(ERR_MEM_LACK); } dll_assign(EOL_var, DLL_VAR, dll_last(format->variables)); EOL_var->type = FFV_EOL; EOL_var->start_pos = FORMAT_LENGTH(format) + 1; EOL_var->end_pos = EOL_var->start_pos; format->length = EOL_var->end_pos; EOL_var->precision = 0; format->num_vars++; return(0); }
/* * remove_end_tag * * remove tag from container stack, check for legal nesting, * show up message if necessary. * * params: hp....hsc process * tag...tag to be removed */ VOID remove_end_tag(HSCPRC * hp, HSCTAG * tag) { /* search for tag on stack of occured tags */ DLNODE *nd = find_dlnode_bw(hp->container_stack->last, (APTR) tag->name, cmp_strtag); if (nd == NULL) { /* closing tag not found on stack */ /* ->unmatched closing tag without previous opening tag */ hsc_message(hp, MSG_UNMA_CTAG, "unmatched %C", tag); } else { /* closing tag found on stack */ HSCTAG *end_tag = (HSCTAG *) dln_data(nd); STRPTR foundnm = (STRPTR) end_tag->name; STRPTR lastnm = (STRPTR) dln_data(dll_last(hp->container_stack)); /* check if name of closing tag is -not- equal * to the name of the last tag last on stack * ->illegal tag nesting */ if (upstrcmp(lastnm, foundnm) && !(tag->option | HT_MACRO) && !(is_hsc_tag(tag))) { hsc_message(hp, MSG_CTAG_NESTING, "illegal end tag nesting (expected %c, found %C)", lastnm, tag); } /* if closing tag has any attributes defined, * it must be a closing macto tag. so copy * the attributes of the closing tag to the * attributes of the macro tag. therefor, * the closing macro tag inherits the * attributes of his opening macro */ if (end_tag->attr) { set_local_varlist(tag->attr, end_tag->attr, MCI_APPCTAG); } /* remove node for closing tag from container_stack */ del_dlnode(hp->container_stack, nd); } }
/* * append_output * * append text to output string */ void append_output(STRPTR text) { EXPSTR *outstr = (EXPSTR *) dln_data(dll_last(outlist)); /* check if current output-string will be full */ if ((estrlen(outstr) + strlen(text) + 1) > OUTPUT_STEPSIZE) { /* if so, append a new output-string to the list * and make use this one */ #if DEBUG_HSC_OUTPUT fprintf(stderr, DHSC "new string after %lu/%lu chars\n", estrlen(outstr), OUTPUT_STEPSIZE); #endif outstr = init_estr(OUTPUT_STEPSIZE); app_dlnode(outlist, (APTR) outstr); } app_estr(outstr, text); }
/* * insert bid in descending cost */ void insert_bid(char *msg) { char *p; Bid *b, *tb; int i, id; Dllist ptr; // create a new bid b = (Bid *) malloc(sizeof(Bid)); p = strstr(msg, "B"); p++; b->cost = atoi(p); p = strstr(p, "$"); p++; b->numrobot = atoi(p); b->coalition = new_dllist(); for (i = 0; i < b->numrobot; i++) { p = strstr(p, "$"); p++; id = atoi(p); if (dll_empty(b->coalition)) b->leaderID = id; dll_append(b->coalition, new_jval_i(id)); } printf("insert bid: %s\n", msg); // insert the bid to bidList, increasing cost if (dll_empty(bidList)) { dll_append(bidList, new_jval_v(b)); } else { dll_traverse(ptr, bidList) { tb = (Bid *) jval_v(dll_val(ptr)); if (tb->cost > b->cost) { dll_insert_b(ptr, new_jval_v(b)); break; } if (ptr == dll_last(bidList)) {// append it to the last dll_append(bidList, new_jval_v(b)); break; } } }
/* * find_end_container * * search container stack for the first macro which is a * container macro anjd return the cerresponding tag structure */ HSCTAG *find_end_container_macro(HSCPRC * hp) { HSCTAG *tag = NULL; DLNODE *nd = dll_last(hp->container_stack); while (nd) { HSCTAG *nd_tag = (HSCTAG *) dln_data(nd); if (nd_tag->option & HT_CONTENT) { tag = nd_tag; nd = NULL; } else { nd = dln_prev(nd); } } return tag; }
/* * args_ok * * prepare args, check & parse user args, display error and * help message if neccessary * * result: TRUE, if all args ok */ BOOL args_ok(HSCPRC * hp, int argc, char *argv[]) { BOOL ok; /* return value */ DLLIST *ignore_list = NULL; /* dummy */ EXPSTR *destdir = init_estr(32); /* destination dir */ EXPSTR *rel_destdir = init_estr(32); /* relative destination dir */ EXPSTR *kack_name = init_estr(0); /* temp. str for outfilename */ struct arglist *hsc_args; /* argument structure */ arg_hp = hp; arg_mode_CB(DEFAULT_MODE_STR); /* create arg-table */ hsc_args = prepare_args("HSC_ARGS", /* file args */ "FROM/M", &incfile, "include- and input-file(s)", "TO/K", &arg_outfname, "output file (default: stdout)", "PRJFILE/T/K", &prjfilename, "project file (default: none)", "PREFSFILE/T/K", &prefsfilename, "syntax preferences (default: hsc.prefs)", "MSGFILE=MF/T/K", &msgfilename, "message file (default: stderr)", "MSGFORMAT/T/K", &msg_format, "how to display message", /* numeric */ "MAXERR/N/K", &max_error, "max. number of errors (default: 20)", "EXTENSION/T/K", &arg_extension, "output-file-extension (default: " DEFAULT_EXTENSION ")", "DEFINE=DEF/T/K/M", &define_list, "define global attribute", "IGNORE=IGN/N/K/M/$", arg_ignore_CB, &ignore_list, "ignore message number", "MODE/E/K/$", arg_mode_CB, MODE_ENUMSTR, &arg_mode, "mode for syntax check (" MODE_ENUMSTR ")", "QUOTESTYLE=QS/E/K", QMODE_ENUMSTR, &arg_quotemode, "defines how quotes appear (" QMODE_ENUMSTR ")", #if 0 "ENTITYSTYLE=ES/E/K", EMODE_ENUMSTR, &entmode, "defines how special chars. appear (" EMODE_ENUMSTR ")", /* switches */ #endif "COMPACT=CO/S", &arg_compact, "strip useless LFs and white-spaces", "GETSIZE/S", &arg_getsize, "get width and height of images", "MSGANSI/S", &msg_ansi, "use ansi-sequences in messages", "RPLCENT=RE/S", &arg_rplc_ent, "replace special characters", "RPLCQUOTE=RQ/S", &arg_rplc_quote, "replace quotes in text by `"'", "SMARTENT=SA/S", &arg_smart_ent, "replace special entities (`&<>\"')", "JENS/S", &arg_jens, "don't try this at home", "STRIPCOMMENT=SC/S", &arg_strip_cmt, "strip SGML-comments", "STRIPEXTERNAL=SX/S", &arg_strip_ext, "strip tags with external URIs", "STRIPTAGS=ST/K", &arg_striptags, "tags to be stripped", "ICONBASE/T/K", &arg_iconbase, "base-uri for icon-entities", "STATUS/E/K/$", arg_status_CB, STATUS_ENUM_STR, &disp_status, "status message (" STATUS_ENUM_STR ")", "-DEBUG/S", &arg_debug, "enable debugging output", /* help */ "HELP=?/S", &arg_help, "display this text", "LICENSE/S", &arg_license, "display license", NULL); /* remove dummy list TODO: this sucks */ del_dllist(ignore_list); ok = (hsc_args != NULL); /* set & test args */ if (ok) { BOOL use_stdout = FALSE; /* flag: use stdout as output-file */ ok = set_args(argc, argv, hsc_args); /* display help, if requested vie HELP switch, or no * input to pipe or read is passed */ ok &= (!arg_help && (arg_pipe_in || (incfile && dll_first(incfile)))); if (arg_license) { /* display license text */ fprintf_prginfo(stderr); show_license(); set_return_code(RC_WARN); } else if (!ok) { /* display help, if error in args or HELP-switch set */ fprintf_prginfo(stderr); fprintf_arghelp(stderr, hsc_args); set_return_code(RC_WARN); } else { BOOL fnsux = FALSE; /* flag: TRUE = can't evaluate out-filename */ /* set debugging switch */ hsc_set_debug(hp, arg_debug); /* autoset depending options */ if (hsc_get_debug(hp)) disp_status = STATUS_VERBOSE; /* set default options */ if (!arg_extension) arg_extension = DEFAULT_EXTENSION; /* disable ID-warning if no project-file */ if (!prjfilename) hsc_set_msg_ignore(hp, MSG_NO_DOCENTRY, TRUE); /* compute name of input file */ arg_inpfname = NULL; if (dll_first(incfile) && !arg_pipe_in) { /* use last FROM as input file */ arg_inpfname = dln_data(dll_last(incfile)); set_estr(inpfilename, arg_inpfname); /* get path part of inputfilename as relative * destination directory */ get_fpath(rel_destdir, arg_inpfname); /* TODO: set reldir when including first file */ /* TODO: find out why the above TODO is there */ /* remove input filename from incfile */ del_dlnode(incfile, dll_last(incfile)); D(fprintf(stderr, DHSC "input : use `%s'\n" DHSC "reldir: use `%s'\n", estr2str(inpfilename), estr2str(rel_destdir))); } /* display include files */ D( { DLNODE * nd = dll_first(incfile); while (nd) { fprintf(stderr, DHSC "includ: use `%s'\n", ( STRPTR) dln_data(nd)); nd = dln_next(nd); } } ); /* * if no output-filename given, * outfilename stays NULL. this let open_output * open stdout as output-file */ if (arg_outfname) { /* check, if last char of outputfilename is a * directory separator; if so, use the filename * as destination directory */ if (arg_outfname) { UBYTE lastch = 0; /* get last char of outfname to determine * if it's a directory */ if (strlen(arg_outfname)) lastch = arg_outfname[strlen(arg_outfname) - 1]; #ifdef AMIGA /* for Amiga, execpt empty string for current dir */ if (!lastch) { lastch = (PATH_SEPARATOR[0]); D(fprintf(stderr, DHSC "AMIGA: use current dir\n")); } #endif if (strchr(PATH_SEPARATOR, lastch)) { /* use outfilename as destdir */ set_estr(destdir, arg_outfname); arg_outfname = NULL; D(fprintf(stderr, DHSC "output: use `%s' as destdir\n", estr2str(destdir))); } else if (arg_inpfname) { /* output-filename already specified */ /* separate it to destdir + reldir + name */ EXPSTR *kack_destdir = init_estr(0); EXPSTR *kack_reldir = init_estr(0); STRPTR inp_reldir = estr2str(rel_destdir); STRPTR out_reldir = NULL; STRPTR ou2_reldir = NULL; get_fname(kack_name, arg_outfname); get_fpath(kack_destdir, arg_outfname); /* check corresponding dirs for * consistency: check if last strlen(rel_destdir) * chars are equal */ out_reldir = estr2str(kack_destdir); ou2_reldir = out_reldir; out_reldir = out_reldir + (strlen(out_reldir) - strlen(inp_reldir)); if (out_reldir[0]) { /* search for next dir-sparator backwards */ /* (this ones only needed for a smart error message) */ while ((out_reldir != ou2_reldir) && (!strchr(PATH_SEPARATOR, out_reldir[0])) ) { out_reldir--; } out_reldir++; } D(fprintf(stderr, DHSC "corr_inp: `%s'\n" DHSC "corr_out: `%s'\n", inp_reldir, out_reldir) ); /* check if correspondig relative in/out-dirs * are equal */ if (!fnamecmp(inp_reldir, out_reldir)) { /* they match.. */ STRPTR tmp_name = NULL; /* copy of kack_nam */ /* cut corresponding chars */ get_left_estr(kack_destdir, kack_destdir, estrlen(kack_destdir) - strlen(out_reldir)); set_estr(kack_reldir, inp_reldir); D(fprintf(stderr, DHSC "kack_dst: `%s'\n" DHSC "kack_rel: `%s'\n" DHSC "kack_nam: `%s'\n", estr2str(kack_destdir), estr2str(kack_reldir), estr2str(kack_name)) ); /* just copy these values where they are * expected to be */ estrcpy(destdir, kack_destdir); estrcpy(rel_destdir, kack_reldir); /* create output filename */ tmp_name = strclone(estr2str(kack_name)); estrcpy(kack_name, kack_destdir); estrcat(kack_name, kack_reldir); app_estr(kack_name, tmp_name); ufreestr(tmp_name); arg_outfname = estr2str(kack_name); } else { /* unmatched corresponding dirs */ fprintf(stderr, "unmatched corresponding relative directories:\n" " input `%s'\n output `%s'\n", inp_reldir, out_reldir); ok = FALSE; } /* free temp. vars */ del_estr(kack_reldir); del_estr(kack_destdir); } } if (arg_outfname) { /* set outputfilename with value passed iwithin args */ outfilename = init_estr(32); set_estr(outfilename, arg_outfname); D(fprintf(stderr, DHSC "output: set to `%s'\n", estr2str(outfilename))); } else { if (!arg_pipe_in) { /* no outfilename given */ /* ->outfilename = destdir + inpfilename + ".html" */ /* link destdir & input filename */ outfilename = init_estr(32); link_fname(outfilename, estr2str(destdir), arg_inpfname); if (strcmp(arg_extension, ".")) set_fext(outfilename, arg_extension); D(fprintf(stderr, DHSC "output: concat destdir+inpfile+`.%s'\n" DHSC "output: set to `%s'\n", arg_extension, estr2str(outfilename))); } else fnsux = TRUE; } if (fnsux) { /* no way to find out output filename */ status_error("unable to evaluate output filename\n"); arg_outfname = NULL; ok = FALSE; } } else { D(fprintf(stderr, DHSC "output: use stdout\n")); use_stdout = TRUE; } if (!ok) set_return_code(RC_ERROR); } if (ok) { if (arg_iconbase) hsc_set_iconbase(hp, arg_iconbase); if (!use_stdout) hsc_set_filename_document(hp, estr2str(outfilename)); } /* display argument error message */ if (!ok) { /* NOTE: no strclone() is used on outfilename, if an * error already occured within set_args(). therefore, * you must not call ufreestr( outfilename ) */ pargerr(); arg_outfname = NULL; set_return_code(RC_ERROR); } else { EXPSTR *tmp_fname = init_estr(32); /* filename only part */ fileattr_str = init_estr(64); if (outfilename) get_fname(tmp_fname, estr2str(outfilename)); set_dest_attribs(hp, estr2str(rel_destdir), estr2str(tmp_fname)); if (!arg_pipe_in) { if (outfilename) get_fname(tmp_fname, estr2str(outfilename)); else clr_estr(tmp_fname); set_source_attribs(hp, estr2str(rel_destdir), estr2str(tmp_fname)); } else set_source_attribs(hp, NULL, NULL); D( { HSCMSG_ID i; fprintf(stderr, "\n" DHSC "input : `%s'\n", estr2str(inpfilename)); fprintf(stderr, DHSC "output: `%s'\n", get_outfilename()); fprintf(stderr, DHSC "destdr: `%s'\n", estr2str(destdir)); fprintf(stderr, DHSC "reldst: `%s'\n", estr2str(rel_destdir)); if (prjfilename) fprintf(stderr, DHSC "projct: `%s'\n", prjfilename); if (!use_stdout) fprintf(stderr, DHSC "procss: `%s'\n", estr2str(outfilename)); fprintf(stderr, DHSC "ignore:"); for (i = 0; i < MAX_MSGID; i++) if (hsc_get_msg_ignore(hp, i)) fprintf(stderr, " %lu", i); fprintf(stderr, "\n"); } ); del_estr(tmp_fname); }
void PfEvict(MMUSim* sim){ Dllist freeFrames; Dllist usedFrames; freeFrames = sim->freePhysicalFrames; usedFrames = sim->usedPhysicalFrames; Dllist uNil; uNil = dll_nil(usedFrames); Dllist uFrame; uFrame = dll_first(usedFrames); int rep = sim->rep; PhysicalFrame* evictFrame; if(rep == 1){ // FIFO/////////////////////////////// // nothing is needed, FIFO happens automatically evictFrame = uFrame->val.v; }//////////////////////////END FIFO///////////////// else if(rep == 2){ // LRU/////////////////////////// PhysicalFrame* oldFrame; unsigned int oldTime = UINT_MAX; PhysicalFrame* frameArray; frameArray = sim->physicalFrames; PhysicalFrame* currentFrame; int i; for (i = 0; i < sim->numFrames; i++){ currentFrame = &frameArray[i]; if(currentFrame->lastUsed < oldTime){ oldFrame = currentFrame; oldTime = currentFrame->lastUsed; } } evictFrame = oldFrame; Dllist* ref; ref = evictFrame->listRef; uFrame = *ref; } ////////////////////END LRU////////////////////// else if(rep == 3){ // LFU//////////////////////// PhysicalFrame* oldFrame; int oldUse = INT_MAX; PhysicalFrame* frameArray; frameArray = sim->physicalFrames; PhysicalFrame* currentFrame; int i; for (i = 0; i < sim->numFrames; i++){ currentFrame = &frameArray[i]; if(currentFrame->useCount < oldUse){ oldFrame = currentFrame; oldUse = currentFrame->useCount; } } evictFrame = oldFrame; Dllist* ref; ref = evictFrame->listRef; uFrame = *ref; } /////////////////////END LFU////////////////////// else if(rep == 4){ // MFU///////////////////////// evictFrame = sim->mfuFrame; Dllist* ref; ref = evictFrame->listRef; uFrame = *ref; } ////////////////////END MFU////////////////////// else{ // RANDOM/////////////////////////////////// int max = sim->numFrames - 1; int randomIndex = ((double) rand() / (((double)RAND_MAX)+1)) * (max+1); PhysicalFrame* frameArray; frameArray = sim->physicalFrames; PhysicalFrame* randomFrame; randomFrame = &frameArray[randomIndex]; evictFrame = randomFrame; Dllist* randomRef; randomRef = evictFrame->listRef; uFrame = *randomRef; }///////////////// END RANDOM//////////////////// dll_delete_node(uFrame); dll_append(freeFrames, new_jval_v(evictFrame)); Dllist listItem = dll_last(sim->freePhysicalFrames); evictFrame->listRef = listItem; }
void setupSim(Config* conf, MMUSim* sim){ // Page Bits int physSize = conf->pms; int frameSize = conf->frame; long addressSpaceSize = pow(2,32); int pages = addressSpaceSize / frameSize; int pageBits = log10(pages)/log10(2); printf("Page bits: %d\n", pageBits); sim->pageBits = pageBits; // Page offset int offsetBits = 32 - pageBits; printf("Offset bits: %d\n", offsetBits); sim->offsetBits = offsetBits; // TLB Size int tlbSize = conf->tlbSz; printf("TLB size: %d\n", tlbSize); sim->tlbSz = tlbSize; // TLB Latency int tlbLatency = conf->tlbLat; float tlbLatInMs = tlbLatency * pow(10, -6); printf("TLB latency (milliseconds): %f\n", tlbLatInMs); sim->tlbLat = tlbLatInMs; // Physical Memory Size printf("Physical memory (bytes): %d\n", physSize); sim->physMemSz = physSize; // Physical Frame Size printf("Physical frame size (bytes): %d\n", frameSize); sim->physFrameSz = frameSize; // Number of Physical Frames int numFrames = ceil(((float) physSize) / ((float)frameSize)); printf("Number of physical frames: %d\n", numFrames); sim->numFrames = numFrames; // Memory Latency int memLatency = conf->memLat; float memLatInMs = memLatency * pow(10, -6); printf("Memory latency (milliseconds): %f\n", memLatInMs); sim->memLat = memLatInMs; // Page Table Entries int pageTableEntries = pow(2, 32 - offsetBits); printf("Number of page table entries: %d\n", pageTableEntries); sim->pageEntries = pageTableEntries; // Page Table Replacement Strategy int rep = conf->rep; printf("Page replacement strategy: "); if(rep == 1) {printf("FIFO");} else if(rep == 2) {printf("LRU");} else if(rep == 3) {printf("LFU");} else if(rep == 4) {printf("MFU");} else if(rep == 5) {printf("RANDOM");} printf("\n"); sim->rep = rep; // Disk latency int diskLat = conf->diskLat; printf("Disk latency (milliseconds): %d\n", diskLat); sim->diskLat = diskLat; // Logging int logging = conf->log; printf("Logging: "); if(logging == 0) {printf("off");} else if(logging == 1) {printf("on");} printf("\n\n"); sim->log = logging; // Setup process list sim->processes = new_dllist(); // Setup TLB and Page table TLB* tlb = malloc(sizeof(TLB)); TLB_Entry* tlbArray = malloc(sim->tlbSz * sizeof(TLB_Entry)); tlb->cache = tlbArray; tlb->size = sim->tlbSz; sim->tlb = tlb; // Setup phyiscal frames sim->frameTree = make_jrb(); sim->usedPhysicalFrames = new_dllist(); sim->freePhysicalFrames = new_dllist(); int frameCount = sim->numFrames; sim->physicalFrames = malloc(sizeof(PhysicalFrame) * frameCount); int i; for (i = 0; i < frameCount; i++){ PhysicalFrame* pf = &sim->physicalFrames[i]; pf->num = i; dll_append(sim->freePhysicalFrames, new_jval_v(pf)); Dllist listItem = dll_last(sim->freePhysicalFrames); pf->listRef = listItem; } }
/* * hsc_parse_tag * * parse tag (after "<") */ BOOL hsc_parse_tag(HSCPRC * hp) { INFILE *inpf = hp->inpf; STRPTR nxtwd = NULL; DLNODE *nd = NULL; HSCTAG *tag = NULL; HSCTAG *now_tag_strip_whtspc = NULL; ULONG tci = 0; /* tag_call_id returned by set_tag_args() */ BOOL(*hnd) (HSCPRC * hp, HSCTAG * tag) = NULL; BOOL open_tag; DLLIST *taglist = hp->deftag; BOOL rplc_lt = FALSE; /* TRUE, if replace spc. char "<" */ BOOL hnd_result = TRUE; /* result returned by handle */ BOOL unknown_tag = FALSE; /* TRUE, if tag has not been defined before */ BOOL preceeding_whtspc = estrlen(hp->whtspc); /* init strings used inside tag-handles */ set_estr(hp->tag_name_str, infgetcw(inpf)); clr_estr(hp->tag_attr_str); clr_estr(hp->tag_close_str); if (hp->smart_ent && preceeding_whtspc) { /* * check for special char "<" */ int ch = infgetc(inpf); /* check if next char is a white space */ if (hsc_whtspc(ch)) { rplc_lt = TRUE; /* write "<" and white spaces */ message_rplc(hp, "<", "<"); hsc_output_text(hp, "", "<"); } inungetc(ch, inpf); } if (!rplc_lt) { /* get tag id */ nxtwd = infget_tagid(hp); if (!hp->fatal) { /* append tag-name to tag_name_str */ if (!hp->compact) { app_estr(hp->tag_name_str, infgetcws(inpf)); } app_estr(hp->tag_name_str, infgetcw(inpf)); if (!hp->suppress_output) { /* output tag currently processing * NOTE: the first tag of the source is skipped because * hp->supress_ouptut is disable later */ D(fprintf(stderr, DHL "tag <")); } } } if (!hp->fatal && !rplc_lt) { BOOL write_tag = FALSE; /* flag: write tag text & attrs to output? */ if (strcmp("/", nxtwd)) /* is it a closing tag? */ { /* * * process start-tag * */ open_tag = TRUE; if (!hp->suppress_output) { D(fprintf(stderr, "%s>\n", nxtwd)); } /* search for tag in list */ nd = find_dlnode(taglist->first, (APTR) nxtwd, cmp_strtag); if (nd == NULL) { hsc_message(hp, MSG_UNKN_TAG, /* tag not found */ "unknown %t", nxtwd); tag = new_hsctag(nxtwd); tag->option |= HT_UNKNOWN; unknown_tag = TRUE; } else { tag = (HSCTAG *) nd->data; } /* set handle-function */ hnd = tag->o_handle; /* * handle options */ /* check for obsolete tag */ if (tag->option & HT_OBSOLETE) { hsc_message(hp, MSG_TAG_OBSOLETE, "%T is obsolete", tag); } /* check for jerk-tag */ if (tag->option & HT_JERK) { hsc_message(hp, MSG_TAG_JERK, "%T is only used by %j", tag); } /* only-once-tag occured twice? */ if ((tag->option & HT_ONLYONCE) && (tag->occured)) { hsc_message(hp, MSG_TAG_TOO_OFTEN, "%T occured too often", tag); } /* set occured-flag */ if (tag->option & (HT_ONLYONCE | HT_REQUIRED)) { tag->occured = TRUE; } /* check for "must be inside"/"not allowed within"-tags */ if (!check_mbinaw(hp, tag)) { hnd = NULL; } /* clear (reset to default) attribute values of tag */ clr_varlist(tag->attr); /* set attributes or check for ">" */ if (!(tag->option & HT_SPECIAL)) { tci = set_tag_args(hp, tag); if (tci == MCI_ERROR) { skip_until_eot(hp, NULL); hnd = NULL; } if (!hp->fatal) { /* set ">" in string that contains closing text */ if (!hp->compact) { set_estr(hp->tag_close_str, infgetcws(inpf)); } else { clr_estr(hp->tag_close_str); } app_estr(hp->tag_close_str, infgetcw(inpf)); /* check for succeeding white-space */ if ((tag->option & HT_WHTSPC) && !infeof(inpf)) { int ch = infgetc(inpf); if (hsc_whtspc(ch)) { if (hp->strip_badws) { hp->strip_next2_whtspc = TRUE; } else if (!hp->strip_next2_whtspc) { #if 1 now_tag_strip_whtspc = tag; #else /* TODO: remove this */ hsc_message(hp, MSG_SUCC_WHTSPC, "succeeding white-space for %T", tag); #endif } } inungetc(ch, inpf); } } } /* for AUTOCLOSE-tags, remove eventually existing * end tags on stack */ if (tag->option & HT_AUTOCLOSE) { DLNODE *nd = find_end_tag_node(hp, tag->name); if (nd) { if (nd == dll_last(hp->container_stack)) { D(fprintf(stderr, DHL " autoclose </%s> before\n", tag->name)); remove_end_tag(hp, tag); } else { HSCTAG *end_tag = (HSCTAG *) dln_data(dll_last(hp->container_stack)); D(fprintf(stderr, DHL " no autoclose because of <%s> \n", end_tag->name)); } } else { D(fprintf(stderr, DHL " no autoclose neccessary\n")); } } /* end-tag required? */ if ((tag->option & HT_CLOSE) || (tag->option & HT_AUTOCLOSE)) { /* yes: push current tag to container stack; * (current values of attributes will be * remembered */ append_end_tag(hp, tag); } } else { /* * * process end-tag * */ /* get tag id */ nxtwd = infget_tagid(hp); /* get tag id */ open_tag = FALSE; /* append tag-name to tag_name_str */ if (!hp->compact) { app_estr(hp->tag_name_str, infgetcws(inpf)); } app_estr(hp->tag_name_str, infgetcw(inpf)); if (!hp->suppress_output) { D(fprintf(stderr, "/%s>\n", nxtwd)); } /* search for tag in taglist */ /* (see if it exists at all) */ nd = find_dlnode(taglist->first, (APTR) nxtwd, cmp_strtag); if (nd == NULL) { /* closing tag is absolutely unknown */ hsc_message(hp, MSG_UNKN_TAG, /* tag not found */ "unknown %c", nxtwd); skip_until_eot(hp, hp->tag_attr_str); } else { tag = (HSCTAG *) nd->data; /* fitting tag in taglist */ /* check for preceding white-spaces */ if ((tag->option & HT_WHTSPC) && anyWhtspc(hp)) { if (hp->strip_badws) { hp->strip_next_whtspc = TRUE; } else if (!hp->strip_next_whtspc) { hsc_message(hp, MSG_PREC_WHTSPC, "preceding white space for %C", tag); } } if (tag->option & (HT_CLOSE | HT_AUTOCLOSE)) { /* set closing handle */ hnd = tag->c_handle; /* check for no args */ if (!parse_wd(hp, ">")) { hsc_message(hp, MSG_CL_TAG_ARG, "no attributes allowed for end-tags"); } else { /* set ">" in string that contains closing text */ if (!hp->compact) { set_estr(hp->tag_close_str, infgetcws(inpf)); } app_estr(hp->tag_close_str, infgetcw(inpf)); } /* set values of attributes stored * in end-tag, * remove end-tag from stack */ remove_end_tag(hp, tag); } else { /* illegal closing tag */ hsc_message(hp, MSG_ILLG_CTAG, /* tag not found */ "illegal %c", nxtwd); parse_gt(hp); tag = NULL; } } } /* * processed for opening AND closing tag */ write_tag = (!(tag) || !(tag->option & HT_NOCOPY)); if (tag) { /* * check if tag should be stripped */ if (!postprocess_tagattr(hp, tag, open_tag)) { /* stripped tag with external reference */ if (open_tag) { hsc_msg_stripped_tag(hp, tag, "external reference"); } hnd = NULL; /* don't call handle */ write_tag = FALSE; /* don't output tag */ } else if (hp->strip_tags && strenum(tag->name, hp->strip_tags, '|', STEN_NOCASE)) { /* strip tag requested by user */ if (!(tag->option & HT_SPECIAL)) { if (open_tag) { hsc_msg_stripped_tag(hp, tag, "as requested"); } hnd = NULL; /* don't call handle */ write_tag = FALSE; /* don't output tag */ } else { hsc_message(hp, MSG_TAG_CANT_STRIP, "can not strip special tag %T", tag); } /* * get values for size from reference */ } else if (tag->uri_size && get_vartext(tag->uri_size)) get_attr_size(hp, tag); } /* call handle if available */ if (hnd && !hp->fatal) hnd_result = (*hnd) (hp, tag); /* write whole tag out */ if (write_tag && hnd_result) { VOID(*tag_callback) (HSCPRC * hp, HSCTAG * tag, STRPTR tag_name, STRPTR tag_attr, STRPTR tag_close) = NULL; if (open_tag) { tag_callback = hp->CB_start_tag; } else { tag_callback = hp->CB_end_tag; } #if 1 /* TODO: remove conditionals, but leave below code intact */ /* enable output if necessary */ if (hp->suppress_output) { hp_enable_output(hp, "non-internal tag occured"); } #endif /* write (flush) white spaces */ hsc_output_text(hp, "", ""); if (tag_callback) { (*tag_callback) (hp, tag, estr2str(hp->tag_name_str), estr2str(hp->tag_attr_str), estr2str(hp->tag_close_str)); } } /* skip LF if requested */ if (tag && (tag->option & HT_SKIPLF)) { skip_next_lf(hp); /* TODO: really skip single lf */ } /* if tag should check for succeeding white spaces, * tell this hscprc now */ if (now_tag_strip_whtspc) { D(fprintf(stderr, " requested to check for succ.whtspc\n")); hp->tag_next_whtspc = now_tag_strip_whtspc; } /* remove temporary created tag */ if (unknown_tag) { del_hsctag(tag); } #if (defined MSDOS) /* HSC_TRIGGER */ #define UNLIKELY (10*1024) /* crash randomly */ if ((rand() % UNLIKELY) == (UNLIKELY / 2)) { enforcerHit(); } #endif } return (BOOL) (!hp->fatal); }
static int add_to_variable_list(char *text_line, FORMAT_PTR format) { VARIABLE_PTR var = NULL; char save_char = STR_END; char *token = NULL; char *endptr = NULL; int error = 0; if (!format->variables) { format->variables = dll_init(); if (!format->variables) return(ERR_MEM_LACK); } token = text_line; token = get_token(token, &save_char); if (FF_STRLEN(token)) { var = ff_create_variable(token); if (var == NULL) return ERR_MEM_LACK; #if 0 error = ERR_MEM_LACK; #endif if (var->name[0] == '"' && var->name[strlen(var->name) - 1] == '"') { memmove(var->name, var->name + 1, strlen(var->name) - 2); var->name[strlen(var->name) - 2] = STR_END; } } else { error = err_push(ERR_VARIABLE_DESC, "Expecting a variable name (\"%s\")", format->name); goto add_to_variable_list_exit; } if (!dll_add(format->variables)) { ff_destroy_variable(var); error = ERR_MEM_LACK; goto add_to_variable_list_exit; } dll_assign(var, DLL_VAR, dll_last(format->variables)); token = get_token(token, &save_char); if (FF_STRLEN(token)) { errno = 0; var->start_pos = strtol(token, &endptr, 10); if (errno || FF_STRLEN(endptr)) { error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable start position: %s", token); goto add_to_variable_list_exit; } } else { error = err_push(ERR_VARIABLE_DESC, "Expecting a start position for \"%s\"", var->name); goto add_to_variable_list_exit; } token = get_token(token, &save_char); if (FF_STRLEN(token)) { errno = 0; var->end_pos = strtol(token, &endptr, 10); if (errno || FF_STRLEN(endptr)) { error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable end position: %s", token); goto add_to_variable_list_exit; } } else { error = err_push(ERR_VARIABLE_DESC, "Expecting an end position for \"%s\"", var->name); goto add_to_variable_list_exit; } token = get_token(token, &save_char); if (FF_STRLEN(token)) { FFV_TYPE(var) = ff_lookup_number(variable_types, token); if (FFV_TYPE(var) == FF_VAR_TYPE_FLAG) { if (os_strncmpi("ARRAY", token, 5) == 0) { RESTORE_CHAR(token, save_char); save_char = STR_END; error = parse_array_variable(&token, var); if (error) goto add_to_variable_list_exit; format->type |= FF_ARRAY; } else { /* Is this a keyworded variable type? If so, remember name of keyword in record_title */ if (IS_KEYWORDED_PARAMETER(token)) { FFV_TYPE(var) = 0; assert(!var->record_title); if (var->record_title) memFree(var->record_title, "var->record_title"); var->record_title = (char *)memStrdup(token, "token"); if (!var->record_title) { error = err_push(ERR_MEM_LACK, ""); goto add_to_variable_list_exit; } } else { error = err_push(ERR_UNKNOWN_VAR_TYPE, token); goto add_to_variable_list_exit; } } } } else { error = err_push(ERR_VARIABLE_DESC, "Expecting a variable type or array description for \"%s\"", var->name); goto add_to_variable_list_exit; } token = get_token(token, &save_char); if (FF_STRLEN(token)) { errno = 0; var->precision = (short)strtol(token, &endptr, 10); if (errno || FF_STRLEN(endptr)) { error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable precision: %s", token); goto add_to_variable_list_exit; } } else { if (IS_ARRAY(var)) { error = err_push(ERR_VARIABLE_DESC, "Expecting a precision for \"%s\"", var->name); goto add_to_variable_list_exit; } } if (var->end_pos < var->start_pos) { error = err_push(ERR_VARIABLE_DESC,"End Position < Start Position\n%s", text_line); goto add_to_variable_list_exit; } /* Determine The Variable Type */ if (var->start_pos == 0 && var->end_pos == 0) { if (IS_BINARY(format)) { error = err_push(ERR_UNKNOWN_FORMAT_TYPE, "Illegal to have delimited binary format"); goto add_to_variable_list_exit; } else if (IS_ARRAY(format)) { error = err_push(ERR_UNKNOWN_FORMAT_TYPE, "Illegal to have delimited array format"); goto add_to_variable_list_exit; } format->type |= FFF_VARIED; } if (NEED_TO_CHECK_VARIABLE_SIZE(format, var)) { if (ffv_type_size(var->type) != var->end_pos - var->start_pos + 1) { char save_eol_char = STR_END; char *end_of_line = find_EOL(text_line); if (end_of_line) { save_eol_char = *end_of_line; *end_of_line = STR_END; } error = err_push(ERR_VARIABLE_SIZE,"Expecting ending position for binary field %s to be %d", var->name, var->start_pos + ffv_type_size(var->type) - 1); if (end_of_line) *end_of_line = save_eol_char; goto add_to_variable_list_exit; } } check_old_style_EOL_var(var); /* Does length of CONSTANT variable name equal length of variable? */ if (IS_CONSTANT(var) && !IS_EOL(var)) { if (FF_STRLEN(var->name) > FF_VAR_LENGTH(var)) { error = err_push(ERR_VARIABLE_SIZE, "Constant variable initializer (%s) is too long for field", var->name); goto add_to_variable_list_exit; } else if (FF_STRLEN(var->name) < FF_VAR_LENGTH(var)) error = err_push(ERR_WARNING_ONLY + ERR_VARIABLE_SIZE, "Constant variable initializer (%s) is shorter than field", var->name); } format->num_vars++; format->length = max(format->length, var->end_pos); add_to_variable_list_exit: if (error) { char *cp; char EOL_char = STR_END; /* Don't destroy variable since it will be destroyed in ff_destroy_format */ cp = find_EOL(text_line); if (cp) { EOL_char = *cp; *cp = STR_END; } error = err_push(ERR_VARIABLE_DESC + (error > ERR_WARNING_ONLY ? ERR_WARNING_ONLY : 0),text_line); if (cp) *cp = EOL_char; } RESTORE_CHAR(token, save_char); return(error); }