예제 #1
0
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;
}
예제 #3
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) );
}
예제 #4
0
/*
** 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 );
}
예제 #5
0
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
}
예제 #6
0
// 边缘填充
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;
        }
    }

    //
}
예제 #7
0
/*
** 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;

    }

}
예제 #8
0
/*
** 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 );
}
예제 #9
0
/*
 * 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));
}
예제 #10
0
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();
}
예제 #11
0
/*
 * 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);
}
예제 #12
0
/*
 * 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"));
                        }
                    }
예제 #13
0
/*
 * 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);
}
예제 #14
0
/*
** 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);
}
예제 #15
0
/*
** 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);
}
예제 #16
0
/*
** 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 );
}