On Thu, 25 May 2000, Peter Haworth wrote: > On 24-May-00 at 18:50, Jeffrey W. Baker ([EMAIL PROTECTED]) wrote: > > It's C with function pointers as struct members. > > That seems a little excessive to me spacewise, but I guess it means you can > keep the functions static, and not confuse users with differently named > functions to do the same thing with different types of input. Yes exactly. For example, each type can share the addAttr, getAttr, setAttr, and delAttr methods, and the TextInput, CheckBoxInput, and RadioInput could all share the same render method. > It's just that you said you were adding at the list head for performance. I > can't see the need for a doubly linked list if you don't have a pointer to the > tail. It will be handy when implementing the delAttr method. > Not sorting still gets my vote. There are too any cases where you > can't sort on just the value or just the label. Well as I said if the programmer doesn't want to sort anything, then they shouldn't call the method. I don't see anything wrong with adding a capability that some people might not use. > > Anyway, I'd still like to see the code. In the meantime, HTML::StickyForm will > probably start off in pure perl. The internals can always be rewritten to use > your library at some point in the future. I attached the files common.c and hfTextInput.c. The former contains the attribute list manipulation routines (and should be renamed attrList.c), and the latter is the partial implementation of the standard textbox input. The render() method in hfTextInput could be shared by the checkbox and radio types without modification. Cheers, Jeffrey
extern void addAttr(void*, char*, char*); extern void destroyAttrs(attrList *);
#ifndef HTMLFORMS_H #define HTMLFORMS_H /* * This header defines the public interface to the htmlforms library. * Only the data structures and functions declared here are for public * consumption. Poking around with stuff declared elsewhere is a no-no. */ typedef struct hfTextInput hfTextInput; typedef struct attrList attrList; struct attrList { attrList *next; attrList *prev; char *name; char *value; }; struct hfTextInput { attrList *attrs; void (*addAttr)(); char* (*render)(); void (*destroy)(); }; extern hfTextInput * hfTextInputNew(); #endif /* HTMLFORMS_H */
#include <stdlib.h> #include <malloc.h> #include <string.h> #include "htmlforms.h" #include "common.h" typedef struct hfElement hfElement; struct hfElement { attrList *attrs; }; static attrList * newAttrList (char *, char *); static void destroyAttrList (attrList *); void addAttr (void *el, char *name, char *value) { attrList *cur, *new; hfElement *myEl = (hfElement *)el; new = newAttrList(name, value); if (myEl->attrs == NULL) myEl->attrs = new; else { cur = myEl->attrs; while (cur->next != NULL) cur = cur->next; new->prev = cur; cur->next = new; } } void destroyAttrs (attrList *list) { attrList *next; while (list != NULL) { next = list->next; destroyAttrList(list); list = next; } } static void destroyAttrList (attrList *list) { free(list->name); free(list->value); free(list); } static attrList* newAttrList (char *name, char *value) { attrList *new; new = malloc(sizeof(attrList)); if (new == NULL) abort(); new->next = NULL; new->prev = NULL; new->name = malloc(strlen(name) + 1); if (new->name == NULL) abort(); strcpy(new->name, name); if (value != NULL) { new->value = malloc(strlen(value) + 1); if (new->value == NULL) abort(); strcpy(new->value, value); } return new; }
#include "htmlforms.h" #include "common.h" #include <malloc.h> #include <string.h> extern hfTextInput * hfTextInputNew (); static char * hfTextInputRender (hfTextInput *); static void hfTextInputDestroy (hfTextInput *); hfTextInput * hfTextInputNew () { hfTextInput *new; new = malloc(sizeof(hfTextInput)); if (new == NULL) abort(); new->attrs = NULL; new->addAttr = &addAttr; new->render = &hfTextInputRender; new->destroy = &hfTextInputDestroy; return new; } char * hfTextInputRender (hfTextInput *self) { attrList *cur; char *out; int bytes; /* <INPUT>\0 */ bytes = 8; /* Count the bytes needed for each attr/value pair, including spaces */ cur = self->attrs; while (cur != NULL) { bytes++; /* for the leading space */ bytes += strlen(cur->name); if (cur->value != NULL) bytes += (3 /* ="" */ + strlen(cur->value)); cur = cur->next; } out = malloc(bytes); if (out == NULL) abort(); strcpy(out, "<INPUT"); cur = self->attrs; while (cur != NULL) { strcat(out, " "); strcat(out, cur->name); if (cur->value != NULL) { strcat(out, "=\""); strcat(out, cur->value); strcat(out, "\""); } cur = cur->next; } strcat(out, ">"); return out; } void hfTextInputDestroy (hfTextInput *self) { destroyAttrs(self->attrs); free(self); }