⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vcp_main.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 2 页
字号:
    widget = malloc(sizeof(vcp_widget_t));    if ( widget == NULL ) {	printf( "get_child_widget(): unable to allocate memory\n" );	return NULL;    }printf ( "  allocated\n" );    /* zero the entire widget structure */    cp = (char *)widget;    for ( n = 0 ; n < sizeof(vcp_widget_t) ; n++ ) {	*cp++ = 0;    }    /* initialize non-zero widget structures fields */    widget->type = wdef;    widget->parent = parent;    widget->linenum = tf->tokenline;printf ( "  inited\n" );    /* link the widget to its parent */    if ( parent != NULL ) {	/* check if parent allows children */	if ( ( parent->type->w_class_mask & CH_ONE ) == 0 ) {	    printf ( "line %d: '%s' may not have child widgets\n",		tf->tokenline, parent->type->name );	    free_widget(widget);	    return NULL;	}	/* check if it is a legal child of parent */	if ( ( wdef->w_class & parent->type->w_class_mask ) == 0 ) {	    printf ( "line %d: '%s' not permitted as child of '%s'\n",		tf->tokenline, wdef->name, parent->type->name );	    free_widget(widget);	    return NULL;	}	if ( parent->child == NULL ) {	    /* no existing child, link it */	    parent->child = widget;	} else {	    /* parent has one child, does it support more than one? */	    if ( ( parent->type->w_class_mask & CH_MANY ) == 0 ) {		printf ( "line %d: '%s' can only have one child\n",		    tf->tokenline, parent->type->name );		free_widget(widget);		return NULL;	    }	    /* link it as sibling of existing child(ren) */	    wp = parent->child;	    while ( wp->sibling != NULL ) {		wp = wp->sibling;	    }	    wp->sibling = widget;	}    }printf ( "  linked\n" );    /* allocate the widget's private data */    widget->priv_data = malloc(wdef->priv_data_size);    if ( widget->priv_data == NULL ) {	printf( "get_child_widget(): unable to allocate memory\n" );	free_widget(widget);	return NULL;    }printf ( "  pd allocated\n" );    /* clear private data */    cp = widget->priv_data;    for ( n = 0 ; n < wdef->priv_data_size ; n++ ) {	*cp++ = 0;    }printf ( "  pd cleared\n" );    /* set default values for all attributes */    adef = wdef->attribs;    if ( adef != NULL ) {	while ( adef->name != NULL ) {	    if ( convert_attrib(adef, adef->deflt, widget->priv_data) != 0 ) {		printf ( "(internal error) widget %s: %s\n", wdef->name, errbuf );		free_widget(widget);		return NULL;	    }	    adef++;	}    }printf ( "  defaulted\n" );    /* parse remainder of widget */    while (1) {	item_name = tf_get_token(tf);	if ( item_name == NULL ) {	    printf ( "line %d: unexpected EOF in widget '%s'\n",		tf->tokenline, wdef->name );	    free_widget(widget);	    return NULL;	} else if ( item_name[0] == '}' ) {	    /* end of widget, check for any string attribs without values */	    adef = widget->type->attribs;	    if ( adef != NULL ) {		while ( adef->name != NULL ) {		    if ( adef->datatype == ATTRIB_STRING ) {			/* point to attribute value */			cp = *((char **)(widget->priv_data + adef->offset));			if ( cp == NULL ) {			    printf ( "line %d: attribute '%s' must be supplied for widget '%s'\n",				tf->tokenline, adef->name, wdef->name );			    free_widget(widget);			    return NULL;			}		    }		    adef++;		}	    }	    return widget;	} else if ( !isalnum(item_name[0]) ) {	    printf ( "line %d: bad widget or attribute name: '%s'\n",		tf->tokenline, item_name );	    free_widget(widget);	    return NULL;	}	delim = tf_get_token(tf);	if ( delim == NULL ) {	    printf ( "line %d: unexpected EOF in widget '%s'\n",		tf->tokenline, wdef->name );	    free_widget(widget);	    return NULL;	} else if ( delim[0] == '=' ) {	    /* name is a attribute */	    if ( get_attrib(widget, item_name, tf) != 0 ) {		/* message already printed inside get_attrib() */		free_widget(widget);		return NULL;	    }	} else if ( delim[0] == '{' ) {	    /* recurse deeper */	    if ( get_child_widget(widget, item_name, tf) == NULL ) {		/* message already printed inside get_child_widget() */		free_widget(widget);		return NULL;	    }	} else {	    printf ( "line %d: expected '=' or '{' after '%s'\n",			tf->tokenline, item_name );	    free_widget(widget);	    return NULL;	}    }}static int get_attrib(vcp_widget_t *widget, char *name, token_file_t *tf){    vcp_widget_def_t *wdef;    vcp_attrib_def_t *adef;    char *value;    wdef = widget->type;    adef = wdef->attribs;    if ( adef == NULL ) {	printf ( "line %d: widget '%s' accepts no attributes\n",	    tf->tokenline, wdef->name );	return -1;    }    while (( adef->name != NULL ) && ( strcmp(adef->name, name) ) != 0 ) {	adef++;    }    if ( adef->name == NULL ) {	printf ( "line %d: attribute '%s' is invalid for widget '%s'\n",	    tf->tokenline, name, wdef->name );	return -1;    }    /* found a match for name */    value = tf_get_token(tf);    if ( value == NULL ) {	printf ( "line %d: missing value for attribute '%s'\n",	    tf->tokenline, name );	return -1;    }    if ( convert_attrib(adef, value, widget->priv_data) != 0 ) {	printf ( "line %d: %s\n", tf->tokenline, errbuf );	return -1;    }    return 0;}static int convert_attrib(vcp_attrib_def_t *adef, char *value, void *base_addr){    char *cp;    double float_value;    int int_value, bool_value;    switch ( adef->datatype ) {    case ATTRIB_FLOAT:	float_value = strtod(value, &cp);	if ( *cp != '\0' ) {	    snprintf ( errbuf, ERRBUFLEN,		"bad value for float attribute '%s': '%s'\n", adef->name, value );	    return -1;	}	/* is this the default value */	if ( value != adef->deflt ) {	    /* no, token from an input file, free it */	    free(value);	}	/* store value */	*((double *)(base_addr + adef->offset)) = float_value;	break;    case ATTRIB_INT:	int_value = strtol(value, &cp, 0);	if ( *cp != '\0' ) {	    snprintf ( errbuf, ERRBUFLEN,		"bad value for integer attribute '%s': '%s'\n", adef->name, value );	    return -1;	}	/* is this the default value */	if ( value != adef->deflt ) {	    /* no, token from an input file, free it */	    free(value);	}	/* store value */	*((int *)(base_addr + adef->offset)) = int_value;	break;    case ATTRIB_BOOL:	if ( strcasecmp(value, "true" ) == 0 ) {	    bool_value = 1;	} else if ( strcasecmp(value, "t" ) == 0 ) {	    bool_value = 1;	} else if ( strcasecmp(value, "1" ) == 0 ) {	    bool_value = 1;	} else if ( strcasecmp(value, "false" ) == 0 ) {	    bool_value = 0;	} else if ( strcasecmp(value, "f" ) == 0 ) {	    bool_value = 0;	} else if ( strcasecmp(value, "0" ) == 0 ) {	    bool_value = 0;	} else {	    snprintf ( errbuf, ERRBUFLEN,		"bad value for boolean attribute '%s': '%s'\n", adef->name, value );	    return -1;	}	/* is this the default value */	if ( value != adef->deflt ) {	    /* no, token from an input file, free it */	    free(value);	}	/* store value */	*((int *)(base_addr + adef->offset)) = bool_value;	break;    case ATTRIB_STRING:	/* get previous value, if any */	cp = *((char **)(base_addr + adef->offset));	/* was there a non-default previous value? */	if (( cp != NULL ) && ( cp != adef->deflt )) {	    /* yes, it was a token from an input file, free it */	    free(cp);	}	/* store value */	*((char **)(base_addr + adef->offset)) = value;	break;    default:	snprintf ( errbuf, ERRBUFLEN,	    "(internal error) bad type for attribute '%s'\n", adef->name );	return -1;	break;    }    return 0;}static void free_widget(vcp_widget_t *widget){    vcp_attrib_def_t *adef;    char *cp;    vcp_widget_t *wp;        if ( widget == NULL ) {	return;    }    /* first free any children */    if ( widget->child != NULL ) {	free_widget(widget->child);    }    /* then any younger siblings */    if ( widget->sibling != NULL ) {	free_widget(widget->sibling);    }    /* free any string attribute values */    adef = widget->type->attribs;    if (( adef != NULL ) && ( widget->priv_data != NULL )) {	while ( adef->name != NULL ) {	    if ( adef->datatype == ATTRIB_STRING ) {		/* point to attribute value */		cp = *((char **)(widget->priv_data + adef->offset));		/* was there a non-default previous value? */		if (( cp != NULL ) && ( cp != adef->deflt )) {		    /* yes, it was a token from an input file, free it */		    free(cp);		}	    }	    adef++;	}    }    /* free widget's private data */    if ( widget->priv_data != NULL ) {	free(widget->priv_data);    }    /* unlink widget from parent or older sibling */    if (( widget->parent != NULL ) && ( widget->parent->child != NULL )) {	if ( widget->parent->child == widget ) {	    widget->parent->child = NULL;	} else {	    wp = widget->parent->child;	    while ( wp->sibling != NULL ) {		if ( wp->sibling == widget ) {		    wp->sibling = NULL;		} else {		    wp = wp->sibling;		}	    }	}    }    /* and finally free the widget structure itself */    free(widget);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -