/* ** check_enumstr: check if a given value is a legal enum value */ BOOL check_enumstr( HSCVAR *var, STRPTR value, INFILE *inpf ) { STRPTR enumcp = strclone( var->enumstr ); /* clone of enumstr */ BOOL found = FALSE; /* flag: TRUE, if value found within enumstr */ BOOL any = FALSE; /* flag: TRUE, if "*" was within enumstr */ if ( enumcp ) { STRPTR word = strtok( enumcp, "|" ); /* search for value in enumcp */ while ( word && !found ) { if ( !strcmp( word, "*" ) ) any = TRUE; if ( !upstrcmp( word, value ) ) found = TRUE; word = strtok( NULL, "|" ); } ufreestr( enumcp ); /* check result, display messages if neccessary */ if ( !found ) { if ( !any ) { /* unknown enum value */ message( MSG_ENUM_UNKN, inpf ); errstr( "unknown" ); } else { /* suspicious enum value */ message( MSG_ENUM_SUSPICIOUS, inpf ); errstr( "suspicious" ); } errstr( " value " ); errqstr( value ); errstr( " for" ); errsym( var->name ); errlf(); } else DDA( fprintf( stderr, "** enum \"%s\" ok for %s\n", value, var->name ) ); } else err_mem( inpf ); return( found ); }
/* ** check_varlist: check for required attributes missing ** ** result: TRUE, if all attributes ok */ BOOL check_reqvar( HSCVAR *var, INFILE *inpf ) { BOOL ok = TRUE; if ( (var->varflag & VF_REQUIRED) && (!var->text) ) { message( MSG_MISS_REQ_ATTR, inpf ); errstr( "required" ); errsym( var->name ); errstr( "missing\n" ); ok = FALSE; } return( ok ); }
void func(int errcand, void *arg) { char *sym = errsym(errcand); char *msg; if (sym) return; errno = 0; msg = strerror(errcand); if (msg && !errno) { /* * strerror() return value for unknown errors: * - GNU/Linux: "Unknown error NNN" * - NetBSD: "Unknown error: NNN" * - Minix: "Undefined error: NNN" * - SunOS: "Error NNN" * - Haiku: * "Unknown General Error (-NNNNNNNNNN)" * "Unknown OS Error (-NNNNNNNNNN)" * "Unknown MIME type" * "Unknown Application Kit Error (-NNNNNNNNNN)" * "Unknown Interface Kit Error (-NNNNNNNNNN)" * "Unknown Media Kit Error (-NNNNNNNNNN)" * "Unknown Translation Kit Error (-NNNNNNNNNN)" * "Unknown Midi Kit Error (-NNNNNNNNNN)" * "Unknown Storage Kit Error (-NNNNNNNNNN)" * "Unknown POSIX Error (-NNNNNNNNNN)" * "No Error (NNN)" */ #define START_WITH(prefix) (strncmp(msg, (prefix), sizeof(prefix)-1) == 0) if (START_WITH("Unknown ") || START_WITH("No Error (") || START_WITH("Error ") || START_WITH("Undefined ")) return; #undef START_WITH printf("%d = %s\n", errcand, msg); } }
/* ** define_var ** ** define a new var with reading its def from input file ** (starts parsing after ":", so ":" has to be read before) ** ** params: varname..name of new var ** varlist..list new var should be inserted at the beginning ** inpf.....input file where to read def from ** flag.....flags: VF_ONLYONCE to avoid re-definition of a var ** result: ptr to new var ** ** definition syntax in input file: ** <vartype>[/flag]["="<deftext value>] ** legal vartypes: see VT_STR_xx in "vars.h" ** legal flags : see VF_STR_xx in "vars.h" */ HSCVAR *define_var( STRPTR varname, DLLIST *varlist, INFILE *inpf, UBYTE flag ) { HSCVAR *var = NULL; /* result */ BOOL ok = FALSE; BYTE val_vartype = VT_NONE; /* var-type (numeric) */ BOOL newattr = FALSE; STRPTR nw = infgetw( inpf ); /* next word read from input */ /* read (optional) var type */ if ( nw ) { if ( !strcmp( nw, ":" ) ) { nw = infgetw( inpf ); if ( nw ) val_vartype = str2vartype( nw ); else err_eof( inpf, "defining attribute" ); } else inungetcw( inpf ); } else err_eof( inpf, "defining attribute" ); /* look if attr already exist, */ var = find_varname( varlist, varname ); if ( !var ) { /* create new attr */ DDA( fprintf( stderr, "** new attr: %s\n", varname ) ); var = app_var( varlist, varname ); if ( val_vartype == VT_NONE ) { /* TODO: error message "attr type expected" */ /* asume generic attribute type "STRING" */ val_vartype = VT_STRING; } /* set type */ var->vartype = val_vartype; /* init enum-attribute */ if ( var->vartype == VT_ENUM ) { var->varflag |= VF_NOQUOTE; read_enum_str( var, inpf ); } newattr = TRUE; } else { /* check for illegal redefinance */ if ( !( flag & VF_UPDATE ) ) { message( MSG_ATTR_REDEFINED, inpf ); errstr( "redefinance of" ); errsym( varname ); errlf(); } /* attr already exists: check for type consistence */ if ( ( val_vartype != VT_NONE ) && ( val_vartype != var->vartype ) ) { /* TODO: error message attr type inconsistent */ } } /* get next word */ nw = infgetw( inpf ); if ( !nw ) err_eof( inpf, "defining attribute" ); /* ** loop: handle flags and deftext value */ while ( nw ) { if ( !strcmp( nw, "=" ) ) { /* get new deftext value */ STRPTR new_deftext; if ( !(var->deftext) ) new_deftext = eval_expression( var, inpf, NULL ); else { STRPTR dummy; message( MSG_SYMB_2ND_DEFAULT, inpf ); errstr( "default value for" ); errsym( var->name ); errstr( "already set\n" ); /* skip illegal default value */ dummy = eval_expression( var, inpf, NULL ); } /* store default text value */ if ( new_deftext ) var->deftext = strclone( new_deftext ); /* check deftext value */ if ( var->vartype == VT_BOOL ) { /* check boolean value */ message( MSG_SYMB_BOOL_DEFAULT, inpf ); errstr( "no default value for boolean" ); errsym( var->name ); errstr( "allowed\n" ); } else if ( var->vartype == VT_NUM ) { /* TODO: test-set value with default value */ /* check numeric value */ LONG num; if ( sscanf( var->text, "%d", &num ) != strlen(var->text) ) { ok = FALSE; message( MSG_ILLEGAL_NUM, inpf ); errstr( "Illegal numeric value: " ); errstr( var->text ); errlf(); } } /* clear boolean var */ /* TODO: why set new bool to ""? */ if ( var->vartype == VT_BOOL ) { var->quote = VQ_NO_QUOTE; var->deftext = strclone( "" ); } } else if ( !strcmp( nw, "/" ) ) { /* set flag */ nw = infgetw( inpf ); if ( flag & VF_UPDATE ) { if ( nw ) { BOOL ok = FALSE; ok |= check_attr_option( nw, var, VF_JERK_STR, VF_JERK_SHT, VF_JERK ); ok |= check_attr_option( nw, var, VF_NOQUOTE_STR, VF_NOQUOTE_SHT, VF_NOQUOTE ); ok |= check_attr_option( nw, var, VF_ONLYONCE_STR, VF_ONLYONCE_SHT, VF_ONLYONCE ); ok |= check_attr_option( nw, var, VF_REQUIRED_STR, VF_REQUIRED_SHT, VF_REQUIRED ); if ( !ok ) { message( MSG_UNKN_ATTR_OPTION, inpf ); errstr( "Unknown attribute option " ); errqstr( nw ); errlf(); } } else err_eof( inpf, "defining attribute" ); } else { /* TODO: error message "no attr flags when updating" */ } } else { /* end of var definition reached */ inungets( nw, inpf ); nw = NULL; ok = TRUE; } /* get next word */ if ( nw ) nw = infgetw( inpf ); } /* while(nw) */ if ( !ok && var ) { del_dlnode( varlist, (APTR) var ); var = NULL; } return (var); }
/* ** 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 ); }
/* ** define_var ** ** define a new var with reading its def from input file ** (starts parsing after ":", so ":" has to be read before) ** ** params: varname..name of new var ** varlist..list new var should be inserted at the beginning ** inpf.....input file where to read def from ** flag.....flags: VF_ONLYONCE to avoid re-definition of a var ** result: ptr to new var ** ** definition syntax in input file: ** <vartype>[/flag]["="<deftext value>] ** legal vartypes: see VT_STR_xx in "vars.h" ** legal flags : see VF_STR_xx in "vars.h" */ HSCVAR *define_var( STRPTR varname, DLLIST *varlist, INFILE *inpf, UBYTE flag ) { HSCVAR *var = NULL; /* result */ BOOL ok = FALSE; STRPTR str_vartype = infgetw( inpf ); /* var-type (string) */ BYTE val_vartype = VT_NONE; /* var-type (numeric) */ /* evaluate var type */ if ( str_vartype ) val_vartype = str2vartype( str_vartype ); else err_eof( inpf, "defining attribute" ); if ( val_vartype == VT_NONE ) { /* illegal var type */ message( MSG_ILLEGAL_SYMB_TYPE, inpf ); errstr( "Illegal variable type \"" ); errstr( str_vartype ); errstr( "\"\n" ); } else { /* look if var already exist, */ /* create new var if neccessary */ var = find_varname( varlist, varname ); if ( !var ) { DDA( fprintf( stderr, "** new var: %s\n", varname ) ); var = app_var( varlist, varname ); } if ( !var ) err_mem( inpf ); else { STRPTR nw; /* next word from input file */ /* set vartype */ var->vartype = val_vartype; /* init enum-attribute */ if ( var->vartype == VT_ENUM ) { var->varflag |= VF_NOQUOTE; read_enum_str( var, inpf ); } /* get next word */ nw = infgetw( inpf ); if ( !nw ) err_eof( inpf, "defining attribute" ); /* ** loop: handle flags and deftext value */ while ( nw ) { if ( !strcmp( nw, "=" ) ) { /* get new deftext value */ STRPTR new_deftext; if ( !(var->deftext) ) new_deftext = parse_vararg( var, inpf ); else { message( MSG_SYMB_2ND_DEFAULT, inpf ); errstr( "Default value for" ); errsym( var->name ); errstr( "already set\n" ); } /* store default text value */ if ( new_deftext ) var->deftext = strclone( new_deftext ); /* check deftext value */ if ( var->deftext && clr_vartext( var ) ) { if ( var->vartype == VT_BOOL ) { /* check boolean value */ message( MSG_SYMB_BOOL_DEFAULT, inpf ); errstr( "No default value for boolean" ); errsym( var->name ); errstr( "allowed\n" ); } else if ( var->vartype == VT_NUM ) { /* check numeric value */ LONG num; if ( sscanf( var->text, "%d", &num ) != strlen(var->text) ) { ok = FALSE; message( MSG_ILLEGAL_NUM, inpf ); errstr( "Illegal numeric value: " ); errstr( var->text ); errlf(); } } } else err_mem( inpf ); /* clear boolean var */ if ( var->vartype == VT_BOOL ) { var->quote = VQ_NO_QUOTE; var->deftext = strclone( "" ); if ( !var->deftext ) err_mem( inpf ); } } else if ( !strcmp( nw, "/" ) ) { /* set flag */ nw = infgetw( inpf ); if ( nw ) { BOOL ok = FALSE; ok |= check_attr_option( nw, var, VF_JERK_STR, VF_JERK_SHT, VF_JERK ); ok |= check_attr_option( nw, var, VF_NOQUOTE_STR, VF_NOQUOTE_SHT, VF_NOQUOTE ); ok |= check_attr_option( nw, var, VF_ONLYONCE_STR, VF_ONLYONCE_SHT, VF_ONLYONCE ); ok |= check_attr_option( nw, var, VF_REQUIRED_STR, VF_REQUIRED_SHT, VF_REQUIRED ); if ( !ok ) { message( MSG_UNKN_ATTR_OPTION, inpf ); errstr( "Unknown attribute option " ); errqstr( nw ); errlf(); } } else err_eof( inpf, "defining attribute" ); } else { /* end of var definition reached */ inungets( nw, inpf ); nw = NULL; ok = TRUE; } /* get next word */ if ( nw ) nw = infgetw( inpf ); } /* while(nw) */ } /* if(!var) */ } /* if(val_vartype..) */ if ( !ok && var ) { del_dlnode( varlist, (APTR) var ); var = NULL; } return (var); }
/* ** parse_vararg: read & check a attribute value */ STRPTR parse_vararg( HSCVAR *var, INFILE *inpf ) { STRPTR str_vararg = NULL; /* return value */ int ch; /* char read from input */ /* TODO: handle "<>" (reset var->text to NULL) */ infskip_ws( inpf ); /* disable log */ inflog_disable( inpf ); /* read var->quote char */ ch = infgetc( inpf ); if ( !strchr( VQ_STR_QUOTE, ch ) ) if ( ch != EOF ) var->quote = VQ_NO_QUOTE; else err_eof( inpf, "reading attribute" ); else var->quote = ch; /* warning if no quote */ if ( ( var->quote == VQ_NO_QUOTE ) && !( var->varflag & VF_NOQUOTE ) ) { message( MSG_ARG_NO_QUOTE, inpf ); errstr( "Argument without quote\n" ); } /* read arg string */ if ( var->quote == '<' ) { /* ** get arg from other var */ STRPTR nw = infgetw( inpf ); if ( nw ) { HSCVAR *refvar = find_varname( vars, nw ); if ( refvar ) { /* TODO: type checking */ var->quote = refvar->quote; str_vararg = refvar->text; /* check empty/circular reference */ if ( !str_vararg ) { message( MSG_EMPTY_SYMB_REF, inpf ); errstr( "Empty reference to" ); errsym( var->name ); errlf(); } /* debugging message */ DDA( fprintf( stderr, "** %s refers to <%s>\n", var->name, refvar->name ) ); } else { /* reference to unknown var */ message( MSG_UNKN_SYMB_REF, inpf ); errstr( "reference to unknown" ); errsym( nw ); errlf(); } if ( (!refvar) || (!str_vararg ) ) { /* return empty var */ var->quote = '"'; str_vararg = ""; } parse_gt( inpf ); } else err_eof( inpf, "reading attribute" ); } else if ( var->quote != EOF ) { /* ** get arg from input file */ BOOL end = FALSE; /* clear vararg or set with first char read */ if ( var->quote == VQ_NO_QUOTE ) end = !set_estr( vararg, ch2str( ch ) ); else end = !clr_estr( vararg ); if ( end ) err_mem( inpf ); /* ** read next char from input file until a ** closing quote if found. ** if the arg had no quote, a white space ** or a '>' is used to detect end of arg. ** if a LF is found, view error message */ while ( !end ) { ch = infgetc( inpf ); end = TRUE; if ( ch == EOF ) err_eof( inpf, "reading attribute" ); else if ( (ch==var->quote) || ( ch==CH_LF ) || ( (var->quote==VQ_NO_QUOTE) && ( inf_isws(ch,inpf) || ( ch=='>' ) ) ) ) { /* end of arg reached */ str_vararg = estr2str( vararg ); if ( var->quote == VQ_NO_QUOTE ) { if ( ch==CH_LF ) err_streol( inpf ); inungetc( ch, inpf ); } } else { /* append next char to vararg */ if ( !app_estrch( vararg, ch ) ) err_mem( inpf ); else end = FALSE; /* continue loop */ } } } if ( str_vararg && var ) /* ** check enum type */ if (var->vartype == VT_ENUM) check_enumstr( var, str_vararg, inpf ); /* ** parse uri (only if no macro-attr) ** (convert abs.uris, check existence) */ else if (var->vartype == VT_URI ) if ( !(var->varflag & VF_MACRO) ) str_vararg = parse_uri( str_vararg, inpf ); else { DDA( fprintf( stderr, "** didn't parse uri \"%s\"\n", str_vararg ) ); } /* update and enable log */ if ( !fatal_error ) { BOOL ok = TRUE; if ( var->quote != VQ_NO_QUOTE ) ok &= inflog_app( inpf, ch2str( var->quote ) );/* append quote */ inflog_app( inpf, str_vararg ); /* append arg */ if ( var->quote != VQ_NO_QUOTE ) ok &= inflog_app( inpf, ch2str( var->quote ) );/* append quote */ inflog_enable( inpf ); /* enable log */ if ( !ok ) err_mem( NULL ); } return ( str_vararg ); }