/* 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); }
/* * check_id_local * * append id to idref-list so it as checked when * check_all_local_idref() is called */ VOID add_local_idref(HSCPRC * hp, STRPTR id) { INFILEPOS *fpos = new_infilepos(hp->inpf); DIHP(fprintf(stderr, DHL " check id: `#%s' (local)\n", id)); DIHP(fprintf(stderr, DHL " append to idref\n")); app_dlnode(hp->idrefs, new_idref(id, fpos)); }
/* * hsc_parse_end * * check for all tags closed and required * tags occured */ BOOL hsc_parse_end(HSCPRC * hp) { if (!hp->fatal) { /* remember current file position */ INFILEPOS *infpos = new_infilepos(hp->inpf); DLNODE *nd = NULL; /* check for unclosed containers: * for every container tag still on stack launch a message, * exept for autoclose tags */ nd = hp->container_stack->last; while (nd) { HSCTAG *endtag = (HSCTAG *) dln_data(nd); if (!(endtag->option & HT_AUTOCLOSE)) { set_infilepos(hp->inpf, endtag->start_fpos); hsc_message(hp, MSG_MISS_CTAG, "%c missing", endtag->name); } nd = dln_prev(nd); } /* restore file position */ set_infilepos(hp->inpf, infpos); del_infilepos(infpos); /* check for required and recommended tags missing */ nd = dll_first(hp->deftag); while (nd) { HSCTAG *tag = (HSCTAG *) dln_data(nd); if ((tag->option & HT_REQUIRED && (tag->occured == FALSE))) { hsc_message(hp, MSG_MISS_REQTAG, "required %T missing", tag); } else if ((tag->option & HT_RECOMMENDED && (tag->occured == FALSE))) { hsc_message(hp, MSG_MISS_RCMDTAG, "recommended %T missing", tag); } nd = dln_next(nd); } /* output last white spaces at eof */ hsc_output_text(hp, "", ""); } return (BOOL) (!hp->fatal); }
/* * postprocess_attributes * * This function scans a tag's list of attributes for URI-attributes * referring to an external URI. If it succeeds, and the hsc-process * has it's hp->strip_ext flag enabled, the function exits. * * Otherwise, it scans the attributes for new IDs and references * and updates the document data if neccessary (but only for start tags) * * params: * hp ........ hsc-process * tag ....... tag whose attribute list should be examined * open_tag .. for end tags, the document-data should not be * updated again * result: * TRUE, if tag should NOT be stripped */ BOOL postprocess_tagattr(HSCPRC * hp, HSCTAG * tag, BOOL open_tag) { BOOL dontstrip = TRUE; if (tag->attr) { /* * find out, if list should be refused */ if (hp->strip_ext && tag->uri_stripext && get_vartext(tag->uri_stripext) && (uri_kind(get_vartext(tag->uri_stripext)) == URI_ext) ) { D(fprintf(stderr, DHL "strip external\n")); dontstrip = FALSE; } else if (open_tag) { /* * search for new IDs and references */ DLNODE *nd = dll_first(tag->attr); while (nd) { HSCATTR *attrib = (HSCATTR *) dln_data(nd); STRPTR value = get_vartext(attrib); if (value) { if (attrib->vartype == VT_URI) { /* new reference */ INFILEPOS *fpos = new_infilepos(hp->inpf); CALLER *newcaller = fpos2caller(fpos); HSCREF *newref = app_reference(hp->project->document, value); newref->caller = newcaller; del_infilepos(fpos); D(fprintf(stderr, DHL "new REFERENCE: `%s'\n", value)); } else if (attrib->vartype == VT_ID) { /* new id defined */ D(fprintf(stderr, DHL "new ID: `%s'\n", value)); add_local_iddef(hp, value); } } nd = dln_next(nd); } } } return (dontstrip); }
/* * append_end_tag * * create end tag and append it to tag-list; * also clone options & attribute list of parent * tag, if tag is a macro and has a closing tag. * * params: hp.....hscprc with container_stack to be modified * tagid..name of the new tag (eg "IMG") * result: ptr to the new tag or NULL if no mem */ HSCTAG *append_end_tag(HSCPRC * hp, HSCTAG * tag) { HSCTAG *end_tag; DLLIST *taglist = hp->container_stack; end_tag = new_hsctag(tag->name); if (end_tag) { BOOL ok = TRUE; DLNODE *nd = NULL; /* copy important data of tag */ end_tag->option = tag->option; /* clone attributes, if tag is a * macro tag and has a closing tag */ if ((tag->option & HT_MACRO) && (tag->option & HT_CLOSE)) { ok = copy_local_varlist(end_tag->attr, tag->attr, MCI_APPCTAG); } /* remeber position where start tag has been called */ /* (for message "end tag missing) */ end_tag->start_fpos = new_infilepos(hp->inpf); #if 0 /* TODO: remove this */ /* for container macros, remember position where content starts */ end_tag->end_fpos = clone_infilepos(tag->end_fpos); #endif /* insert tag in list */ if (ok) { nd = app_dlnode(taglist, end_tag); if (!nd) { del_hsctag((APTR) end_tag); end_tag = NULL; } } } return (end_tag); }
/* * app_ctag * * create end tag and append it to tag-list; * also clone options & attribute list of parent * tag, if tag is a macro and has a closing tag. * * params: hp.....hscprc with container_stack to be modified * tagid..name of the new tag (eg "IMG") * result: ptr to the new tag or NULL if no mem */ HSCTAG *app_ctag(HSCPRC * hp, HSCTAG * tag) { HSCTAG *ctag; DLLIST *taglist = hp->container_stack; ctag = new_hsctag(tag->name); if (ctag) { BOOL ok = TRUE; DLNODE *nd = NULL; /* copy important data of tag */ ctag->option = tag->option; /* clone attributes, if tag is a * macro tag and has a closing tag */ if ((tag->option & HT_MACRO) && (tag->option & HT_CLOSE)) { ok = copy_local_varlist( ctag->attr, tag->attr, MCI_APPCTAG); } /* remeber position where start tag has been called */ /* (for message "end tag missing) */ ctag->start_fpos = new_infilepos(hp->inpf); /* insert tag in list */ if (ok) { nd = app_dlnode(taglist, ctag); if (!nd) { del_hsctag((APTR) ctag); ctag = NULL; } } } return (ctag); }
/* * hsc_parse_end * * check for all tags closed and required * tags occured */ BOOL hsc_parse_end(HSCPRC * hp) { if (!hp->fatal) { INFILEPOS *infpos = new_infilepos(hp->inpf); /* check for unclosed containers */ DLNODE *nd = hp->container_stack->first; while (nd) { HSCTAG *endtag = (HSCTAG *) dln_data(nd); set_infilepos(hp->inpf, endtag->start_fpos); hsc_message(hp, MSG_MISS_CTAG, "%c missing", endtag->name); nd = dln_next(nd); } set_infilepos(hp->inpf, infpos); del_infilepos(infpos); /* check for required tags missing */ nd = hp->deftag->first; while (nd) { HSCTAG *tag = (HSCTAG *) nd->data; if ((tag->option & HT_REQUIRED && (tag->occured == FALSE))) { hsc_message(hp, MSG_MISS_REQTAG, "required %T missing", tag); } nd = nd->next; } } return (BOOL) (!hp->fatal); }
/* * add_local_iddef * * define a new local ID that can be refered to */ BOOL add_local_iddef(HSCPRC * hp, STRPTR id) { INFILEPOS *fpos = new_infilepos(hp->inpf); HSCIDD *iddef = find_iddef(hp->project->document, id); DIHP(fprintf(stderr, DHL "add ref to id `%s' at `%s' (%lu,%lu)\n", id, ifp_get_fname(fpos), ifp_get_y(fpos), ifp_get_x(fpos))); /* check for duplicate definition */ if (iddef) { /* duplicate definition */ DIHP(fprintf(stderr, DHL " duplicate definition\n")); hsc_message(hp, MSG_REDEFINE_ID, "local id %q already declared", id); set_infilepos(hp->inpf, iddef->fpos); hsc_message(hp, MSG_REDEFINE_ID, "(location of previous declaration)"); set_infilepos(hp->inpf, fpos); del_infilepos(fpos); } else { /* remember new local id */ iddef = app_iddef(hp->project->document, id); iddef->caller = fpos2caller(fpos); iddef->fpos = fpos; DIHP(fprintf(stderr, DHL " append to local iddefs\n")); } return (TRUE); }
BOOL handle_hsc_content(HSCPRC * hp, HSCTAG * tag) { HSCATTR *content_attr = find_varname(hp->defattr, CONTENT_ATTR); /* attribute that contains content */ HSCTAG *macro = find_end_container_macro(hp); /* use current fileposition as base for including content */ INFILEPOS *fpos = new_infilepos(hp->inpf); if (!macro) { DMC(fprintf(stderr, DHL " no container macro on stack\n")); hsc_msg_no_content(hp); } else if (content_attr) { /* position where content text started */ INFILEPOS *start_content_fpos = macro->end_fpos; /* first node on content stack contains current content text */ DLNODE *first_content_text_node = dll_first(hp->content_stack); if (first_content_text_node) { /* pull first entry from content stack */ STRPTR content = (STRPTR) detach_dlnode(hp->content_stack, first_content_text_node); STRPTR old_content = strclone(get_vartext(content_attr)); DLLIST *old_attribs = init_dllist(del_hscattr); ULONG scope_id = get_current_mci(hp); DMC(fprintf(stderr, DHL " content=`%s'\n", content)); /* update content attribute */ set_vartext(content_attr, content); #ifndef EXPERIMENTAL_CONTAINER /* move local attributes from global list to buffer list */ copy_local_varlist(old_attribs, hp->defattr, scope_id); remove_local_varlist(hp->defattr, scope_id); /* switch back to above scope */ unget_mci(hp); #endif /* now include the macro content */ hsc_base_include_string(hp, SPECIAL_FILE_ID "macro-content", content, IH_NO_STATUS | IH_PARSE_MACRO, start_content_fpos); /* TODO: why IH_PARSE_MACRO? */ /* push entry pulled above back to content stack */ add_dlnode(hp->content_stack, content); #ifndef EXPERIMENTAL_CONTAINER /* restore local attribs and scope from before */ copy_local_varlist(hp->defattr, old_attribs, scope_id); get_mci(hp); #endif /* restore content attribute */ set_vartext(content_attr, old_content); /* free resources */ del_dllist(old_attribs); ufreestr(old_content); } else { DMC(fprintf(stderr, DHL " no content\n")); hsc_msg_no_content(hp); } } else { panic("no content attribute"); } /* cleanup */ del_infilepos(fpos); return (FALSE); }
/* * 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); }
int main( int argc, char *argv[] ) { INFILE *inpf; INFILEPOS *pos1 = NULL; INFILEPOS *pos2 = NULL; char *fname; char ch; size_t i; char getstr[GETSTRLEN+1]; char *wdbuf; #if DEBUG_UGLY_MEMORY atexit( atexit_uglymemory ); #endif if ( argc == 1 ) fname = "hugo.txt"; else fname = argv[1]; errno = 0; inpf = infopen( fname, 0 ); if ( inpf ) { #if 1 /* info about first word */ wdbuf = infgetw( inpf ); printf( "word#0: \"%s\", \"%s\"\n", infgetcws( inpf ), infgetcw( inpf ) ); /* ** get 10 chars, print them, ** and put them back again */ ch = '*'; /* dummy */ for ( i=0; i<GETSTRLEN; i++ ) getstr[i] = infgetc( inpf ); getstr[i] = '\0'; printf( "got : \"%s\"\nback: \"", getstr ); for ( ; i>0; i-- ) { ch = getstr[i-1]; printf( "%c", ch ); inungetc( ch, inpf ); } printf( "\"\n" ); #endif /* ** read the first 3 words */ for ( i=0; i<3; i++ ) { wdbuf = infgetw( inpf ); printf( "word#%lu: [%lu] \"%s\"\n", (ULONG) i, (ULONG) strlen(wdbuf), wdbuf ); } /* info about current word */ printf( "current word: \"%s\", \"%s\"\n", infgetcws( inpf ), infgetcw( inpf ) ); /* ** unget last word */ inungetcw( inpf ); wdbuf = infgetw( inpf ); printf( "reword: [%lu] \"%s\"\n", (ULONG) strlen(wdbuf), wdbuf ); /* remember current position */ pos1 = new_infilepos( inpf ); /* ** read and print rest of file */ while ( !infeof( inpf ) ) { ch = infgetc( inpf ); if ( !infeof( inpf ) ) { printf( "%c", ch ); fflush( stdout ); /* flush output -> slow */ } } pos2 = new_infilepos( inpf ); printf( "pos#1: %s (%lu,%lu)\n", ifp_get_fname( pos1 ), ifp_get_x( pos1 ), ifp_get_y( pos1 ) ); del_infilepos( pos1 ); infclose( inpf ); printf( "pos#2: %s (%lu,%lu)\n", ifp_get_fname( pos2 ), ifp_get_x( pos2 ), ifp_get_y( pos2 ) ); del_infilepos( pos2 ); } else perror( "Can't open input file" ); /* test a string file */ inpf = infopen_str( "test string", "this is\n a string\n converted\n to an\n input file.", 0 ); if ( inpf ) { wdbuf = infgetw( inpf ); while ( wdbuf ) { printf( "%s%s", infgetcws( inpf ), infgetcw( inpf )); wdbuf = infgetw( inpf ); } infclose( inpf ); } else perror( "Can't open input file from string" ); printf( "\n" ); return( 0 ); }