/* * new_hsctag * * alloc & init a new hsctag */ HSCTAG *new_hsctag(STRPTR newid) { HSCTAG *newtag = (HSCTAG*) umalloc(sizeof(HSCTAG)); if (newtag) { /* init new tag item */ newtag->name = upstr(strclone(newid)); /* set id */ newtag->option = 0; 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 = NULL; newtag->naw = NULL; newtag->uri_size = NULL; newtag->uri_stripext = NULL; newtag->start_fpos = NULL; newtag->end_fpos = NULL; if (!(newtag->name && newtag->attr)) { del_hsctag(newtag); newtag = NULL; } } return (newtag); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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 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); }
/* * init_strlist: set up new list of strings */ DLLIST *init_strlist(void) { return (init_dllist(del_string_node)); }
/* ** prepare_args ** ** convert argument definitions to dllist of struct arginfo ** */ struct arglist *prepare_args( STRPTR arglist_name, ... ) { va_list ap; struct dllist *newlist; struct arginfo *newarg; struct arglist *new_arglist = NULL; clr_preperr(); /* clear error vars */ /* ** alloc & init _new_arglist */ new_arglist = ( struct arglist *) umalloc( sizeof( struct arglist ) ); if ( new_arglist ) { new_arglist->al_name = arglist_name; new_arglist->al_list = NULL; new_arglist->al_multiple = NULL; new_arglist->al_nokeywd = NULL; } else set_preperr( APE_NO_MEM, 0); /* ** TODO: don't go into if(), when new_arglist failed */ /* ** convert template to double linked list */ newlist = init_dllist( del_arginfo ); if ( newlist ) { STRPTR nxtdef = NULL; /* next template definition */ va_start( ap, arglist_name ); do { ufree( nxtdef ); nxtdef = va_arg( ap, STRPTR ); /* get next definition */ /* clone nxtdef: this is necessary because on unix-systems, */ /* you can not let strtok() run on strings received with */ /* va_arg() -> bus error */ nxtdef = strclone( nxtdef ); prep_error_idx++; if ( nxtdef ) { newarg = umalloc( sizeof( struct arginfo) ); if ( newarg ) { STRPTR new_id; STRPTR typestr; STRPTR flagstr; STRPTR enumstr; /* enum string for type 'E' */ LONG new_type = 0; LONG new_flags = 0; LONG rnlolim = 0; LONG rnhilim = 0; /* init _newarg */ newarg->ai_id = NULL; newarg->ai_type = 0; newarg->ai_flags = 0; newarg->ai_misc1.ai_lolim = 0; newarg->ai_misc2.ai_uplim = 0; newarg->ai_dest = NULL; newarg->ai_func = NULL; newarg->ai_help = NULL; new_id = strtok( nxtdef, "/" ); typestr = strtok( NULL, "/" ); /* ** get argument type */ if ( typestr ) { if ( strlen( typestr ) == 1 ) { switch ( toupper( typestr[0] ) ) { case 'T': new_type = ARG_TEXT; break; case 'S': new_type = ARG_SWITCH; break; case 'N': new_type = ARG_LONG; break; case 'R': new_type = ARG_LONG_RANGE; break; case 'E': new_type = ARG_ENUM; break; } if ( new_type ) /* arg-type specified? */ flagstr = /* Y-> get next flag */ strtok( NULL, "/" ); else { flagstr = typestr; /* N-> must be flag */ new_type = ARG_TEXT; /* set type to text */ } } else set_preperr( APE_INVALID_TEMPLATE, 0 ); } else { /* no type at all */ flagstr = NULL; /* -> no flags also */ new_type = ARG_TEXT; /* set type to text */ } /* if typestr */ /* ** get argument flags */ while ( flagstr && flagstr[0] && no_preperr ) { switch ( toupper( flagstr[0] ) ) { case 'M': new_flags |= ARG_MULTIPLE; break; case 'A': new_flags |= ARG_REQUIRED; break; case 'K': new_flags |= ARG_KEYWORD; break; case 'O': new_flags |= ARG_OVERWRITE; break; case '$': new_flags |= ARG_HANDLEFUNC; break; default: set_preperr( APE_ILLEGAL_FLAG, 0); break; } /* switch */ flagstr = strtok( NULL, "/" ); } /* while */ if ( no_preperr ) { /* ** get additional arguments */ if ( new_flags & ARG_HANDLEFUNC ) { /* ** get handler function */ #if 1 APTR func_tmp = va_arg( ap, STRPTR ); newarg->ai_func = (STRPTR (*) (STRPTR) ) func_tmp; #else /* tricky type-cast, 1-step-version, does */ /* not work with several compilers */ newarg->ai_func = va_arg( ap, STRPTR (*) (STRPTR) ); #endif } if ( new_type == ARG_LONG_RANGE ) { /* ** get range limits */ rnlolim = va_arg( ap, LONG ); rnhilim = va_arg( ap, LONG ); } else if ( new_type == ARG_ENUM ) { /* ** get enum string */ enumstr = va_arg( ap, STRPTR ); } if ( no_preperr ) { newarg->ai_id = strclone( new_id ); /* sux */ newarg->ai_type = new_type; newarg->ai_flags = new_flags; newarg->ai_dest = va_arg( ap, APTR ); newarg->ai_help = strclone( va_arg( ap, STRPTR ) ); /* ** set additional argument information ** (->misc1, ->misc2) */ switch ( new_type ) { case ARG_ENUM: newarg->ai_misc1.ai_enum = strclone( enumstr ); if ( !(newarg->ai_misc1.ai_enum) ) set_preperr( APE_NO_MEM, 0 ); break; case ARG_LONG_RANGE: newarg->ai_misc1.ai_lolim = rnlolim; newarg->ai_misc2.ai_uplim = rnhilim; break; } /* ** check for NULL as destination var */ if ( newarg->ai_dest == NULL ) set_preperr( APE_DESTVAR_IS_NULL, 0 ); } /* ** check, if arg multiple arg without keyword */ if ( new_flags & ARG_MULTIPLE ) if ( !(new_flags & ARG_KEYWORD) ) if ( new_arglist->al_multiple ) set_preperr( APE_DOUBLE_MULTIPLE, 0 ); else new_arglist->al_multiple = newarg; /* ** append new argument entry to list */ if ( no_preperr ) if ( app_dlnode( newlist, (APTR) newarg ) == NULL ) set_preperr( APE_NO_MEM, 0 ); /* free _newarg if any error occured */ if ( any_preperr ) del_arginfo( (APTR) newarg ); } } else set_preperr( APE_NO_MEM, 0 ); } } while ( nxtdef && no_preperr );
/* * set_arg_value * * sets argument _ai->ai_dest with value specified in _arg * */ static UBYTE set_arg_value(struct arginfo *ai, STRPTR arg, STRPTR arg2, BOOL keywd) { APTR dest = ai->ai_dest; STRPTR param; UBYTE arg_incr = 0; /* set to 1 if arg2 is used */ BOOL arg2used = FALSE; /* evaluate parameter: */ /* if arg is equal to arg-id of ai (no other chars */ /* following), the param is taken from the next arg. */ /* otherwise, the arg is scanned for '=' and the */ /* rest of the arg is taken as param */ if (keywd && !(ai->ai_type == ARG_SWITCH)) { param = arg; while (param[0] && (param[0] != '=')) param++; if (param[0]) param++; else { param = arg2; arg2used = TRUE; if (!param) set_argerr(ASE_REQUIRED_MISS, arg); } } else param = arg; /* * set switch/arg-value */ if (no_argerr) { if (ai->ai_func) { /* call handle function with arg value */ arg_error_hfs = (*(ai->ai_func)) (param); if (arg_error_hfs) set_argerr(ASE_HANDLE_FUNC, param); } else if (ai->ai_type == ARG_SWITCH) /* switch */ *((BOOL *) dest) = TRUE; else { /* * check if argument already set */ if (ai->ai_set && !((ai->ai_flags & ARG_OVERWRITE) || (ai->ai_flags & ARG_MULTIPLE)) ) set_argerr(ASE_OCCURED_TWICE, arg); else ai->ai_set = TRUE; if (no_argerr) { APTR aparam = NULL; DLLIST **dest_list = (DLLIST **) dest; LONG along; /* * get new value and store it in aparam */ if (!param) /* missing param */ set_argerr(ASE_NO_VAL_AFTER_KW, arg); if (ai->ai_type == ARG_TEXT) /* text */ aparam = (APTR) param; else if (ai->ai_type == ARG_LONG) { /* long */ if (!str2long(param, &along)) set_argerr(ASE_INVALID_NUM, arg); else aparam = (APTR) along; /* what a pervert! */ } else if (ai->ai_type == ARG_ENUM) { LONG aenum = strenum(param, ai->ai_misc1.ai_enum, '|', STEN_NOCASE); if (!aenum) set_argerr(ASE_INVALID_ENUM, arg); else aparam = (APTR) aenum; /* what a pervert! */ } #if 0 if (!param) /* missing param */ set_argerr(ASE_NO_VAL_AFTER_KW, arg); if (ai->ai_type == ARG_TEXT) /* text */ *((STRPTR *) dest) = param; else if (ai->ai_type == ARG_LONG) { /* long */ if (!str2long(param, (LONG *) dest)) set_argerr(ASE_INVALID_NUM, arg); } #endif /* * set new value */ if (no_argerr) if (ai->ai_flags & ARG_MULTIPLE) { if (!(*dest_list)) *dest_list = init_dllist(NULL); if (*dest_list) { if (!app_dlnode(*dest_list, aparam)) set_argerr(APE_NO_MEM, arg); } else set_argerr(APE_NO_MEM, arg); } else { if (ai->ai_type == ARG_LONG) *((LONG *) dest) = (LONG) aparam; else if (ai->ai_type == ARG_ENUM) *((LONG *) dest) = (LONG) aparam; else if (ai->ai_type == ARG_TEXT) *((STRPTR *) dest) = (STRPTR) aparam; } } } if (arg2used) /* set return value that arg2 */ arg_incr = 1; /* is skipped outside this func */ } return (arg_incr); }