📄 form.c
字号:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include "form.h"#include "str_util.h"#include "debug.h"#include "dw_embed_gtk.h"#include "htmlparser.h"#include "htmltokenizer.h"#include "htmltag.h"#include "html.h"#include "error.h"#define TOTAL_KEYWORDS 10#define MIN_WORD_LENGTH 4#define MAX_WORD_LENGTH 8#define MIN_HASH_VALUE 4#define MAX_HASH_VALUE 16HtmlForm *form_new();void form_free(HtmlForm *form);FormControl *form_control_new(void);void form_control_free(FormControl *control);ControlList *control_list_add(ControlList *list, FormControl *control);void control_list_free(ControlList *list);FormList *form_list_add(FormList *list, HtmlForm *form);GtkWidget *create_input_widget(FormControl *control);HtmlForm *form_list_get_last(FormList *list);/* * input_hash() - perfect hash table for retrieving input types */__inline static unsigned int input_hash(const char *str, unsigned int len){ static unsigned char asso_values[] = { 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 10, 5, 0, 0, 5, 17, 5, 10, 17, 17, 17, 17, 0, 5, 0, 17, 0, 0, 0, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17 }; return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]];}/* * get_input_type() - returns the input type for str */__inline int get_input_type(const char *str, unsigned int len){ static InputTypeStruct wordlist[] = { {""}, {""}, {""}, {""}, {"TEXT", INPUT_TEXT}, {"RESET", INPUT_RESET}, {"SUBMIT", INPUT_SUBMIT}, {""}, {"PASSWORD", INPUT_PASSWORD}, {"FILE", INPUT_FILE}, {"RADIO", INPUT_RADIO}, {"HIDDEN", INPUT_HIDDEN}, {""}, {"CHECKBOX", INPUT_CHECKBOX}, {""}, {"IMAGE", INPUT_IMAGE}, {"BUTTON", INPUT_BUTTON} }; register int key; char *upper; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { upper = str_to_upper(str); if(!upper) { fprintf(stderr, "Ran out of memory."); return -1; } key = input_hash (upper, len); if( key <= MAX_HASH_VALUE && key >= 0) { register const char *s = wordlist[key].type; if(!my_strcmp(upper, s)) { free(upper); return wordlist[key].id; } } free(upper); } return -1;}/* * create_input_widget() - Returns a GtkWidget containing * the attributes specified by control */void form_embed_control(html_t *html, FormControl *control){ DwWidget *embed; g_return_if_fail(html && control && control->widget); embed = a_Dw_embed_gtk_new(); a_Dw_embed_gtk_add_gtk(DW_EMBED_GTK(embed), control->widget); a_Dw_page_add_widget(DW_PAGE(html->dw), embed, -1, -1, html->stack[html->stack_top].style);}int create_control_widget(html_t *html, FormControl *control) { GtkWidget *widget = NULL; if(!control || !html) return -1; switch(control->type) { case INPUT_TEXT: widget = control->maxlength ? gtk_entry_new_with_max_length(control->maxlength) : gtk_entry_new(); if(control->value) gtk_entry_set_text(GTK_ENTRY(widget), control->value); if(control->size) gtk_widget_set_usize(widget, control->size * 8, -1); gtk_widget_show(widget); break; case INPUT_PASSWORD: widget = control->maxlength ? gtk_entry_new_with_max_length(control->maxlength) : gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE); if(control->value) gtk_entry_set_text(GTK_ENTRY(widget), control->value); if(control->size) gtk_widget_set_usize(widget, control->size * 8, -1); break; case INPUT_CHECKBOX: widget = gtk_check_button_new(); if(control->checked) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); gtk_widget_show(widget); break; case INPUT_RADIO: break; case INPUT_SUBMIT: if(control->value) widget = gtk_button_new_with_label(control->value); else widget = gtk_button_new_with_label("Submit"); gtk_widget_show(widget); break; case INPUT_RESET: if(control->value) widget = gtk_button_new_with_label(control->value); else widget = gtk_button_new_with_label("Reset"); gtk_widget_show(widget); break; case INPUT_FILE: break; case INPUT_IMAGE: break; case INPUT_BUTTON: if(control->value) widget = gtk_button_new_with_label(control->value); else { widget = gtk_button_new(); if(!control->size) gtk_widget_set_usize(widget, 20, 20); } gtk_widget_show(widget); break; } /* Set the widget size if necessary and possible */ if (widget != NULL && control->size && control->type != INPUT_TEXT && control->type != INPUT_PASSWORD) gtk_widget_set_usize(widget, control->size, -1); control->widget = widget; form_embed_control(html, control); return 0;}/* * form_control_new() - allocate an empty form control structure */FormControl *form_control_new(void){ FormControl *control; control = (FormControl *)malloc(sizeof(FormControl)); if(!control) return NULL; control->name = NULL; control->value = NULL; control->src = NULL; control->maxlength = 0; control->size = 0; control->checked = FALSE; control->type = -1; return control;}/* * control_free() - free a form control */void form_control_free(FormControl *control){ if(!control) return; if(control->name) free(control->name); if(control->value) free(control->value); if(control->src) free(control->src); free(control);}/* * form_new() - allocates an empty form structure */HtmlForm *form_new(){ HtmlForm *form; form = (HtmlForm *)malloc(sizeof(HtmlForm)); if(!form) return NULL; form->action = NULL; form->enctype = NULL; form->charset = NULL; form->name = NULL; form->accept = NULL; form->method = GET; form->control_list = NULL; return form;}/* * form_free() - free a form structure */void form_free(HtmlForm *form){ if(!form) { debug_print("html_form_free() got NULL argument"); return; } if(form->action) free(form->action); if(form->enctype) free(form->enctype); if(form->charset) free(form->charset); if(form->name) free(form->name); if(form->accept) free(form->accept); if(form->control_list) control_list_free(form->control_list); free(form);}/* * form_list_add() - adds a form to the list of forms */FormList *form_list_add(FormList *list, HtmlForm *form){ FormList *tmp = list; if(!form) return NULL; if(!list) { list = (FormList *)malloc(sizeof(FormList)); if(!list) return NULL; list->form = form; list->next = NULL; return list; } while(list->next) list = list->next; list->next = (FormList *)malloc(sizeof(FormList)); if(!list->next) return NULL; list = list->next; list->form = form; list->next = NULL; return tmp;}/* * form_list_free() - free a form list */void form_list_free(FormList *list){ FormList *cur, *next; if(!list) return; cur = list; while(cur) { form_free(cur->form); next = cur->next; free(cur); cur = next; }}/* * form_list_get_last() - return the last form in the list */HtmlForm *form_list_get_last(FormList *list) { FormList *cur; if(!list) return NULL; cur = list; while(cur->next) cur = cur->next; return cur->form;}/* * control_list_add() - adds a control to a form */ControlList *control_list_add(ControlList *list, FormControl *control){ ControlList *tmp = list; if(!control) return NULL; if(!list) { list = (ControlList *)malloc(sizeof(ControlList)); if(!list) { error("Out of memory"); return NULL; } list->control = control; list->next = NULL; return list; } while(list->next) list = list->next; list->next = (ControlList *)malloc(sizeof(ControlList)); if(!list->next) { error("Out of memory"); return NULL; } list = list->next; list->control = control; list->next = NULL; return tmp;} /* * control_list_free() - free a control list */void control_list_free(ControlList *list){ ControlList *cur, *next; if(!list) return; cur = list; while(cur) { form_control_free(cur->control); next = cur->next; free(cur); cur = next; }}/* * html_label() - <LABEL> tag. */__inline int html_label (html_t *html, char *tag, html_tag_args *args, tag_type type) { return 0;}/* * html_form() - <FORM> tag */__inline int html_form (html_t *html, char *tag, html_tag_args *args, tag_type type) { HtmlForm *form; html_tag_args *cur; if(type == HTML_TAG_CLOSE); form = form_new(); if(!form) { fprintf(stderr, "Out of memory creating form"); return -1; } cur = args; while(cur) { if(strcasecmp(cur->name, "action") == 0) form->action = strdup(cur->value); else if(strcasecmp(cur->name, "enctype") == 0) form->enctype = strdup(cur->value); else if(strcasecmp(cur->name, "accept-charset") == 0) form->charset = strdup(cur->value); else if(strcasecmp(cur->name, "accept") == 0) form->accept = strdup(cur->value); else if(strcasecmp(cur->name, "name") == 0) form->name = strdup(cur->value); else if(strcasecmp(cur->name, "method") == 0) { if(strcasecmp(cur->value, "post") == 0) form->method = POST; else form->method = GET; } cur = cur->next; } html->formlist = form_list_add(html->formlist, form); return 0;}/* * html_select() - <SELECT> tag. */__inline int html_select (html_t *html, char *tag, html_tag_args *args, tag_type type) { return 0;}/* * html_textarea() - <TEXAREA> tag. */__inline int html_textarea (html_t *html, char *tag, html_tag_args *args, tag_type type) { return 0;}/* * html_button() - <BUTTON> tag. */__inline int html_button (html_t *html, char *tag, html_tag_args *args, tag_type type) { HtmlForm *form; FormControl *button; html_tag_args *cur; /* Create the control */ button = form_control_new(); if(!button) { error("Out of memory"); return -1; } button->type = INPUT_BUTTON; cur = args; while(cur) { if(strcasecmp(cur->name, "name") == 0) button->name = strdup(cur->value); else if(strcasecmp(cur->name, "value") == 0) button->value = strdup(cur->value); cur = cur->next; } /* Create the widget for the button */ if(create_control_widget(html, button) < 0) return -1; /* If we're inside of a form tag then add this control to * the form, otherwise just return */ if(html_seek_tag(html, FORM) < 0) return 0; form = form_list_get_last(html->formlist); if(!form) { debug_print("*** Inside a form tag but no form structure found!"); return -1; } button->form = form; form->control_list = control_list_add(form->control_list, button); if(!form->control_list) return -1; return 0;}/* * html_option() - <OPTION> tag. */__inline int html_option (html_t *html, char *tag, html_tag_args *args, tag_type type) { return 0;}/* * html_input() - <INPUT> tag. */__inline int html_input (html_t *html, char *tag, html_tag_args *args, tag_type type) { HtmlForm *form; FormControl *control; html_tag_args *cur; char *type_str = NULL; if(type == HTML_TAG_CLOSE) return 0; /* Create the control structure */ control = form_control_new(); if(!control) { error("Out of memory"); return -1; } cur = args; while(cur) { if(strcasecmp(cur->name, "name") == 0) control->name = strdup(cur->value); else if(strcasecmp(cur->name, "value") == 0) control->value = strdup(cur->value); else if(strcasecmp(cur->name, "type") == 0) type_str = cur->value; else if(strcasecmp(cur->name, "size") == 0) control->size = atoi(cur->value); else if(strcasecmp(cur->name, "maxlength") == 0) control->maxlength = atoi(cur->value); else if(strcasecmp(cur->name, "src") == 0) control->src = strdup(cur->value); else if(strcasecmp(cur->name, "checked") == 0) control->checked = TRUE; cur = cur->next; } control->type = get_input_type(type_str, strlen(type_str)); if(control->type < 0) { debug_print("Unkown input type %s", type_str); return -1; } /* Create the widget */ if(create_control_widget(html, control) < 0) return -1; /* If we're inside of a form tag then add this control to * the form, otherwise just return */ if(!html_seek_tag(html, FORM)) return 0; form = form_list_get_last(html->formlist); if(!form) { debug_print("*** Inside a form tag but no form structure found!"); return -1; } control->form = form; form->control_list = control_list_add(form->control_list, control); if(!form->control_list) return -1; return 0;}__inline int html_fieldset (html_t *html, char *tag, html_tag_args *args, tag_type type) { return 0;}__inline int html_legend (html_t *html, char *tag, html_tag_args *args, tag_type type) { return 0;}__inline int html_optgroup (html_t *html, char *tag, html_tag_args *args, tag_type type) { return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -