2 * Copyright (c)2004 Cat's Eye Technologies. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * Neither the name of Cat's Eye Technologies nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
36 * $Id: form.c,v 1.18 2005/03/04 21:26:20 cpressey Exp $
43 #include <libaura/mem.h>
45 #define NEEDS_DFUI_STRUCTURE_DEFINITIONS
47 #undef NEEDS_DFUI_STRUCTURE_DEFINITIONS
53 dfui_info_new(const char *name, const char *short_desc, const char *long_desc)
57 AURA_MALLOC(i, dfui_info);
58 i->name = aura_strdup(name);
59 i->short_desc = aura_strdup(short_desc);
60 i->long_desc = aura_strdup(long_desc);
66 dfui_info_free(struct dfui_info *i)
71 AURA_FREE(i, dfui_info);
75 dfui_info_get_name(const struct dfui_info *i)
83 dfui_info_get_short_desc(const struct dfui_info *i)
87 return(i->short_desc);
91 dfui_info_get_long_desc(const struct dfui_info *i)
99 dfui_info_set_name(struct dfui_info *i, const char *name)
105 i->name = aura_strdup(name);
109 dfui_info_set_short_desc(struct dfui_info *i, const char *short_desc)
113 if (i->short_desc != NULL)
115 i->short_desc = aura_strdup(short_desc);
119 dfui_info_set_long_desc(struct dfui_info *i, const char *long_desc)
123 if (i->long_desc != NULL)
125 i->long_desc = aura_strdup(long_desc);
130 struct dfui_property *
131 dfui_property_new(const char *name, const char *value)
133 struct dfui_property *p;
135 AURA_MALLOC(p, dfui_property);
136 p->name = aura_strdup(name);
137 p->value = aura_strdup(value);
143 dfui_property_free(struct dfui_property *p)
149 AURA_FREE(p, dfui_property);
153 dfui_properties_free(struct dfui_property *head)
155 struct dfui_property *p;
157 for (p = head; p != NULL; ) {
159 dfui_property_free(p);
164 struct dfui_property *
165 dfui_property_find(struct dfui_property *head, const char *name)
167 struct dfui_property *p;
169 for (p = head; p != NULL; p = p->next) {
170 if (strcmp(name, p->name) == 0)
178 dfui_property_get(struct dfui_property *head, const char *name)
180 struct dfui_property *p;
182 if ((p = dfui_property_find(head, name)) != NULL)
187 struct dfui_property *
188 dfui_property_set(struct dfui_property **head, const char *name, const char *value)
190 struct dfui_property *p;
195 if ((p = dfui_property_find(*head, name)) != NULL) {
197 p->value = aura_strdup(value);
201 p = dfui_property_new(name, value);
209 dfui_property_get_name(const struct dfui_property *p)
215 dfui_property_get_value(const struct dfui_property *p)
223 dfui_field_new(const char *id, struct dfui_info *info)
225 struct dfui_field *fi;
227 AURA_MALLOC(fi, dfui_field);
228 fi->id = aura_strdup(id);
230 fi->option_head = NULL;
231 fi->property_head = NULL;
234 dfui_field_property_set(fi, "editable", "true");
240 dfui_field_free(struct dfui_field *fi)
243 dfui_info_free(fi->info);
244 dfui_options_free(fi->option_head);
245 dfui_properties_free(fi->property_head);
246 AURA_FREE(fi, dfui_field);
250 dfui_fields_free(struct dfui_field *head)
252 struct dfui_field *fi;
263 dfui_field_get_next(const struct dfui_field *fi)
271 dfui_field_get_id(const struct dfui_field *fi)
279 dfui_field_get_info(const struct dfui_field *fi)
287 dfui_field_option_add(struct dfui_field *fi, const char *value)
289 struct dfui_option *o;
293 o = dfui_option_new(value);
294 o->next = fi->option_head;
301 dfui_field_option_get_first(const struct dfui_field *fi)
305 return(fi->option_head);
308 struct dfui_property *
309 dfui_field_property_set(struct dfui_field *fi, const char *name, const char *value)
311 return(dfui_property_set(&fi->property_head, name, value));
315 dfui_field_property_get(const struct dfui_field *fi, const char *name)
317 return(dfui_property_get(fi->property_head, name));
321 dfui_field_property_is(const struct dfui_field *fi, const char *name, const char *value)
323 struct dfui_property *h;
327 if ((h = dfui_property_find(fi->property_head, name)) == NULL)
329 return(!strcmp(h->value, value));
335 dfui_option_new(const char *value)
337 struct dfui_option *o;
339 AURA_MALLOC(o, dfui_option);
340 o->value = aura_strdup(value);
347 dfui_option_free(struct dfui_option *o)
352 AURA_FREE(o, dfui_option);
356 dfui_options_free(struct dfui_option *head)
358 struct dfui_option *o;
369 dfui_option_get_next(const struct dfui_option *o)
377 dfui_option_get_value(const struct dfui_option *o)
387 dfui_action_new(const char *id, struct dfui_info *info)
389 struct dfui_action *a;
391 AURA_MALLOC(a, dfui_action);
392 a->id = aura_strdup(id);
395 a->property_head = NULL;
401 dfui_action_free(struct dfui_action *a)
404 dfui_info_free(a->info);
405 dfui_properties_free(a->property_head);
406 AURA_FREE(a, dfui_action);
410 dfui_actions_free(struct dfui_action *head)
412 struct dfui_action *a;
423 dfui_action_get_next(const struct dfui_action *a)
431 dfui_action_get_id(const struct dfui_action *a)
439 dfui_action_get_info(const struct dfui_action *a)
446 struct dfui_property *
447 dfui_action_property_set(struct dfui_action *a, const char *name, const char *value)
449 return(dfui_property_set(&a->property_head, name, value));
453 dfui_action_property_get(const struct dfui_action *a, const char *name)
455 return(dfui_property_get(a->property_head, name));
459 dfui_action_property_is(const struct dfui_action *a, const char *name, const char *value)
461 struct dfui_property *h;
465 if ((h = dfui_property_find(a->property_head, name)) == NULL)
467 return(!strcmp(h->value, value));
473 dfui_form_new(const char *id, struct dfui_info *info)
477 AURA_MALLOC(f, dfui_form);
478 f->id = aura_strdup(id);
482 f->field_head = NULL;
483 f->action_head = NULL;
484 f->dataset_head = NULL;
485 f->property_head = NULL;
491 * Convenience function for creating a form.
492 * This function takes a list of any number of strings.
493 * This list MUST be terminated by a NULL pointer.
494 * The first four strings are the id, name, short description, and long
495 * description of the form.
496 * Each subsequent string determines what the strings following it represent:
497 * "f": create a field (id, name, short desc, long desc).
498 * "o": add an option to the last field (value).
499 * "a": create an action (id, name, short desc, long desc).
500 * "p": add a property to the last object (name, value).
503 dfui_form_create(const char *id, const char *name,
504 const char *short_desc, const char *long_desc, ...)
506 #define DFUI_FORM_CREATE_FORM 0
507 #define DFUI_FORM_CREATE_FIELD 1
508 #define DFUI_FORM_CREATE_ACTION 2
513 int state = DFUI_FORM_CREATE_FORM;
517 char *a_name, *a_short_desc, *a_long_desc;
519 i = dfui_info_new(name, short_desc, long_desc);
520 f = dfui_form_new(id, i);
522 va_start(args, long_desc);
523 while ((arg = va_arg(args, char *)) != NULL) {
526 a_id = va_arg(args, const char *);
527 a_name = va_arg(args, char *);
528 a_short_desc = va_arg(args, char *);
529 a_long_desc = va_arg(args, char *);
530 i = dfui_info_new(a_name, a_short_desc, a_long_desc);
531 object = (void *)dfui_form_field_add(f, a_id, i);
532 state = DFUI_FORM_CREATE_FIELD;
535 a_id = va_arg(args, const char *);
536 a_name = va_arg(args, char *);
537 a_short_desc = va_arg(args, char *);
538 a_long_desc = va_arg(args, char *);
539 i = dfui_info_new(a_name, a_short_desc, a_long_desc);
540 object = (void *)dfui_form_action_add(f, a_id, i);
541 state = DFUI_FORM_CREATE_ACTION;
544 a_name = va_arg(args, char *);
545 if (state == DFUI_FORM_CREATE_FIELD) {
546 dfui_field_option_add(object, a_name);
548 dfui_debug("form_create: can't add option to non-field\n");
553 a_id = va_arg(args, char *);
554 a_short_desc = va_arg(args, char *);
556 if (state == DFUI_FORM_CREATE_FIELD) {
557 dfui_field_property_set(object, a_id, a_short_desc);
558 } else if (state == DFUI_FORM_CREATE_ACTION) {
559 dfui_action_property_set(object, a_id, a_short_desc);
560 } else if (state == DFUI_FORM_CREATE_FORM) {
561 dfui_form_property_set(f, a_id, a_short_desc);
563 dfui_debug("form_create: can't add property in this state\n");
568 dfui_debug("form_create: unknown option `%c'\n", arg[0]);
578 dfui_form_free(struct dfui_form *f)
581 dfui_info_free(f->info);
582 dfui_fields_free(f->field_head);
583 dfui_actions_free(f->action_head);
584 dfui_datasets_free(f->dataset_head);
585 dfui_properties_free(f->property_head);
586 AURA_FREE(f, dfui_form);
590 dfui_form_field_add(struct dfui_form *f, const char *id, struct dfui_info *info)
592 struct dfui_field *fi;
596 fi = dfui_field_new(id, info);
597 fi->next = f->field_head;
604 dfui_form_field_attach(struct dfui_form *f, struct dfui_field *fi)
608 fi->next = f->field_head;
615 dfui_form_action_add(struct dfui_form *f, const char *id, struct dfui_info *info)
617 struct dfui_action *a;
621 a = dfui_action_new(id, info);
622 a->next = f->action_head;
629 dfui_form_action_attach(struct dfui_form *f, struct dfui_action *a)
633 a->next = f->action_head;
640 dfui_form_dataset_add(struct dfui_form *f, struct dfui_dataset *ds)
642 if (f == NULL || ds == NULL)
644 ds->next = f->dataset_head;
645 f->dataset_head = ds;
648 struct dfui_dataset *
649 dfui_form_dataset_get_first(const struct dfui_form *f)
653 return(f->dataset_head);
657 dfui_form_dataset_count(const struct dfui_form *f)
660 struct dfui_dataset *ds;
665 ds = f->dataset_head;
675 dfui_form_datasets_free(struct dfui_form *f)
679 dfui_datasets_free(f->dataset_head);
680 f->dataset_head = NULL;
684 dfui_form_field_find(const struct dfui_form *f, const char *id)
686 struct dfui_field *fi;
693 if (!strcmp(id, fi->id))
702 dfui_form_field_get_first(const struct dfui_form *f)
706 return(f->field_head);
710 dfui_form_field_count(const struct dfui_form *f)
713 struct dfui_field *fi;
728 dfui_form_action_find(const struct dfui_form *f, const char *id)
730 struct dfui_action *a = f->action_head;
733 if (!strcmp(id, a->id))
742 dfui_form_action_get_first(const struct dfui_form *f)
746 return(f->action_head);
750 dfui_form_action_count(const struct dfui_form *f)
753 struct dfui_action *a;
767 struct dfui_property *
768 dfui_form_property_set(struct dfui_form *f, const char *name, const char *value)
770 return(dfui_property_set(&f->property_head, name, value));
774 dfui_form_property_get(const struct dfui_form *f, const char *name)
776 return(dfui_property_get(f->property_head, name));
780 dfui_form_property_is(const struct dfui_form *f, const char *name, const char *value)
782 struct dfui_property *h;
786 if ((h = dfui_property_find(f->property_head, name)) == NULL)
788 return(!strcmp(h->value, value));
792 dfui_form_get_id(const struct dfui_form *f)
795 return(NULL); /* XXX ? */
800 dfui_form_get_info(const struct dfui_form *f)
808 dfui_form_set_multiple(struct dfui_form *f, int multiple)
812 f->multiple = multiple;
816 dfui_form_is_multiple(const struct dfui_form *f)
824 dfui_form_set_extensible(struct dfui_form *f, int extensible)
828 f->extensible = extensible;
832 dfui_form_is_extensible(const struct dfui_form *f)
836 return(f->extensible);
841 struct dfui_celldata *
842 dfui_celldata_new(const char *field_id, const char *value)
844 struct dfui_celldata *c;
846 AURA_MALLOC(c, dfui_celldata);
847 c->field_id = aura_strdup(field_id);
848 c->value = aura_strdup(value);
854 dfui_celldata_free(struct dfui_celldata *c)
860 AURA_FREE(c, dfui_celldata);
864 dfui_celldatas_free(struct dfui_celldata *head)
866 struct dfui_celldata *c;
871 dfui_celldata_free(c);
876 struct dfui_celldata *
877 dfui_celldata_find(struct dfui_celldata *head, const char *id)
879 struct dfui_celldata *c;
883 if (!strcmp(id, c->field_id))
891 struct dfui_celldata *
892 dfui_celldata_get_next(const struct dfui_celldata *cd)
902 dfui_celldata_get_field_id(const struct dfui_celldata *cd)
905 return(cd->field_id);
912 dfui_celldata_get_value(const struct dfui_celldata *cd)
923 struct dfui_dataset *
924 dfui_dataset_new(void)
926 struct dfui_dataset *ds;
928 AURA_MALLOC(ds, dfui_dataset);
929 ds->celldata_head = NULL;
935 struct dfui_dataset *
936 dfui_dataset_dup(const struct dfui_dataset *ds)
938 struct dfui_dataset *nds;
939 struct dfui_celldata *cd;
941 nds = dfui_dataset_new();
943 for (cd = ds->celldata_head; cd != NULL; cd = cd->next) {
944 dfui_dataset_celldata_add(nds,
945 cd->field_id, cd->value);
952 dfui_dataset_free(struct dfui_dataset *ds)
954 dfui_celldatas_free(ds->celldata_head);
955 AURA_FREE(ds, dfui_dataset);
959 dfui_datasets_free(struct dfui_dataset *head)
961 struct dfui_dataset *ds;
966 dfui_dataset_free(ds);
971 struct dfui_celldata *
972 dfui_dataset_celldata_add(struct dfui_dataset *ds, const char *field_id, const char *value)
974 struct dfui_celldata *c;
979 c = dfui_celldata_new(field_id, value);
980 c->next = ds->celldata_head;
981 ds->celldata_head = c;
986 struct dfui_celldata *
987 dfui_dataset_celldata_get_first(const struct dfui_dataset *ds)
991 return(ds->celldata_head);
994 struct dfui_celldata *
995 dfui_dataset_celldata_find(const struct dfui_dataset *ds, const char *field_id)
999 return(dfui_celldata_find(ds->celldata_head, field_id));
1002 struct dfui_dataset *
1003 dfui_dataset_get_next(const struct dfui_dataset *ds)
1011 * Returns the value of the celldata with the given id found in the
1012 * given dataset. If no such celldata is found, a constant zero-length
1013 * string is returned. As such, the return value of this function is
1014 * guaranteed to not be NULL and must NEVER be freed after use.
1017 dfui_dataset_get_value(const struct dfui_dataset *ds, const char *id)
1019 struct dfui_celldata *cd;
1021 if ((cd = dfui_dataset_celldata_find(ds, id)) != NULL) {
1022 return(dfui_celldata_get_value(cd));
1029 * Allocates a string to hold the value of the celldata with the
1030 * given id found in the given dataset. Even if no such celldata
1031 * is found, an allocated, zero-length string is returned. As such,
1032 * the return value of this function is guaranteed to not be NULL,
1033 * and must ALWAYS be freed after use.
1036 dfui_dataset_dup_value(const struct dfui_dataset *ds, const char *id)
1038 return(aura_strdup(dfui_dataset_get_value(ds, id)));
1043 struct dfui_response *
1044 dfui_response_new(const char *form_id, const char *action_id)
1046 struct dfui_response *r;
1048 AURA_MALLOC(r, dfui_response);
1049 r->form_id = aura_strdup(form_id);
1050 r->action_id = aura_strdup(action_id);
1051 r->dataset_head = NULL;
1057 dfui_response_free(struct dfui_response *r)
1061 dfui_datasets_free(r->dataset_head);
1062 AURA_FREE(r, dfui_response);
1066 dfui_response_dataset_add(struct dfui_response *r, struct dfui_dataset *ds)
1068 if (ds == NULL || r == NULL)
1070 ds->next = r->dataset_head;
1071 r->dataset_head = ds;
1074 struct dfui_dataset *
1075 dfui_response_dataset_get_first(const struct dfui_response *r)
1079 return(r->dataset_head);
1083 dfui_response_dataset_count(const struct dfui_response *r)
1086 struct dfui_dataset *ds;
1091 ds = r->dataset_head;
1092 while (ds != NULL) {
1101 dfui_response_get_form_id(const struct dfui_response *r)
1104 return(NULL); /* XXX ? */
1109 dfui_response_get_action_id(const struct dfui_response *r)
1112 return(NULL); /* XXX ? */
1113 return(r->action_id);
1118 struct dfui_progress *
1119 dfui_progress_new(struct dfui_info *info, int amount)
1121 struct dfui_progress *pr;
1123 AURA_MALLOC(pr, dfui_progress);
1125 pr->amount = amount;
1127 pr->msg_line = NULL;
1133 dfui_progress_free(struct dfui_progress *pr)
1137 dfui_info_free(pr->info);
1138 if (pr->msg_line != NULL)
1140 AURA_FREE(pr, dfui_progress);
1144 dfui_progress_get_info(const struct dfui_progress *pr)
1152 dfui_progress_set_amount(struct dfui_progress *pr, int amount)
1156 pr->amount = amount;
1160 dfui_progress_get_amount(const struct dfui_progress *pr)
1168 dfui_progress_set_streaming(struct dfui_progress *pr, int streaming)
1172 pr->streaming = streaming;
1176 dfui_progress_get_streaming(const struct dfui_progress *pr)
1180 return(pr->streaming);
1184 dfui_progress_set_msg_line(struct dfui_progress *pr, const char *msg_line)
1188 if (pr->msg_line != NULL)
1190 pr->msg_line = aura_strdup(msg_line);
1194 dfui_progress_get_msg_line(const struct dfui_progress *pr)
1198 if (pr->msg_line == NULL)
1200 return(pr->msg_line);