/* * gettimestr */ static EXPSTR *gettimestr(HSCPRC * hp, const struct tm *time) { #define TIMEBUF_INC 20 STRPTR timefmt = get_vartext_byname(hp->defattr, TIMEFORMAT_ATTR); EXPSTR *timebuf = init_estr(TIMEBUF_INC); BOOL strftrc = 0; /* result of strftime() */ size_t i; /* loop var */ /* set default time format */ if (!timefmt) timefmt = "%d-%b-%Y, %H:%M"; while (!(hp->fatal) && !strftrc) { /* expand timebuffer */ for (i = 0; i < TIMEBUF_INC; i++) app_estrch(timebuf, '.'); D(fprintf(stderr, DHL " timebuf: inc+%d\n", TIMEBUF_INC)); /* output time */ strftrc = strftime(estr2str(timebuf), estrlen(timebuf), timefmt, time); } if (!strftrc) { del_estr(timebuf); timebuf = NULL; } return (timebuf); }
carray<char> *cstring::explode (const char *string, const char *dividers, int limit) { carray<char> *result; char *singleton = NULL, *pointers[2] = {NULL, NULL}, *characters = (char *)dividers; size_t segments = 0, length; length = estrlen(string); pointers[0] = (char *)string; if ((result = enew carray<char>)) { while ((pointers[1] = cstring::nearchar(pointers[0], characters))) { if ((pointers[1]-pointers[0]) > 0) { if ((singleton = (char *) emalloc((pointers[1]-pointers[0])+1))) { strncpy(singleton, pointers[0], (pointers[1]-pointers[0])); singleton[(pointers[1]-pointers[0])] = '\0'; if (!result->add(singleton)) break; } else ekill("out of memory"); } if ((pointers[1]-string) < length) { pointers[0] = (pointers[1]+1); if ((limit >= 0) && (limit <= (++segments))) characters = NULL; } else break; } } else ekill("out of memory"); return result; }
/* ** handle_hsc_time ** ** insert current time */ BOOL handle_hsc_time( INFILE *inpf, HSCTAG *tag ) { STRPTR timefmt = get_vartext( tag->attr, "FORMAT" ); EXPSTR *timebuf = init_estr( TIMEBUF_INC ); BOOL strftrc = 0; /* result of strftime() */ size_t i; /* loop var */ /* set default time format */ if ( !timefmt ) timefmt = "%d-%b-%Y, %H:%M"; while ( !fatal_error && !strftrc ) { /* expand timebuffer */ for ( i=0; i<TIMEBUF_INC; i++ ) if ( !app_estrch( timebuf, '.' ) ) err_mem( inpf ); D( fprintf( stderr, "** timebuf: inc+%d\n", TIMEBUF_INC ) ); /* output time */ strftrc = strftime( estr2str( timebuf ), estrlen( timebuf ), timefmt, localtime(&now) ); } if ( strftrc ) include_hsc_string( "[insert TIME]", estr2str( timebuf ), outfile, IH_PARSE_HSC ); del_estr( timebuf ); return (TRUE); }
/* * 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); }
int cstring::defrag (const char *string, const char *dividers, const char *format, ...) { va_list arguments; char integer[EE_DIGITS_SIZE], *pointer = NULL, **stringbackup = NULL; unsigned int index, args = 0; int *valuebackup = NULL, result = EE_OK; size_t length; va_start(arguments, format); { length = estrlen(format); for (index = 0; index < length; index++) { if ((pointer = cstring::nearchar(string, dividers))) { switch(format[index]) { case 's': case 'S': stringbackup = va_arg(arguments, char**); if ((*stringbackup = (char *) emalloc((pointer-string)+1))) memcpy(*stringbackup, string, pointer-string); else ekill("out of memory"); break; case 'd': case 'D': valuebackup = va_arg(arguments, int*); memcpy(integer, string, pointer-string); integer[pointer-string] = '\0'; *valuebackup = atoi(integer); break; default: result = EE_ERROR; } } else result = EE_ERROR; if (!result) break; args++; if ((*pointer != '\0') && (*pointer != '\n')) string = (pointer+1); else break; } }
/* * hsc_include * * read from inpf, parse for hsc-commands and execute them, * check for html-error, * write all out to outf and close input file. * * params: inpfnm...input file name * outf.....output file structure, already opended * * result: TRUE, if all worked well, else FALSE */ static BOOL hsc_include(HSCPRC * hp, INFILE * inpf, ULONG optn, INFILEPOS * base_pos) { BOOL ok; /* result */ ok = (inpf != NULL); if (optn & IH_POS_PARENT) { panic("IH_POS_PARENT set"); } if (inpf) /* file opened? */ { #if (defined MSDOS) /* HSC_YOUR */ /* check input > 32K */ if (estrlen(inpf->lnbuf) > (32*1024)) { fprintf(stderr, "** input file too huge\n"); exit(RC_FAIL); } #endif /* push current input file on input-file-stack */ if (hp->inpf) { ins_dlnode(hp->inpf_stack, hp->inpf_stack->first, (APTR) hp->inpf); } /* set new base position for input-file */ /* (if called from a macro or after eg. <$source>) */ if (base_pos) { set_infile_base(inpf, base_pos); } /* assign new input file to hsc-process */ hp->inpf = inpf; /* hide status? */ if ((optn & IH_PARSE_MACRO) || (optn & IH_PARSE_MACRO)) { optn |= IH_NO_STATUS; } /* set char-parse methods */ inpf->is_nc = hsc_normch; /* set is_nc-methode */ inpf->is_ws = hsc_whtspc; /* set is_ws-methode */ /* status message: reading new file */ if (!(optn & IH_NO_STATUS) && !infeof(inpf)) { hsc_status_file_begin(hp, infget_fname(hp->inpf)); } /* parse file */ while (!infeof(inpf) && ok) { if (!(optn & IH_NO_STATUS) && (hp->prev_status_line != infget_y(hp->inpf)) ) { /* status message */ hsc_status_line(hp); hp->prev_status_line = infget_y(hp->inpf); } /* parse next item */ if (optn & IH_PARSE_SOURCE) { ok = hsc_parse_source(hp); } else { ok = hsc_parse(hp); } } /* parse at end: check for missing tags, .. */ if (ok && (optn & IH_PARSE_END)) { /* parse end (unclosed tags etc) */ ok = hsc_parse_end(hp); if (ok && (optn & IH_UPDATE_PRJ)) { /* update project file */ ok = hsc_parse_end_id(hp); } } /* end of file status */ if (!(optn & IH_NO_STATUS)) { /* status message: file processed */ hsc_status_file_end(hp); } /* close file */ infclose(hp->inpf); /* pull previous input file from input-file-stack * or end hsc-process */ if (hp->inpf_stack->first) { /* pull first item from stack */ hp->inpf = (INFILE *) hp->inpf_stack->first->data; hp->inpf_stack->first->data = NULL; del_dlnode(hp->inpf_stack, hp->inpf_stack->first); } else { hp->inpf = NULL; } } else { panic("no input file"); } return (ok); }
/* * hsc_parse_text */ BOOL hsc_parse_text(HSCPRC * hp) { INFILE *inpf = hp->inpf; STRPTR nw = infgetcw(inpf); if (nw && hp->suppress_output) hp_enable_output(hp, "some text"); if (nw) { /* do test below only if not end-of-file */ /* * check unmatched ">" */ if (!strcmp(nw, ">")) { BOOL rplc = hp->smart_ent; /* TRUE, if ">" should be replaced */ if (rplc) { /* * test if char before and * after ">" is white-space */ int ch = infgetc(inpf); inungetc(ch, inpf); if (!(hsc_whtspc(ch) && estrlen(hp->whtspc))) { rplc = FALSE; } } if (rplc) { /* replace gt */ message_rplc(hp, nw, ">"); nw = ">"; } else { hsc_message(hp, MSG_UNMA_GT, "unmatched %q", ">"); } } /* * check for quote */ else if (!strcmp(nw, "\"")) { if (hp->rplc_quote) { /* replace quote */ message_rplc(hp, nw, """); nw = """; } } /* * check for entities to replace */ else { DLNODE *nd = NULL; /* entity search result */ if (hp->rplc_ent && (strlen(nw) == 1) && (nw[0] >= 127)) { nd = find_dlnode(hp->defent->first, (APTR) nw, cmp_rplcent); if (nd) { BOOL ok = TRUE; /* copy replaced entity to buffer */ ok &= set_estr(hp->tmpstr, "&"); ok &= app_estr(hp->tmpstr, ((HSCENT *) nd->data)->name); ok &= app_estr(hp->tmpstr, ";"); if (ok) { /* replace-message */ message_rplc(hp, nw, estr2str(hp->tmpstr)); nw = estr2str(hp->tmpstr); } } } /* * check for "click here" syndrome */ if (hp->inside_anchor && hp->click_here_str) { ULONG found = strenum(nw, hp->click_here_str, '|', STEN_NOCASE); if (found) { hsc_message(hp, MSG_CLICK_HERE, "%q-syndrome detected", "click here"); } } #if (defined MSDOS & (!defined HSC_PLEASE)) /* replace certain keywords */ if (!upstrcmp(nw, "Netscape")) { nw = "Nutscape"; } else if (!upstrcmp(nw, "Microsoft")) { nw = "Mircosoft"; } else if (!upstrcmp(nw, "Intel")) { nw = "Wintel"; } /* to be continued.. */ #endif } } if (nw) hsc_output_text(hp, "", nw); /* output word */ return (BOOL) (!hp->fatal); }
/* * hsc_parse_amp * * parse ampersand ("&") */ BOOL hsc_parse_amp(HSCPRC * hp) { INFILE *inpf = hp->inpf; EXPSTR *amp_str = init_estr(0); if (!hp->fatal) { BOOL rplc = hp->smart_ent; /* TRUE, if "&" should be replaced */ hp_enable_output(hp, "entity"); if (rplc) { /* * test if char before and * after ">" is white-space */ int ch = infgetc(inpf); inungetc(ch, inpf); if (!(hsc_whtspc(ch) && estrlen(hp->whtspc))) rplc = FALSE; } if (rplc) { /* replace ampersand */ message_rplc(hp, "&", "&"); set_estr(amp_str, "&"); } else { /* * get entity-id, test for unknown entity */ char *nxtwd; DLNODE *nd; BOOL app_entity = TRUE; /* remember "&" */ set_estr(amp_str, infgetcw(inpf)); /* get entity id */ nxtwd = infgetw(inpf); /* TODO: check for white-space */ if (!strcmp(nxtwd, "#")) { /* * process numeric entity */ /* append "#" */ app_estr(amp_str, infgetcw(inpf)); nxtwd = infgetw(inpf); errno = 0; strtoul(nxtwd, NULL, 0); if (errno || strlen(infgetcws(inpf))) { hsc_message(hp, MSG_ILLG_NUM, /* illegal numeric entity */ "illegal numeric value %n for entity", nxtwd); } /* append entity specifier */ app_estr(amp_str, nxtwd); } else { /* * process text entity */ HSCVAR *attr = NULL; /* search for entity in list */ nd = find_dlnode(hp->defent->first, (APTR) nxtwd, cmp_strent); if (hp->jens && (nd == NULL)) { /* asume that entity is an attribute, * try to find it and append it's value */ attr = find_varname(hp->defattr, nxtwd); if (attr) { set_estr(amp_str, get_vartext(attr)); app_entity = FALSE; } } if ((nd == NULL) && (attr == NULL)) { hsc_message(hp, MSG_UNKN_ENTITY, "unknown %e", nxtwd); } else { /* check for icon-entity and warn about */ /* portability peoblem */ HSCENT *entity = dln_data(nd); if (entity->numeric == ICON_ENTITY) if (estrlen(hp->iconbase)) { replace_icon(hp, nxtwd); set_estr(amp_str, ""); app_entity = FALSE; } else { hsc_message(hp, MSG_ICON_ENTITY, "icon %e found", nxtwd); } } if (app_entity) /* append entity specifier */ app_estr(amp_str, nxtwd); } /* TODO: check for whitespace before ";" */ /* check for closing ';' */ parse_wd(hp, ";"); /* append ";" */ if (app_entity) app_estr(amp_str, infgetcw(inpf)); } /* output whole entity */ if (estrlen(amp_str)) hsc_output_text(hp, "", estr2str(amp_str)); del_estr(amp_str); #if (defined MSDOS & (!defined HSC_BILL)) #define WASTE_SIZE (1024*1024) /* waste some time */ { STRPTR mem1 = (STRPTR) umalloc(WASTE_SIZE); STRPTR mem2 = (STRPTR) umalloc(WASTE_SIZE); size_t i = WASTE_SIZE; while (i) { if (mem1[i] && mem2[i]) { mem1[i] = mem2[i]; } else { mem2[i] = mem1[i]; } i--; } ufree(mem2); ufree(mem1); } #endif } return (BOOL) (!hp->fatal); }
/* * 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; 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 */ app_estr(hp->tag_name_str, infgetcw(inpf)); /* check for hsctag; if not, enable output */ if (hp->suppress_output && upstrncmp(nxtwd, HSC_TAGID, strlen(HSC_TAGID)) && strcmp(nxtwd, HSC_COMMENT_STR) && strcmp(nxtwd, HSC_ONLYCOPY_STR) ) { hp_enable_output(hp, "non-hsctag occured"); } if (!hp->suppress_output) { 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; #if 0 /* TODO: remove */ /* NOTE: This one's a bit perverted, because * the closing ">" is appended to the * attribute string, and the closing string * is left empty; as there is nearly no code * between setting and writing the strings, * I think this is more reasonable than doing * some tricky string-manipulation... */ skip_until_eot(hp, hp->tag_attr_str); clr_estr(hp->tag_close_str); #endif } 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 { hsc_message(hp, MSG_SUCC_WHTSPC, "succeeding white-space for %T", tag); } } inungetc(ch, inpf); } } } /* end-tag required? */ if (tag->option & HT_CLOSE) app_ctag(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 { 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_ctag(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) (struct hscprocess * 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; /* write 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 */ } /* remove temporary created tag */ if (unknown_tag) del_hsctag(tag); #if (defined MSDOS && (!defined HSC_TRIGGER)) #define UNLIKELY (10*1024) /* crash randomly */ if ((rand() % UNLIKELY) == (UNLIKELY / 2)) { enforcerHit(); } #endif } return (BOOL) (!hp->fatal); }
/* * 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); }
/* * close_output * * close output file, if it not stdout */ BOOL write_output(HSCPRC * hp) { #define MAX_ERRORLEN 500 STRPTR outfilenm = NULL; BOOL written = FALSE; if (outfilename) outfilenm = estr2str(outfilename); if ((return_code == RC_OK) || (return_code == RC_WARN) || hp->debug) { FILE *outfile = NULL; /* output file */ char buf[MAX_ERRORLEN + 2]; /* buffer for error string */ /* * try to open output file */ if (outfilenm) { errno = 0; outfile = fopen(outfilenm, "w"); if (!outfile) { strncpy(buf, "unable to open `", MAX_ERRORLEN); strncat(buf, estr2str(outfilename), MAX_ERRORLEN - strlen(buf)); strncat(buf, "' for output: ", MAX_ERRORLEN - strlen(buf)); strncat(buf, strerror(errno), MAX_ERRORLEN - strlen(buf)); status_error(buf); } } else { outfile = stdout; outfilenm = STDOUT_NAME; } /* * write output */ if (outfile) { DLNODE *nd = dll_first(outlist); status_msg("writing output..."); errno = 0; /* write whole list of output-strings */ while (nd && !errno) { EXPSTR *outstring = (EXPSTR *) dln_data(nd); nd = dln_next(nd); fwrite(estr2str(outstring), sizeof(char), estrlen(outstring), outfile); } /* handle write-error, display message */ if (errno) { strncpy(buf, "error writing `", MAX_ERRORLEN); strncat(buf, outfilenm, MAX_ERRORLEN - strlen(buf)); strncat(buf, "': ", MAX_ERRORLEN - strlen(buf)); strncat(buf, strerror(errno), MAX_ERRORLEN - strlen(buf)); status_error(buf); } else written = TRUE; status_clear(); /* close output file */ if (outfile != stdout) { fclose(outfile); #ifdef RISCOS { /* set the filetype to HTML (&FAF) */ char *riscos_filename=unixname_to_riscos(outfilenm); _swix(OS_File,_IN(0)|_IN(1)|_IN(2),18,riscos_filename,0xFAF); free(riscos_filename); } #endif } } } else { status_msg("no output written"); status_lf(); } return (written); }
/* * hsc_write_project_file * * store all project-data in a string and write it to * the file specified with hsc_set_project_filename() */ BOOL hsc_project_write_file(HSCPRJ * hp, STRPTR project_fname) { BOOL written = FALSE; if (hp && !hp->fatal && project_fname) { EXPSTR *prjstr = init_estr(256); DLNODE *nd = NULL; FILE *outfile = NULL; DP(fprintf(stderr, DHP "update project file `%s'\n", project_fname)); /* append header information */ append_header(prjstr); /* append current document to project */ hsc_project_add_document(hp); /* * append all old project info of other files */ nd = dll_first(hp->documents); while (nd) { HSCDOC *document = (HSCDOC *) nd->data; append_document(prjstr, document); nd = dln_next(nd); } DP(fprintf(stderr, DHP "project file contains:\n%s", estr2str(prjstr))); /* write new project file */ errno = 0; outfile = fopen(project_fname, "w"); if (outfile) { errno = 0; fwrite(estr2str(prjstr), sizeof(char), estrlen(prjstr), outfile); if (errno) { DP(fprintf(stderr, DHP "can't write project file\n")); /* TODO: show message "can't open project file" */ } else written = TRUE; } else { DP(fprintf(stderr, DHP "can't open project file for output\n")); /* TODO: show message "can't open project file" */ } del_estr(prjstr); } else { D(fprintf(stderr, DHP "no update project\n")); } return (written); }