/* * hsc_read_prefs * * try to open (any) config file and read preferences * from it */ static BOOL hsc_read_prefs(HSCPRC * hp, STRPTR prefs_fname) { BOOL ok = FALSE; EXPSTR *prefs_name_buffer = init_estr(32); /* find prefs file */ if (!prefs_fname) prefs_fname = find_prefs_fname(hp, prefs_name_buffer); /* status message */ if (prefs_fname) { dbg_disable(hp); hsc_status_file_begin(hp, prefs_fname); ok = hsc_include_file(hp, prefs_fname, IH_PARSE_HSC | IH_NO_STATUS); dbg_restore(hp); if (ok) { EXPSTR *msg = init_estr(32); set_estr(msg, prefs_fname); app_estr(msg, ": preferences read"); hsc_status_misc(hp, estr2str(msg)); del_estr(msg); } } else hsc_message(hp, MSG_NO_CONFIG, "can not open preferences file"); del_estr(prefs_name_buffer); return (ok); }
/* * read_macro_text */ static BOOL read_macro_text(HSCPRC * hp, HSCTAG * macro, BOOL is_start_macro) { BOOL ok = FALSE; EXPSTR *macstr = NULL; /* skip first LF if any */ skip_next_lf(hp); /* init an EXPSTR for macro text, * remember location of macro-def (for messages) */ if (is_start_macro) { macro->op_text = init_estr(ES_STEP_MACRO); macstr = macro->op_text; macro->start_fpos = new_winfilepos(hp->inpf); } else { macro->cl_text = init_estr(ES_STEP_MACRO); macstr = macro->cl_text; macro->end_fpos = new_winfilepos(hp->inpf); } /* read macro text */ ok = skip_until_tag(hp, macstr, NULL, NULL, HSC_MACRO_STR, SKUT_NO_CONTENT_TAGFOUND); /* if last char of macrotext is LF, CR or CR/LF, remove it */ if (ok) { STRPTR ms = estr2str(macstr); size_t len = strlen(ms); size_t oldlen = len; /* NOTE: this is a bit ugly, it would be nicer to * call leftstr() here and strip last ch, but this * a lot faster */ if (len && (ms[len - 1] == '\n')) { ms[len - 1] = '\0'; len = strlen(ms); } if (len && (ms[len - 1] == '\r')) { ms[len - 1] = '\0'; len = strlen(ms); } if (oldlen != len) { DMC(fprintf(stderr, DHL " stripped cr/lf at end\n")); } DMC(fprintf(stderr, DHL "Macro text: \"%s\"\n", estr2str(macstr))); } return (ok); }
/* * cpy_hsctag * * copy an already existing hsctag * * NOTE: this is not a 100% clone: * - tag-callbacks are disabled and have to be assigned again. * - the occured-flag is disabled */ HSCTAG *cpy_hsctag(HSCTAG * oldtag) { HSCTAG *newtag = new_hsctag(oldtag->name); if (newtag) { DLNODE *nd = NULL; /* init new tag item */ newtag->option = oldtag->option; newtag->o_handle = NULL; /* no handle functions */ newtag->c_handle = NULL; newtag->occured = FALSE; newtag->op_text = NULL; newtag->cl_text = NULL; newtag->attr = init_dllist(del_hscattr); newtag->mbi = strclone(oldtag->mbi); newtag->naw = strclone(oldtag->naw); newtag->uri_size = NULL; newtag->uri_stripext = NULL; /* copy macro text */ if (oldtag->op_text) { newtag->op_text = init_estr(0); estrcpy(newtag->op_text, oldtag->op_text); } if (oldtag->cl_text) { newtag->cl_text = init_estr(0); estrcpy(newtag->cl_text, oldtag->cl_text); } /* copy attribute list */ nd = oldtag->attr->first; while (nd) { HSCATTR *attr = (HSCATTR *) nd->data; /* old attribute */ /* create copy of old attribute */ HSCATTR *nattr = cpy_hscattr(attr); /* append this copy to new attr-list */ app_dlnode(newtag->attr, nattr); /* check for special uri-attributes */ if (!upstrcmp(nattr->name, oldtag->uri_size->name)) newtag->uri_size = nattr; if (!upstrcmp(nattr->name, oldtag->uri_stripext->name)) newtag->uri_size = nattr; } } return (newtag); }
/* * find_prefs_fname * * find preferences file: first check, if it is located * somewhere in the paths given via CONFIG_PATH (which * is a system depandent symbol); if not, check if it * is in the path described in the envvar HSCPREFS * * result: full path & filename of prefs or NULL if not found * */ static STRPTR find_prefs_fname(HSCPRC * hp, EXPSTR *cfgfn) { #define ENV_HOME "HOME" STRPTR prefs_fname = NULL; STRPTR paths[] = /* paths to search for config file */ {"", "", "", CONFIG_PATH, NULL, NULL}; STRPTR path = NULL; UBYTE path_ctr = 0; FILE *cfgf = NULL; /* prefs file */ EXPSTR *hscpathstr = init_estr(32); /* buffer to read $HSCPATH */ EXPSTR *homepathstr = init_estr(32); /* buffer to read $HOME */ /* add "$HSCPATH/hsc.prefs" to files-to-be-checked */ if (link_envfname(hscpathstr, ENV_HSCPATH, NULL, NULL)) { /* add envval to paths */ paths[1] = estr2str(hscpathstr); } /* add "$HOME/lib/hsc.prefs" to files-to-be-checked */ if (link_envfname(homepathstr, ENV_HOME, "lib", NULL)) { /* add envval to paths */ paths[2] = estr2str(homepathstr); } /* try to open any prefs-file */ do { /* loop: */ path = paths[path_ctr]; /* get next path */ if (path) { /* is it the last one? */ set_estr(cfgfn, path); /* N->generate filename */ app_estr(cfgfn, CONFIG_FILE); DC(fprintf(stderr, DHL "try \"%s\"\n", estr2str(cfgfn))); cfgf = fopen(estr2str(cfgfn), "r"); /* try to open file */ } path_ctr++; /* process next path */ } while (path && (!cfgf)); /* until no path left or file opened */ if (cfgf) { prefs_fname = estr2str(cfgfn); fclose(cfgf); } del_estr(homepathstr); del_estr(hscpathstr); return (prefs_fname); }
/* ** init_global ** ** init global data */ BOOL init_global( VOID ) { BOOL ok = TRUE; return_code = RC_OK; inpfilename = init_estr( 32 ); msgbuf = init_estr( 64 ); ok = ( inpfilename && msgbuf ); return( ok ); }
/* ** handle_macro ** ** handle for macro: add local attributes to global attributes, ** include macro text, remove local attributes ** ** params: open_mac..TRUE, if called by an opening macro ** inpf......input file */ BOOL handle_macro( BOOL open_mac, INFILE *inpf, HSCTAG *macro ) { BOOL ok = FALSE; EXPSTR *text; /* macro text */ EXPSTR *fname; /* pseudo-filename */ DLLIST *args; ULONG mci = get_mci(); /* determine filename & args */ args = macro->attr; if ( open_mac ) { text = macro->op_text ; } else { text = macro->cl_text ; } fname = init_estr( 0 ); if ( fname ) { /* debugging message */ DMC( { fprintf( stderr, "**-MACRO <" ); if ( !open_mac ) fprintf( stderr, "/" ); fprintf( stderr, "%s> from %p\n", macro->name, text ); } ); /* create pseudo-filename */ ok = set_estr( fname, "[macro " ); ok &= app_estr( fname, macro->name ); ok &= app_estr( fname, "]" ); }
/* * define_attr_by_text * * define a new attribute with attribute definition passed as * string. The new attribute is assigned to the global attr-list * (by default, with a local scope) * * params: varname..name of new var * flag.....flags: VF_ONLYONCE to avoid re-definition of a var * result: ptr to new var * * NOTE: * The new attribute will be declared as if a corresponding * <$define> showed up in the source. It will be assigned to * the local scope; you will need to add a "/GLOBAL" to the * description text if you want to avoid this * * It's recommended not to setup a default value, if you are * not sure that it can't contain data that will cause error * messages to show up (like value=xy"zw'bl) * * definition syntax in input file: * <varname>":"<vartype>[/flag]["="<deftext value>] * * EXAMPLE: * define_attr_by_text(hp,"sepp:string/global='sepp'", 0) * * SEE ALSO: * define_var() */ HSCATTR *define_attr_by_text(HSCPRC * hp, STRPTR attr_text, STRPTR default_value, ULONG unmasked_flags) { /* NOTE: this functions works a bit strange */ EXPSTR *define_text = init_estr(0); INFILE *old_inpf = hp->inpf; HSCATTR *attr = NULL; /* create attribute definition */ set_estr(define_text, attr_text); app_estr(define_text, ">"); hp->inpf = infopen_str(PARENT_FILE_ID "define_attr_by_text", estr2str(define_text), 0); /* process attribute definition */ if (hp->inpf) { attr = define_attr_by_hp(hp, default_value, unmasked_flags); infclose(hp->inpf); } /* cleanup */ hp->inpf = old_inpf; del_estr(define_text); return (attr); }
/* replace icon-entity by image */ static VOID replace_icon(HSCPRC * hp, STRPTR icon) { INFILEPOS *base = new_infilepos(hp->inpf); EXPSTR *image = init_estr(0); STRPTR s = estr2str(hp->iconbase); /* create string like <IMG SRC=":icons/back.gif" ALT="back"> */ set_estr(image, "<IMG SRC=\""); /* use iconbase with "*" replaced by iconname as uri */ while (s[0]) { if (s[0] == '*') app_estr(image, icon); else app_estrch(image, s[0]); s++; } /* set ALT attribute to iconname */ app_estr(image, "\" ALT=\""); app_estr(image, icon); app_estr(image, "\">"); hsc_message(hp, MSG_RPLC_ICON, "replacing icon-%e", icon); hsc_include_string(hp, SPECIAL_FILE_ID "include icon", estr2str(image), IH_PARSE_HSC | IH_NO_STATUS | IH_POS_PARENT); del_estr(image); del_infilepos(base); }
/* * 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); }
/* * get_mid_estr * * get a part from a expstr; compare BASIC's "MID$()" * * params: dest...destination expstr where to store result part * src....source expstr where to get part from * from...position of char where to begin part (0=first char) * num....number of chars to get * result: TRUE and result in dest if ok; else FALSE is returned an * dest is left untouched * * NOTE: it is possible to use the source-exstr as destination-expstr, * because the result is copied to a temp. expstr before * ( example: get_mid_estr( hugo, hugo, 3, 4 ); ) */ BOOL get_mid_estr(EXPSTR * dest, EXPSTR * src, size_t from, size_t num) { BOOL ok = FALSE; EXPSTR *tmp = init_estr(dest->es_step); if (tmp) { STRPTR old_data = tmp->es_data; /* check size */ if (from >= src->es_len) from = src->es_len - 1; if (from + num >= src->es_len) num = src->es_len - from - 1; /* set new mem for tmp */ ok = set_estr_mem(tmp, modadj(num + 1, tmp->es_step)); if (ok) { /* copy data */ strncpy(estr2str(tmp), estr2str(src) + from, num); tmp->es_data[num] = 0; tmp->es_len = num + 1; ufree(old_data); ok = estrcpy(dest, tmp); } del_estr(tmp); } return (ok); }
/* ** 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); }
/* * getfilesize * * get size of a specific file * * templates for HSC.FORMAT.FILESIZE: * %b size in byte * %k size in Kbyte * %m size in MByte * %g size in Gbyte * %a size, unit computed automatically * %u unit for %A (none, "K", "M" or "G") */ static STRPTR getfilesize(HSCPRC * hp, EXPSTR * dest, STRPTR uri) { STRPTR filesizestr = NULL; FILE *file = NULL; LONG filesize = 0; /* filesize in byte */ LONG filesize_k = 0; /* filesize in Kbyte */ LONG filesize_m = 0; /* filesize in Mbyte */ LONG filesize_g = 0; /* filesize in Gbyte */ LONG filesize_auto = 0; /* filesize in auto-units (%A) */ EXPSTR *efilename = init_estr(32); STRPTR filename = NULL; STRPTR sizeunit = ""; STRPTR s = get_vartext_byname(hp->defattr, FILESIZEFORMAT_ATTR); conv_hscuri2file(hp, efilename, uri); filename = estr2str(efilename); D(fprintf(stderr, DHL " GETFILESIZE(`%s')\n", filename)); errno = 0; file = fopen(filename, "rb"); if (file) { /* retrieve size */ fseek(file, 0L, SEEK_END); filesize = ftell(file); fclose(file); /* compute size in units, */ filesize_k = (filesize + 512) >> 10; filesize_m = (filesize_k + 512) >> 10; filesize_g = (filesize_m + 512) >> 10; /* compute auto-size */ if (filesize_g > 10) { filesize_auto = filesize_g; sizeunit = "G"; } else if (filesize_m > 10) { filesize_auto = filesize_m; sizeunit = "M"; } else if (filesize_k > 10) { filesize_auto = filesize_k; sizeunit = "K"; } else { filesize_auto = filesize; sizeunit = ""; } } else {
static VOID send_arexx_command(HSCPRC * hp, STRPTR arexx_command) { /* Hex-escaped Arexx command */ EXPSTR *escaped_arexx_command = init_estr(256); STRPTR command_character = NULL; BOOL insert_concatenation; set_estr(escaped_arexx_command, "RX >nil: \"cmd='"); /* Hex-escape nasty characters in command before sending it via RX. * Probably more characters then neccessary are escaped, but extending * this list is faster then finding out if a character is nasty or not. */ command_character = arexx_command; insert_concatenation = TRUE; while (command_character[0] != '\0') { STRARR hex_buffer[10]; if (insert_concatenation) { app_estr(escaped_arexx_command, "'||'"); } switch (command_character[0]) { case '\'': case '\"': case '*': case '`': sprintf(hex_buffer, "'||'%x'x'", command_character[0]); app_estr(escaped_arexx_command, hex_buffer); insert_concatenation = TRUE; break; default: app_estrch(escaped_arexx_command, command_character[0]); insert_concatenation = FALSE; break; } command_character += 1; } app_estr(escaped_arexx_command,"';"); #if DEBUG_MSGBROWSER app_estr(escaped_arexx_command,"call open(f,'console:'); call writeln(f,cmd);"); #endif app_estr(escaped_arexx_command,"address " SC_SCMSG " cmd"); app_estr(escaped_arexx_command, "\""); #if DEBUG_MSGBROWSER fprintf(stderr, "sending arexx: %s\n", estr2str(escaped_arexx_command)); #endif system(estr2str(escaped_arexx_command)); del_estr(escaped_arexx_command); }
/* * init_output: * * init output string * * result: TRUE if sucessful, else FALSE */ BOOL init_output(HSCPRC * hp) { BOOL ok = TRUE; /* return value */ EXPSTR *outstring = init_estr(OUTPUT_STEPSIZE); /* first output string */ outlist = init_dllist((del_outstr)); /* init outstring-list */ app_dlnode(outlist, (APTR) outstring); /* append first entry */ return (ok); }
/* hsc_include_file: include file without base-position */ BOOL hsc_include_file(HSCPRC * hp, STRPTR filename, ULONG optn) { BOOL ok = FALSE; EXPSTR *real_filename = init_estr(64); /* scan include directories */ find_includefile(hp, real_filename, filename); /* now include file */ ok = hsc_base_include_file(hp, estr2str(real_filename), optn, NULL); /* cleanup */ del_estr(real_filename); return ok; }
/* * 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); }
/* ** handle_hsc_exec ** ** exec a sub file */ BOOL handle_hsc_exec( INFILE *inpf, HSCTAG *tag ) { STRPTR cmd = get_vartext( tag->attr, "COMMAND" ); if ( cmd ) { int result; EXPSTR *msg = init_estr( 0 ); if ( msg && app_estr( msg, "execute: " ) && app_estr( msg, cmd ) ) { /* status message */ status_msg( estr2str( msg ) ); if ( verbose ) status_lf(); /* call command */ result = system( cmd ); /* check for non-zero-result */ if ( result ) { message( MSG_SYSTEM_RETURN, inpf ); errstr( "Calling external command returned " ); errstr( long2str( (LONG) result ) ); errlf(); } } else err_mem( inpf ); del_estr( msg ); } return (TRUE); }
/* * get_width_height * * tries to get values for WIDTH and HEIGHT attributes * from file * * result: TRUE, if filetype has been recognised */ BOOL get_attr_size(HSCPRC * hp, HSCTAG * tag) { #define BUFSIZE 2048 #define WIDTH_PNG 16 /* file indeces for PNG */ #define HEIGHT_PNG 20 HSCVAR *asrc = tag->uri_size; STRPTR srcuri = NULL; if (asrc) srcuri = get_vartext(asrc); else { panic("no uri_size"); } if (hp->getsize && srcuri && (uri_kind(srcuri) != URI_ext)) { STRARR buf[BUFSIZE]; EXPSTR *srcpath = init_estr(64); EXPSTR *imgpath = init_estr(64); ULONG width = 0; ULONG height = 0; BOOL transparent = FALSE; BOOL progressive = FALSE; STRPTR filetype = NULL; FILE *fref = NULL; /* file link references to */ STRARR id_PNG[8] = {137, 80, 78, 71, 13, 10, 26, 10}; /* PNG image header */ conv_hscuri2file(hp, srcpath, srcuri); DSZ(fprintf(stderr, DHL " uri : \"%s\"\n** path: \"%s\"\n", srcuri, estr2str(srcpath))); fref = fopen(estr2str(srcpath), "r"); if (fref) { /* fill buffer with zero */ memset(buf, 0, BUFSIZE); /* read buffer from file */ fread(buf, BUFSIZE, 1, fref); if (buf[0] == 0xff) { /* * JFIF/JPEG */ BOOL found = FALSE; size_t i = 0; /*TODO: progressive */ while (!found && (i < BUFSIZE + 8)) { if (buf[i] == 0xff) { BOOL is_msof = FALSE; int j = 0; DSZ(printf("%04x: %02x %02x: (%02x%02x %02x%02x) ", (ULONG) i, buf[i], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5])); /* check if marker is of required type */ while (!is_msof && msof[j]) if (buf[i + 1] == msof[j]) is_msof = TRUE; else j++; if (is_msof) { DSZ( { for (j = 0; j < 10; j++) { printf("\n %-2d: $%02x %-3d", j, buf[i + j], buf[i + j]); if (buf[i + j] >= 32) printf(" '%c'", buf[i + j]); } } ); filetype = "JFIF/JPEG"; width = buf[i + 8] + (buf[i + 7] << 8); height = buf[i + 6] + (buf[i + 5] << 8); found = TRUE; } else { DDA(printf("ignore\n")); } }
/* * new_hscprc * * create and init a new hsc process */ HSCPRC *new_hscprc(void) { HSCPRC *hp = NULL; hp = (HSCPRC *) umalloc(sizeof(HSCPRC)); if (hp) { memset(hp, 0, sizeof(HSCPRC)); /* init lists */ hp->defent = init_dllist(del_entity); hp->deftag = init_dllist(del_hsctag); hp->defattr = init_dllist(del_hscattr); hp->container_stack = init_dllist(del_hsctag); hp->content_stack = init_dllist(del_string_node); hp->inpf_stack = init_dllist(del_inpf_stack_node); hp->project = NULL; hp->idrefs = init_dllist(del_idref); hp->select_stack = init_dllist(del_select_stack_node); hp->include_dirs = init_strlist(); /* init strings */ hp->destdir = init_estr(0); hp->reldir = init_estr(0); hp->iconbase = init_estr(0); hp->server_dir = init_estr(0); hp->if_stack = init_estr(0); hp->tag_name_str = init_estr(128); hp->tag_attr_str = init_estr(128); hp->tag_close_str = init_estr(0); hp->tmpstr = init_estr(0); hp->curr_msg = init_estr(64); hp->curr_ref = init_estr(64); hp->whtspc = init_estr(0); #if 0 /* TODO:remove */ hp->filename_project = NULL; hp->filename_document = NULL; #endif /* alloc message arrays */ hp->msg_ignore = (BOOL *) umalloc((MAX_MSGID + 1) * sizeof(BOOL)); hp->msg_class = (HSCMSG_CLASS *) umalloc((MAX_MSGID + 1) * sizeof(HSCMSG_CLASS)); reset_hscprc(hp); } return (hp); }
BOOL skip_until_tag(HSCPRC * hp, EXPSTR * tagfound, STRPTR tagstoplist, STRPTR tagnest) { UBYTE state = STATE_TEXT; /* */ INFILE *inpf = hp->inpf; /* input file */ LONG nesting = 0; /* tag-nesting */ LONG nesting_comment = 0; /* comment-nesting */ STRPTR nw = NULL; BOOL quit = FALSE; /* flag: exit from skipping */ EXPSTR *ungetstr = init_estr(32); clr_estr(tagfound); do { /* get next word or tag-id */ if (state != STATE_TAG) nw = infgetw(inpf); else { nw = infget_tagid(hp); if (nw) { app_estr(ungetstr, infgetcws(inpf)); app_estr(ungetstr, infgetcw(inpf)); if (strcmp(nw, "/")) { DS(fprintf(stderr, DHLS "start-tag <%s>\n", nw)); state = STATE_TAGNAME; /* tag detected */ } else { nw = infget_tagid(hp); DS(fprintf(stderr, DHLS "end-tag </%s>\n", nw)); app_estr(ungetstr, infgetcws(inpf)); app_estr(ungetstr, infgetcw(inpf)); state = STATE_ENDTAGNAME; /* end-tag detected */ } } } if (nw) { switch (state) { /* check if tag starts */ case STATE_TEXT: if (!strcmp(nw, "<")) { DS(fprintf(stderr, DHLS "tag\n")); set_estr(ungetstr, nw); state = STATE_TAG; } break; /* check which tag it is and how to act */ case STATE_TAGNAME: { /* check, if nesting-tag should be incr. */ if (!upstrcmp(nw, tagnest)) { DS(fprintf(stderr, DHLS "nest-tag (%ld)\n", nesting)); state = STATE_TAGATTR; nesting++; } /* check, if stop-tag reached */ else if (!nesting && strenum(nw, tagstoplist, '|', STEN_NOCASE)) { DS(fprintf(stderr, DHLS "stop-tag `%s'\n", nw)); set_estr(tagfound, nw); quit = TRUE; } /* check, if commant-tag reached */ else if (!strcmp(nw, HSC_COMMENT_STR)) { DS(fprintf(stderr, DHLS "comment-tag (0)\n")); state = STATE_COMMENT; } /* any tag; just skip attributes */ else { DS(fprintf(stderr, DHLS "any tag\n")); state = STATE_TAGATTR; } break; } case STATE_ENDTAGNAME: { if (!upstrcmp(nw, tagnest)) { if (nesting) { nesting--; DS(fprintf(stderr, DHLS "nest-tag (%ld)\n", nesting)); } else { DS(fprintf(stderr, DHLS "nest-tag ending\n")); quit = TRUE; } } else state = STATE_TEXT; /* no attr for endtag */ break; } /* * process tag attributes */ case STATE_TAGATTR: { if (!strcmp(nw, "=")) state = STATE_TAGATTR_EQ; else if (!strcmp(nw, ">")) { DS(fprintf(stderr, DHLS "back to text\n")); state = STATE_TEXT; } break; } case STATE_TAGATTR_EQ: { if (!strcmp(nw, "\"")) { DS(fprintf(stderr, DHLS "tagarg (double quote)\n")); state = STATE_TAGATTR_DQUOTE; } else if (!strcmp(nw, "'")) { DS(fprintf(stderr, DHLS "tagarg (single quote)\n")); state = STATE_TAGATTR_SQUOTE; } else state = STATE_TAGATTR; break; } case STATE_TAGATTR_DQUOTE: { if (!strcmp(nw, "\"")) { DS(fprintf(stderr, DHLS "end tagarg (double quote)\n")); state = STATE_TAGATTR; } break; } case STATE_TAGATTR_SQUOTE: { if (!strcmp(nw, "'")) { DS(fprintf(stderr, DHLS "end tagarg (single quote)\n")); state = STATE_TAGATTR; } break; } /* * comment processing */ case STATE_COMMENT: { /* check for <" */ if (!strcmp(nw, "<")) state = STATE_COMMENT_TAG; else if (!strcmp(nw, HSC_COMMENT_STR)) state = STATE_COMMENT_STAR; break; } case STATE_COMMENT_TAG: { /* check for comment-nesting */ if (!strcmp(nw, HSC_COMMENT_STR)) { nesting_comment++; DS(fprintf(stderr, DHLS "comment-tag (%ld)\n", nesting_comment)); state = STATE_COMMENT; } else state = STATE_COMMENT; break; } case STATE_COMMENT_STAR: { /* check for end comment */ if (!strcmp(nw, ">")) if (nesting_comment) { nesting_comment--; DS(fprintf(stderr, DHLS "end comment-tag (%ld)\n", nesting_comment)); state = STATE_COMMENT; } else { DS(fprintf(stderr, DHLS "end comment-tag (%ld)\n", nesting_comment)); state = STATE_TEXT; } else state = STATE_COMMENT; break; } /* * unhandled tag */ default: panic("unhandled state"); break; } } } while (nw && !quit && !(hp->fatal)); if (nw) { inungets(estr2str(ungetstr), inpf); } else { EXPSTR *tagstr = init_estr(0); set_estr(tagstr, "</"); app_estr(tagstr, tagnest); app_estr(tagstr, "> expected"); hsc_msg_eof(hp, estr2str(tagstr)); del_estr(tagstr); } del_estr(ungetstr); return ((BOOL) (nw != NULL)); }
/* ** set_tag_arg ** ** parse & set one single tag argument ** */ static BOOL set_tag_arg( HSCPRC *hp, DLLIST *varlist, STRPTR varname ) { HSCATTR *var = find_varname( varlist, varname ); INFILE *inpf = hp->inpf; STRPTR arg = NULL; BOOL ok = FALSE; STRPTR nw; HSCATTR skipvar; /* dummy attribute to skip unkown */ EXPSTR *attr_str = init_estr( 40 ); /* string for attribute name */ EXPSTR *val_str = init_estr( 40 ); /* string for "=" and value */ DAV( fprintf( stderr, DHL " set attr %s\n", varname ) ); /* append attribute name to attr_str */ app_estr( attr_str, infgetcws( inpf ) ); app_estr( attr_str, infgetcw( inpf ) ); if ( !var ) { /* attribute not found */ /* assign to pseudo-attribute */ var = &skipvar; var->name = varname; var->deftext = NULL; var->text = NULL; var->enumstr = NULL; var->vartype = VT_STRING; var->varflag = 0; /* message: unknown attribute */ hsc_msg_unkn_attr( hp, varname ); } /* get argument */ nw = infgetw( inpf ); if ( nw ) if ( !strcmp( nw, "=" ) ) { /* append "=" to log */ app_estr( val_str, infgetcws( inpf ) ); app_estr( val_str, infgetcw( inpf ) ); /* parse expression */ arg = eval_expression( hp, var, NULL ); /* append value to log */ if ( var->quote != VQ_NO_QUOTE ) app_estrch( val_str, var->quote ); if ( get_vartext( var ) ) app_estr( val_str, get_vartext( var ) ); if ( var->quote != VQ_NO_QUOTE ) app_estrch( val_str, var->quote ); if ( arg ) { DAV( fprintf( stderr, DHL " `%s'\n", arg ) ); ok = TRUE; } } else { arg = NULL; inungetcwws( inpf ); ok = TRUE; } else hsc_msg_eof( hp, "read attribute value" ); if ( ok ) if ( arg ) { if ( var->vartype == VT_BOOL ) { /* set boolean attribute depending on expression */ set_vartext_bool( var, get_varbool( var ) ); /* if the expression returned FALSE, remove ** the boolean switch from the call */ if ( !get_varbool( var ) ) clr_estr( attr_str ); } else /* append value to attribute string */ app_estr( attr_str, estr2str( val_str ) ); } else { /* no value has been passed to the attribute */ if ( var->vartype == VT_BOOL ) { /* for boolean attributes, this is legal, ** and enables the attribute */ set_vartext_bool( var, TRUE ); } else { /* for non-boolean attributes, display ** error message */ hsc_message( hp, MSG_NOARG_ATTR, "missing value for %A", var ); } } #if 0 if ( arg ) { if ( var->vartype == VT_BOOL ) { message( MSG_ARG_BOOL_ATTR, inpf ); errstr( "value for boolean" ); errsym( var->name ); errlf(); } } else { if ( var->vartype == VT_BOOL ) { /* set boolean attribute */ DAV( fprintf( stderr, " (bool)\n", var->name ) ); set_vartext( var, var->name ); var->quote = VQ_NO_QUOTE; } else { } } #endif /* cleanup pseudo-attr */ if ( var == &skipvar ) clr_vartext( var ); /* append & cleanup attribute and value string */ app_estr( hp->tag_attr_str, estr2str( attr_str ) ); del_estr( attr_str ); del_estr( val_str ); return( ok ); }
/* * new_hscprc * * create and init a new hsc process */ HSCPRC *new_hscprc(void) { HSCPRC *hp = NULL; hp = (HSCPRC *) umalloc(sizeof(HSCPRC)); if (hp) { memset(hp, 0, sizeof(HSCPRC)); /* init lists */ hp->defent = init_dllist(del_entity); hp->deftag = init_hsctree(free_tag_node, cmp_tag_node, ubi_trOVERWRITE); hp->defattr = init_dllist(del_hscattr); hp->deflazy = init_hsctree(free_tag_node, cmp_tag_node, ubi_trOVERWRITE); hp->defstyle = init_hsctree(free_style_node, cmp_style_node, ubi_trOVERWRITE); hp->container_stack = init_dllist(del_hsctag); hp->content_stack = init_dllist(del_string_node); hp->inpf_stack = init_dllist(del_inpf_stack_node); hp->project = NULL; hp->idrefs = init_dllist(del_idref); hp->select_stack = init_dllist(del_select_stack_node); hp->tag_styles = init_dllist(&del_styleattr); hp->include_dirs = init_strlist(); /* precompile some regular expressions */ hp->re_uri = hscregcomp(hp, REGEXP_URI, TRUE, TRUE); /* init strings */ hp->destdir = init_estr(0); hp->reldir = init_estr(0); hp->iconbase = init_estr(0); hp->server_dir = init_estr(0); hp->if_stack = init_estr(0); hp->tag_name_str = init_estr(128); hp->tag_attr_str = init_estr(128); hp->tag_close_str = init_estr(0); hp->tmpstr = init_estr(0); hp->curr_msg = init_estr(64); hp->curr_ref = init_estr(64); hp->whtspc = init_estr(0); /* allocate message arrays */ hp->msg_ignore = (HSCIGN *) umalloc((MAX_MSGID + 1) * sizeof(HSCIGN)); hp->msg_class = (HSCMSG_CLASS *) umalloc((MAX_MSGID + 1) * sizeof(HSCMSG_CLASS)); /* allocate image buffer */ hp->image_buffer = (unsigned char *) umalloc(IMAGE_BUFFER_SIZE); reset_hscprc(hp); } return (hp); }
int main(void) { #if 0 LONG i; #endif #if DEBUG_UGLY_MEMORY atexit(atexit_uglymemory); #endif #if 0 for (i = 0; i < 20; i++) printf("modadj(%-2d/%-2d) = %d\n", i, EXPSTR_MEMSTEP, modadj(i, EXPSTR_MEMSTEP)); #endif es = init_estr(8); pe("init "); res = init_estr(8); pr("init "); umem_wallcheck("after init"); #if 0 /* test reference to NULL string */ app_estrch(NULL, 'x'); app_estr(es, NULL); #endif #if 0 #if 1 printf("** test set\n"); set_estr(es, "dummy"); pr("set "); umem_wallcheck("after set"); #if 1 set_estr(es, "hugo ist doof."); pe("set "); set_estrn(es, "hugo", 4); pe("setn:4 "); set_estrn(es, "hugo", 1); pe("setn:1 "); set_estrn(es, "hugo", 0); pe("setn:0 "); set_estrn(es, "hugo", 5); pe("setn:5 "); #endif umem_wallcheck("after set"); #endif #if 1 printf("** test append-string\n"); set_estr(es, "hugo ist doof...!!"); pe("set "); app_estrch(es, ' '); pe("appch "); app_estrch(es, 's'); pe("appch "); #if 1 app_estr(es, "epp auch."); pe("appstr"); app_estr(es, "."); pe("appstr"); app_estr(es, "."); pe("appstr"); app_estr(es, "."); pe("appstr"); app_estr(es, " that's it, as you can see"); pe("appstr"); #endif umem_wallcheck("after append"); #endif #if 0 /* test cutting functions */ estrcpy(res, es); pr("copy "); get_mid_estr(es, res, 5, 3); pe("mid "); /* "ist" */ get_right_estr(es, res, 5); pe("right "); /* "auch." */ get_left_estr(es, res, 4); pe("left "); /* "hugo" */ /* test special cases for cutting funtions */ printf("** test get-part\n"); set_estr(res, "hugo"); pr("res=hugo "); get_mid_estr(es, res, 4, 3); pe("mid(4,5) "); get_mid_estr(es, res, 3, 2); pe("mid(3,2) "); get_mid_estr(es, res, 0, 9); pe("mid(0,9) "); get_left_estr(es, res, 5); pe("lef(5) "); get_left_estr(es, res, 4); pe("lef(4) "); get_right_estr(es, res, 5); pe("rig(5) "); get_right_estr(es, res, 4); pe("rig(4) "); #endif #endif /* umem_wallcheck("before delete"); */ printf("** remove strings\n"); del_estr(es); del_estr(res); return (0); }
/* * 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); }
/* * user_defines_ok * * process all defines passed via user args * * result: always TRUE */ BOOL user_defines_ok(HSCPRC * hp) { /* define destination attributes (HSC.DOCUMENT.URI etc.) */ define_file_attribs(hp); if (define_list && dll_first(define_list)) { DLNODE *nd = dll_first(define_list); EXPSTR *defbuf = init_estr(64); #if 0 BOOL old_ignore_quotemsg = hsc_get_msg_ignore(hp, MSG_ARG_NO_QUOTE); #endif while (nd) { STRPTR defarg = (STRPTR) dln_data(nd); D(fprintf(stderr, DHSC "define using `%s'\n", defarg)); set_estr(defbuf, "<$define "); /* append attribute name */ do { app_estrch(defbuf, defarg[0]); defarg++; } while (defarg[0] && (defarg[0] != '=') && (defarg[0] != '/') && (defarg[0] != ':')); /* if no type set, use "string" as default */ if (defarg[0] != ':') { app_estr(defbuf, ":string"); } /* append type (if set) and attribute-flags */ while (defarg[0] && (defarg[0] != '=')) { app_estrch(defbuf, defarg[0]); defarg++; } /* append value (if any) and quotes */ if (defarg[0] == '=') { char quote_needed = 0; /* flag: user did not use quotes */ /* append "=" */ app_estrch(defbuf, defarg[0]); defarg++; /* check which kind of quote should be appended */ if ((defarg[0] != '\"') && (defarg[0] != '\'')) { BOOL single_quote = FALSE; BOOL double_quote = FALSE; STRPTR scanarg = defarg; /* scan value for quotes */ while (scanarg[0]) { if (scanarg[0] == '\"') double_quote = TRUE; else if (scanarg[0] == '\'') single_quote = TRUE; scanarg++; } /* choose quote to enclose value */ if (!double_quote) quote_needed = '\"'; else if (!single_quote) quote_needed = '\''; else panic("both quotes in value"); } /* append quote (if not already done by user) */ if (quote_needed) app_estrch(defbuf, quote_needed); /* append value */ while (defarg[0]) { app_estrch(defbuf, defarg[0]); defarg++; } /* append quote (if not already done by user) */ if (quote_needed) app_estrch(defbuf, quote_needed); } /* append end ">" */ app_estrch(defbuf, '>'); D(fprintf(stderr, DHSC "define: `%s'\n", estr2str(defbuf))); hsc_include_string(hp, "DEFINE", estr2str(defbuf), IH_PARSE_HSC | IH_NO_STATUS); nd = dln_next(nd); } del_estr(defbuf); #if 0 hsc_set_msg_ignore(hp, MSG_ARG_NO_QUOTE, old_ignore_quotemsg); #endif } else { D(fprintf(stderr, DHSC "(no defines)\n")); } return ((BOOL) (return_code < RC_ERROR)); }
/* * convert uri to filename in destination-dir */ static VOID conv_hscuri2fileNuri(HSCPRC * hp, EXPSTR * dest_uri, EXPSTR * dest_fname, STRPTR uri) { EXPSTR *rel_path = init_estr(32); /* relative path */ URIKIND kind = uri_kind(uri); clr_estr(dest_uri); clr_estr(dest_fname); /* if a <BASE HREF=".."> was found before, * therefor treat URI as absolute */ if (hp->docbase_set) kind = URI_ext; /* evaluate kind of URI */ if (kind == URI_abs) uri++; /* skip ":" */ /* reset destination filename */ set_estr(dest_fname, ""); if (kind == URI_abs) { /* * parse absolute uri */ D(fprintf(stderr, DHL "exists `%s' [abs]\n", uri)); /* check if local uri exists */ { EXPSTR *dest_relfname = init_estr(32); conv_uri2path(dest_relfname, uri); estrcpy(dest_fname, hp->destdir); estrcat(dest_fname, dest_relfname); del_estr(dest_relfname); } D(fprintf(stderr, DHL " -> file `%s'\n", estr2str(dest_fname))); /* create path of destination file */ estrcpy(dest_uri, hp->reldir); app_estr(dest_uri, uri); get_relfname(rel_path, uri, estr2str(hp->reldir)); D(fprintf(stderr, DHL " -> rel. path `%s' (`%s')\n", estr2str(rel_path), estr2str(hp->reldir))); /* debug */ D(fprintf(stderr, DHL " -> real path `%s'\n", uri)); /* convert (filesystem depending) path to uri */ conv_path2uri(dest_uri, estr2str(rel_path)); /* debug */ D(fprintf(stderr, DHL " -> real uri `%s'\n", estr2str(dest_uri))); } else if (kind == URI_rel) { /* * parse relative uri */ EXPSTR *uri_path = init_estr(32); /* debug */ D(fprintf(stderr, DHL "exists `%s' [rel]\n", uri)); /* create local filename */ conv_uri2path(uri_path, uri); estrcat(dest_fname, hp->destdir); estrcat(dest_fname, hp->reldir); estrcat(dest_fname, uri_path); /* create uri (only copy path) */ set_estr(dest_uri, uri); /* debug */ D( { fprintf(stderr, DHL " -> real path `%s'\n", estr2str(dest_fname)); fprintf(stderr, DHL " -> real uri `%s'\n", estr2str(dest_uri)); } );
/* * convert uri to filename in destination-dir */ static VOID conv_hscuri2fileNuri(HSCPRC * hp, EXPSTR * dest_uri, EXPSTR * dest_fname, STRPTR uri) { EXPSTR *rel_path = init_estr(32); /* relative path */ URIKIND kind = uri_kind(uri); clr_estr(dest_uri); clr_estr(dest_fname); if (kind == URI_relserv) { /* skip "/" in URI */ STRPTR uri2 = uri + 1; /* debug */ D(fprintf(stderr, DHL "exists `%s' [relserv]\n", uri)); /* convert server relative URI to local filename * by preceding server_dir */ conv_uri2path(rel_path, uri2, hp->weenix); estrcpy(dest_fname, hp->server_dir); estrcat(dest_fname, rel_path); /* debug */ D(fprintf(stderr, DHL " server-dir=`%s'\n", estr2str(hp->server_dir))); D(fprintf(stderr, DHL " rel. path =`%s'\n", estr2str(rel_path))); /* keep URI untouched */ set_estr(dest_uri, uri); } else { /* convert relative/project uris */ /* if a <BASE HREF="..."> was found before, * treat all relative URIs as absolute */ if (hp->docbase_set) { kind = URI_ext; } /* evaluate kind of URI */ if (kind == URI_abs) { uri++; /* skip ":" */ } if (kind == URI_abs) { /* * parse absolute uri */ D(fprintf(stderr, DHL "exists `%s' [abs]\n", uri)); /* check if local uri exists */ { EXPSTR *dest_relfname = init_estr(32); conv_uri2path(dest_relfname, uri, hp->weenix); estrcpy(dest_fname, hp->destdir); estrcat(dest_fname, dest_relfname); del_estr(dest_relfname); } D(fprintf(stderr, DHL " -> file `%s'\n", estr2str(dest_fname))); /* create path of destination file */ estrcpy(dest_uri, hp->reldir); app_estr(dest_uri, uri); get_relfname(rel_path, uri, estr2str(hp->reldir)); D(fprintf(stderr, DHL " -> rel. path `%s' (`%s')\n", estr2str(rel_path), estr2str(hp->reldir))); /* debug */ D(fprintf(stderr, DHL " -> real path `%s'\n", uri)); /* convert (filesystem depending) path to uri */ conv_path2uri(dest_uri, estr2str(rel_path)); } else if (kind == URI_rel) { /* * parse relative uri */ EXPSTR *uri_path = init_estr(32); /* debug */ D(fprintf(stderr, DHL "exists `%s' [rel]\n", uri)); /* create local filename */ conv_uri2path(uri_path, uri, hp->weenix); estrcat(dest_fname, hp->destdir); estrcat(dest_fname, hp->reldir); estrcat(dest_fname, uri_path); /* create uri (only copy path) */ set_estr(dest_uri, uri); del_estr(uri_path); } else { set_estr(dest_uri, uri); set_estr(dest_fname, ""); } } /* debug */ D( { fprintf(stderr, DHL " -> real file `%s'\n", estr2str(dest_fname)); fprintf(stderr, DHL " -> real uri `%s'\n", estr2str(dest_uri)); } );
/* * handle_content_macro * * handle for content macros * (with /CLOSE set at declaration) * * - scan macro content until corresponding end macro * tag is found * - increase scope * - define local HSC.CONTENT * - include macro text (not content!) * - remove HSC.CONTENT * */ static BOOL handle_content_macro(HSCPRC * hp, HSCTAG * tag) { EXPSTR *macro_content = init_estr(1024); /* contains macro contents */ HSCATTR *macro_content_attr = find_varname(hp->defattr, CONTENT_ATTR); /* attribute that contains contents, too */ HSCTAG *end_macro = NULL; STRPTR old_content = NULL; /* to store old value of content attr */ /* position where content starts */ INFILEPOS *start_content_fpos = new_infilepos(hp->inpf); DMC(fprintf(stderr, DHL "--BEGIN content macro <%s>\n", tag->name)); if (!macro_content_attr) { panic("no content attribute") } /* skip macro content until corresponding end macro is found; store * content in macro_content, but without the tag call for the end macro */ skip_until_tag(hp, macro_content, NULL, NULL, tag->name, SKUT_NO_CONTENT_TAGFOUND); /* store current value of content attribute */ { STRPTR old = get_vartext(macro_content_attr); if (old) { old_content = strclone(old); } } /* set content attribute with current macro content */ set_vartext(macro_content_attr, estr2str(macro_content)); /* push content to content stack */ add_strnode(hp->content_stack, estr2str(macro_content)); /* some debuggin info */ DMC(fprintf(stderr, DHL " content=`%s'\n", estr2str(macro_content))); DMC(fprintf(stderr, DHL " text =`%s'\n", estr2str(tag->op_text))); /* push current tag on container stack; this is * only necessary for tag modifiers /MCI and * /NAW, which would not work otherwise */ end_macro = append_end_tag(hp, tag); /* assign position of start of content to macro-tag */ end_macro->end_fpos = start_content_fpos; /* now include the macro text */ include_macro(hp, tag, estr2str(tag->op_text), SPECIAL_FILE_ID "content-macro", tag->start_fpos); /* pull macro tag from container stack */ end_macro->end_fpos = NULL; remove_end_tag(hp, tag); /* restore content attribute to previous value */ set_vartext(macro_content_attr, old_content); /* remove content from stack */ del_dlnode(hp->content_stack, dll_first(hp->content_stack)); /* cleanup */ ufreestr(old_content); del_estr(macro_content); del_infilepos(start_content_fpos); DMC(fprintf(stderr, DHL "--END content macro <%s>\n", tag->name)); return (FALSE); }
/* * 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); }
/* **------------------------------------- ** <$SOURCE> include a source part **------------------------------------- */ BOOL handle_hsc_source( INFILE *inpf, HSCTAG *tag ) { BOOL pre = get_varbool( tag->attr, "PRE" ); BOOL ok = TRUE; EXPSTR *bufstr = NULL; EXPSTR *srcstr = NULL; LONG nesting = 0; BYTE state = SRST_TEXT; STRPTR nw = NULL; /* ** read until </$SOURCE> found */ /* init bufstr */ bufstr = init_estr( ES_STEP_SOURCE ); srcstr = init_estr( ES_STEP_SOURCE ); if ( !(bufstr && srcstr ) ) err_mem( inpf ); while ( !(fatal_error || (state==SRST_CSOURCE) ) ) { /* read next word */ if ( state == SRST_SLASH ) nw = infget_tagid( inpf ); else if ( state != SRST_TAG ) nw = infgetw( inpf ); if ( nw ) { if ( state == SRST_TAG ) { /* ** skip inside tags */ BYTE tag_state = TGST_TAG; /* state var passe to */ /* eot_reached() */ do { if ( eot_reached( inpf, &tag_state ) ); state = SRST_TEXT; if ( !( app_estr( srcstr, infgetcws( inpf ) ) && app_estr( srcstr, infgetcw( inpf ) ) ) ) err_mem( inpf ); } while ( (tag_state!=TGST_END) && !fatal_error ); } else { switch ( state ) { case SRST_TEXT: if ( !strcmp( nw, "<" ) ) state = SRST_LT; break; case SRST_LT: if ( !strcmp( nw, "/" ) ) state = SRST_SLASH; else if ( !upstrcmp( nw, HSC_COMMENT_STR ) ) { state = SRST_COMT; } else { /* handle "<$SOURCE" (open source) */ if ( !upstrcmp( nw, HSC_SOURCE_STR ) ) nesting++; /* incr. source nesting */ state = SRST_TAG; } break; case SRST_SLASH: if ( !upstrcmp( nw, HSC_SOURCE_STR ) ) /* handle "</$SOURCE" (close source) */ if ( nesting ) nesting--; /* decr. source nesting */ else state = SRST_CSOURCE; /* end of source */ else state = SRST_TAG; break; } if ( state == SRST_TEXT ) { /* append current white spaces & word to srcstr */ if ( !( app_estr( srcstr, infgetcws( inpf ) ) && app_estr( srcstr, infgetcw( inpf ) ) ) ) err_mem( inpf ); } else if ( ( state == SRST_COMT ) || ( state == SRST_TAG ) ) { /* append bufstr to srcstr, clear bufstr, ** append current word to srcstr */ if ( !( app_estr( srcstr, estr2str(bufstr) ) && set_estr( bufstr, "" ) && app_estr( srcstr, infgetcws( inpf ) ) && app_estr( srcstr, infgetcw( inpf ) ) ) ) err_mem( inpf ); } else { /* append current white spaces & word to srcstr */ if ( !( app_estr( bufstr, infgetcws( inpf ) ) && app_estr( bufstr, infgetcw( inpf ) ) ) ) err_mem( inpf ); } /* ** skip hsc comment */ if ( state == SRST_COMT ) { BYTE cstate = CMST_TEXT; /* vars for eoc_reached() */ LONG cnest = 0; BOOL end = FALSE; /* end of comment reached? */ while ( !end && !fatal_error ) { end = eoc_reached( inpf, &cstate, &cnest ); if ( !( app_estr( srcstr, infgetcws( inpf ) ) && app_estr( srcstr, infgetcw( inpf ) ) ) ) err_mem( inpf ); } state = SRST_TEXT; /* reset state after comment */ } } } else { err_eof( inpf, "missing </" HSC_SOURCE_STR ">" ); state = SRST_ERR; } } /* while */ /* check for legal end state */ if ( state == SRST_CSOURCE ) { ok = parse_wd( inpf, ">" ); } /* include source */ if ( ok ) { if ( pre ) include_hsc_string( "[include <PRE>]", "<PRE>\n", outfile, IH_PARSE_HSC ); include_hsc_string( "[SOURCE]", estr2str( srcstr ), outfile, IH_PARSE_SOURCE ); if ( pre ) include_hsc_string( "[include </PRE>]", "</PRE>\n", outfile, IH_PARSE_HSC ); } del_estr( bufstr ); del_estr( srcstr ); return ( ok ); }