📄 vcp_main.c
字号:
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 + -