void DDADisplay::doDDA() { init(); int delx = p1.x() - p2.x(); int dely = p1.y() < p2.y(); if(delx < 0) delx *= -1; if(dely < 0) dely *= -1; if(delx > dely) { if(p1.x() < p2.x()) DDA(p1.x(), p1.y(), p2.x(), p2.y()); else DDA(p2.x(), p2.y(), p1.x(), p1.y()); } else { if(p1.y() < p2.y()) DDA(p1.x(), p1.y(), p2.x(), p2.y()); else DDA(p2.x(), p2.y(), p1.x(), p1.y()); } }
int main(){ int gd = DETECT, gm; initgraph(&gd, &gm, ""); DDA(100,100,200,100); DDA(200,100,200,200); DDA(200,200,100,200); DDA(100,200,100,100); delay(1000); return 0; }
/* ** read_enum_str ** ** sidefx: modifies tmpstr */ BOOL read_enum_str( HSCVAR *var, INFILE *inpf ) { BOOL ok; int ch; ok = parse_wd( inpf, "(" ); /* check for "(" */ ok &= clr_estr( tmpstr ); /* reset string */ ch = infgetc( inpf ); while ( ok && (ch!=')') && (ch!=EOF) && (ch!=CH_LF) ) { if ( (ch!=')') && (ch!=' ') ) ok &= app_estrch( tmpstr, ch ); ch = infgetc( inpf ); }; /* check result */ if ( ok ) if ( ch == EOF ) err_eof( inpf, "reading enumerator" ); else if ( ch ==CH_LF ) err_eol( inpf ); /* store enumstr in var-struct */ if ( ok ) { DDA( fprintf( stderr, "** enum: %s\n", estr2str( tmpstr ) ) ); var->enumstr = strclone( estr2str( tmpstr ) ); } return( (BOOL)(!fatal_error) ); }
/* ** parse_lazy_option ** ** allowed abbrevations: ** ** c CLASS:string ** h HREF:uri ** i ID:id ** k CLEAR:enum("left|right|all|*") ** l LANG:string ** m MD:string ** s SRC:URI ** w NOWRAP:bool */ static HSCATTR *def_lazy_attr( HSCPRC *hp, HSCTAG *tag, STRPTR attrname, BYTE attrtype ) { HSCATTR *newattr = app_var( tag->attr, attrname ); DDA( fprintf( stderr, DHL "new attr: `%s'\n", attrname ) ); newattr->vartype = attrtype; return( newattr ); }
void drawshape(int x1, int x2, int x3, int x4, int y1, int y2, int y3){ // This is for drawing the body of the truck DDA(x1,y1,x2,y1); // Base Horizontal Line DDA(x1,y1,x1,y2); // Leftmost Vertical Line DDA(x2,y1,x2,y2); // Rightmost Vertical Line DDA(x1,y2,x2,y2); // Completing the body of the Truck DDA(x3,y2,x3,y3); // The Left Side of the Engine Part of the Truck DDA(x4,y2,x4,y3); // The Right Side of the Engine Part of the Truck DDA(x3,y3,x4,y3); // The Topmost Covering of the Enginer of the Truck }
// 边缘填充 void ImageRenderer::EdgeFilling() { points[m_cPointCount + 1] = points[0]; int x0, y0, x1, y1; // 查找最小值 // 这不是必须的, 优化的话在PushPoint那里可以优化(记录/更新这些点) int right = static_cast<int>(std::max_element(points, points + m_cPointCount + 1, [](D2D1_POINT_2F& p1, D2D1_POINT_2F& p2)->bool {return p1.x < p2.x; } )->x); // int dx, dy, eps1, k, p, q, flag, temp; float x, y, xIncre, yIncre; for (size_t i = 0; i <= m_cPointCount; i++) { x0 = to_int(points[i].x); y0 = to_int(points[i].y); x1 = to_int(points[i + 1].x); y1 = to_int(points[i + 1].y); //保证(x0,y0)在(x1,y1)的下面 if (y0 > y1) { temp = y0; y0 = y1; y1 = temp; temp = x0; x0 = x1; x1 = temp; } dx = x1 - x0; dy = y1 - y0; x = to_float(x0); y = to_float(y0); //注意这里和DDA算法不同,yIncre=1 //if(abs(dx)>abs(dy)) //eps1=abs(dx); //else eps1 = abs(dy); xIncre = (float)dx / (float)eps1; yIncre = (float)dy / (float)eps1; flag = 1; for (k = 0; k <= eps1; k++) { p = (int)(x + 0.5); q = (int)(y + 0.5); //每条直线的上端点不处理,避免交点处处理两次,没达到填充的效果 if (k != 0) { //putpixel(p, q); DDA(p, q, right, q); } x += xIncre; y += yIncre; } } // }
/* ** remove_local_varlist */ void remove_local_varlist( DLLIST *varlist, ULONG mci ) { DLNODE *nd = varlist->first; while ( nd ) { HSCVAR *var = (HSCVAR *) nd->data; /* var data of node */ DLNODE *nd_nxt = nd->next; /* next node */ if ( var->macro_id == mci ) { DDA( fprintf( stderr, "** del %s\n", var->name ) ); del_dlnode( varlist, nd ); } else DDA( fprintf( stderr, "** skip %s\n", var->name ) ); nd = nd_nxt; } }
/* ** 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 ); }
/* * read_enum_str * * sidefx: modifies tmpstr */ static BOOL read_enum_str(HSCPRC * hp, HSCATTR * var) { HSCATTR *attr = new_hscattr(PREFIX_TMPATTR "enumerator"); attr->vartype = VT_STRING; /* store enumstr in var-struct */ if (eval_expression(hp, attr, NULL)) { /*DDA(fprintf(stderr, DHL " enum: %s\n", estr2str(hp->tmpstr)));*/ var->enumstr = strclone(get_vartext(attr)); DDA(fprintf(stderr, DHL " enum: %s\n",var->enumstr)); } del_hscattr(attr); return ((BOOL) (!hp->fatal)); }
void main() { int gm=DETECT,gd; initgraph(&gm,&gd,"C:\\TC\\BGI"); DDA(100,100,200,100); DDA(200,100,200,200); DDA(200,200,100,200); DDA(100,200,1000,100); BresenhamLine(100,100,150,10); BresenhamLine(133,133,150,10); BresenhamLine(200,100,150,10); BresenhamLine(233,133,150,10); DDA(133,133,233,133); DDA(233,133,233,233); DDA(233,233,133,233); DDA(133,233,133,133); BresenhamLine(100,100,133,133); BresenhamLine(100,200,133,233); BresenhamLine(200,100,233,133); BresenhamLine(200,200,233,233); getch(); closegraph(); }
/* * check_attr_option * * check if a attribute-option-string is equal to an id/short id. * if so, set the corresponding option value within the attribute. * * params: option..option string to check for (read from input) * attr....attribute to update option value for * id......id string of option (eg "REQUIRED") * sid.....short id string (eg "R") * value...option value to OR with old tag's option value * result: TRUE, if tag's option value updated */ static BOOL check_attr_option(HSCPRC * hp, STRPTR option, HSCATTR * attr, STRPTR id, STRPTR sid, ULONG value, ULONG unmasked_flags) { BOOL found = FALSE; if (!((upstrcmp(option, id)) && (upstrcmp(option, sid)))) { DDA(fprintf(stderr, DHL " option %s\n", id)); if (value & unmasked_flags) { hsc_message(hp, MSG_ILLG_ATTR_FLAG, "attribute option %q not allowed in this context", id); } else attr->varflag |= value; found = TRUE; } return (found); }
/* * 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")); } }
/* * 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" */ HSCATTR *define_var(HSCPRC * hp, DLLIST * varlist, ULONG unmasked_flags) { HSCATTR *var = NULL; /* result */ BOOL ok = FALSE; BYTE val_vartype = VT_NONE; /* var-type (numeric) */ BOOL newattr = FALSE; /* next word read from input */ STRPTR nw = NULL; STRPTR varname = NULL; BOOL eof_called = FALSE; /* used at end-of-func, if nw==NULL */ INFILE *inpf = hp->inpf; /* read attribute name */ nw = infget_attrid(hp); if (nw) varname = strclone(nw); /* remember attribute name */ else eof_called = TRUE; /* err_eof() called already */ /* read attribute type */ if (nw) { if (parse_wd(hp, ":")) { nw = infgetw(inpf); if (nw) val_vartype = str2vartype(nw); } else inungetcw(inpf); } if (nw) { /* * look if attr already exist; * if yes, clear old attribute * to redefine the new one */ var = find_varname(varlist, varname); if (var) { DLNODE *nd = find_attrnode(varlist, varname); /* remove old attribute */ if (nd) del_dlnode(varlist, nd); else panic("no node for redefined attribute"); hsc_message(hp, MSG_ATTR_REDEFINED, "redefined %a", varname); } /* * create new attribute */ DDA(fprintf(stderr, DHL "new attr: %s\n", varname)); var = app_var(varlist, varname); /* set type */ var->vartype = val_vartype; if (var->vartype == VT_ENUM) { /* init enum-attribute */ read_enum_str(hp, var); } else if (var->vartype == VT_BOOL) { /* init boolean attr with FALSE */ set_varbool(var, FALSE); } newattr = TRUE; } /* disable "/STRIPEXT" and "/GETSIZE" for non-URI-attributes */ if (nw) { if (var->vartype != VT_URI) unmasked_flags |= VF_GETSIZE | VF_STRIPEXT; nw = infgetw(inpf); /* get net word */ } /* * handle attribute flags */ while (nw && !strcmp(nw, "/")) { nw = infgetw(inpf); /* read flag identifier */ if (nw) { BOOL ok = FALSE; ok |= check_attr_option(hp, nw, var, VF_CONST_STR, VF_CONST_SHT, VF_CONST, unmasked_flags); ok |= check_attr_option(hp, nw, var, VF_GLOBAL_STR, VF_GLOBAL_SHT, VF_GLOBAL, unmasked_flags); ok |= check_attr_option(hp, nw, var, VF_JERK_STR, VF_JERK_SHT, VF_JERK, unmasked_flags); ok |= check_attr_option(hp, nw, var, VF_ONLYONCE_STR, VF_ONLYONCE_SHT, VF_ONLYONCE, unmasked_flags); ok |= check_attr_option(hp, nw, var, VF_REQUIRED_STR, VF_REQUIRED_SHT, VF_REQUIRED, unmasked_flags); ok |= check_attr_option(hp, nw, var, VF_GETSIZE_STR, VF_GETSIZE_SHT, VF_GETSIZE, unmasked_flags); ok |= check_attr_option(hp, nw, var, VF_STRIPEXT_STR, VF_STRIPEXT_SHT, VF_STRIPEXT, unmasked_flags); ok |= check_attr_option(hp, nw, var, VF_OBSOLETE_STR, VF_OBSOLETE_SHT, VF_OBSOLETE, unmasked_flags); ok |= check_attr_option(hp, nw, var, VF_RECOMMENDED_STR, VF_RECOMMENDED_SHT, VF_RECOMMENDED, unmasked_flags); if (!ok) { hsc_message(hp, MSG_UNKN_ATTR_OPTION, "unknown attribute flag %q", nw); } /* read next word (should be "/", "=" or next attr / ">") */ nw = infgetw(inpf); } else hsc_msg_eof(hp, "defining attribute"); } /* * handle default value */ if (nw && !strcmp(nw, "=")) { /* get new deftext value */ STRPTR new_deftext = NULL; LONG old_attrflag = var->varflag; /* disable quotemode-checking */ var->varflag |= VF_KEEP_QUOTES; if (!(var->deftext)) new_deftext = eval_expression(hp, var, NULL); else { STRPTR dummy; hsc_message(hp, MSG_SYMB_2ND_DEFAULT, "default value for %A already set", var); /* skip illegal default value */ dummy = eval_expression(hp, var, NULL); } /* restore quotemode-checking */ var->varflag = old_attrflag; /* store default text value */ if (new_deftext) var->deftext = strclone(new_deftext); /* read next word, only to be ungotten below */ nw = infgetw(inpf); } /* check for unexpected end of file */ if (!nw) { if (!eof_called) hsc_msg_eof(hp, "defining attribute"); } else { /* end of var definition reached */ inungetcw(inpf); ok = TRUE; } /* cleanup */ if (!ok && var) { DLNODE *nd = find_attrnode(varlist, varname); if (nd) del_dlnode(varlist, (APTR) nd); else del_hscattr(var); var = NULL; } ufreestr(varname); return (var); }
/* ** 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); }
/* ** 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 ); }