1 /*
2 * Copyright (c)2004 Cat's Eye Technologies. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
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
14 * distribution.
15 *
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.
19 *
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.
32 */
33
34 /*
35 * form.c
36 * $Id: form.c,v 1.18 2005/03/04 21:26:20 cpressey Exp $
37 */
38
39 #include <stdarg.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include <libaura/mem.h>
44
45 #define NEEDS_DFUI_STRUCTURE_DEFINITIONS
46 #include "dfui.h"
47 #undef NEEDS_DFUI_STRUCTURE_DEFINITIONS
48 #include "dump.h"
49
50 /*** INFOS ***/
51
52 struct dfui_info *
dfui_info_new(const char * name,const char * short_desc,const char * long_desc)53 dfui_info_new(const char *name, const char *short_desc, const char *long_desc)
54 {
55 struct dfui_info *i;
56
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);
61
62 return(i);
63 }
64
65 void
dfui_info_free(struct dfui_info * i)66 dfui_info_free(struct dfui_info *i)
67 {
68 free(i->name);
69 free(i->short_desc);
70 free(i->long_desc);
71 AURA_FREE(i, dfui_info);
72 }
73
74 const char *
dfui_info_get_name(const struct dfui_info * i)75 dfui_info_get_name(const struct dfui_info *i)
76 {
77 if (i == NULL)
78 return("");
79 return(i->name);
80 }
81
82 const char *
dfui_info_get_short_desc(const struct dfui_info * i)83 dfui_info_get_short_desc(const struct dfui_info *i)
84 {
85 if (i == NULL)
86 return("");
87 return(i->short_desc);
88 }
89
90 const char *
dfui_info_get_long_desc(const struct dfui_info * i)91 dfui_info_get_long_desc(const struct dfui_info *i)
92 {
93 if (i == NULL)
94 return("");
95 return(i->long_desc);
96 }
97
98 void
dfui_info_set_name(struct dfui_info * i,const char * name)99 dfui_info_set_name(struct dfui_info *i, const char *name)
100 {
101 if (i == NULL)
102 return;
103 if (i->name != NULL)
104 free(i->name);
105 i->name = aura_strdup(name);
106 }
107
108 void
dfui_info_set_short_desc(struct dfui_info * i,const char * short_desc)109 dfui_info_set_short_desc(struct dfui_info *i, const char *short_desc)
110 {
111 if (i == NULL)
112 return;
113 if (i->short_desc != NULL)
114 free(i->short_desc);
115 i->short_desc = aura_strdup(short_desc);
116 }
117
118 void
dfui_info_set_long_desc(struct dfui_info * i,const char * long_desc)119 dfui_info_set_long_desc(struct dfui_info *i, const char *long_desc)
120 {
121 if (i == NULL)
122 return;
123 if (i->long_desc != NULL)
124 free(i->long_desc);
125 i->long_desc = aura_strdup(long_desc);
126 }
127
128 /*** PROPERTIES ***/
129
130 struct dfui_property *
dfui_property_new(const char * name,const char * value)131 dfui_property_new(const char *name, const char *value)
132 {
133 struct dfui_property *p;
134
135 AURA_MALLOC(p, dfui_property);
136 p->name = aura_strdup(name);
137 p->value = aura_strdup(value);
138
139 return(p);
140 }
141
142 void
dfui_property_free(struct dfui_property * p)143 dfui_property_free(struct dfui_property *p)
144 {
145 if (p == NULL)
146 return;
147 free(p->name);
148 free(p->value);
149 AURA_FREE(p, dfui_property);
150 }
151
152 void
dfui_properties_free(struct dfui_property * head)153 dfui_properties_free(struct dfui_property *head)
154 {
155 struct dfui_property *p;
156
157 for (p = head; p != NULL; ) {
158 head = p->next;
159 dfui_property_free(p);
160 p = head;
161 }
162 }
163
164 struct dfui_property *
dfui_property_find(struct dfui_property * head,const char * name)165 dfui_property_find(struct dfui_property *head, const char *name)
166 {
167 struct dfui_property *p;
168
169 for (p = head; p != NULL; p = p->next) {
170 if (strcmp(name, p->name) == 0)
171 return(p);
172 }
173
174 return(NULL);
175 }
176
177 const char *
dfui_property_get(struct dfui_property * head,const char * name)178 dfui_property_get(struct dfui_property *head, const char *name)
179 {
180 struct dfui_property *p;
181
182 if ((p = dfui_property_find(head, name)) != NULL)
183 return(p->value);
184 return("");
185 }
186
187 struct dfui_property *
dfui_property_set(struct dfui_property ** head,const char * name,const char * value)188 dfui_property_set(struct dfui_property **head, const char *name, const char *value)
189 {
190 struct dfui_property *p;
191
192 if (head == NULL)
193 return(NULL);
194
195 if ((p = dfui_property_find(*head, name)) != NULL) {
196 free(p->value);
197 p->value = aura_strdup(value);
198 return(p);
199 }
200
201 p = dfui_property_new(name, value);
202 p->next = *head;
203 *head = p;
204
205 return(p);
206 }
207
208 const char *
dfui_property_get_name(const struct dfui_property * p)209 dfui_property_get_name(const struct dfui_property *p)
210 {
211 return(p->name);
212 }
213
214 const char *
dfui_property_get_value(const struct dfui_property * p)215 dfui_property_get_value(const struct dfui_property *p)
216 {
217 return(p->value);
218 }
219
220 /*** FIELDS ***/
221
222 struct dfui_field *
dfui_field_new(const char * id,struct dfui_info * info)223 dfui_field_new(const char *id, struct dfui_info *info)
224 {
225 struct dfui_field *fi;
226
227 AURA_MALLOC(fi, dfui_field);
228 fi->id = aura_strdup(id);
229 fi->info = info;
230 fi->option_head = NULL;
231 fi->property_head = NULL;
232 fi->next = NULL;
233
234 dfui_field_property_set(fi, "editable", "true");
235
236 return(fi);
237 }
238
239 void
dfui_field_free(struct dfui_field * fi)240 dfui_field_free(struct dfui_field *fi)
241 {
242 free(fi->id);
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);
247 }
248
249 void
dfui_fields_free(struct dfui_field * head)250 dfui_fields_free(struct dfui_field *head)
251 {
252 struct dfui_field *fi;
253
254 fi = head;
255 while (fi != NULL) {
256 head = fi->next;
257 dfui_field_free(fi);
258 fi = head;
259 }
260 }
261
262 struct dfui_field *
dfui_field_get_next(const struct dfui_field * fi)263 dfui_field_get_next(const struct dfui_field *fi)
264 {
265 if (fi == NULL)
266 return(NULL);
267 return(fi->next);
268 }
269
270 const char *
dfui_field_get_id(const struct dfui_field * fi)271 dfui_field_get_id(const struct dfui_field *fi)
272 {
273 if (fi == NULL)
274 return(NULL);
275 return(fi->id);
276 }
277
278 struct dfui_info *
dfui_field_get_info(const struct dfui_field * fi)279 dfui_field_get_info(const struct dfui_field *fi)
280 {
281 if (fi == NULL)
282 return(NULL);
283 return(fi->info);
284 }
285
286 struct dfui_option *
dfui_field_option_add(struct dfui_field * fi,const char * value)287 dfui_field_option_add(struct dfui_field *fi, const char *value)
288 {
289 struct dfui_option *o;
290
291 if (fi == NULL)
292 return(NULL);
293 o = dfui_option_new(value);
294 o->next = fi->option_head;
295 fi->option_head = o;
296
297 return(o);
298 }
299
300 struct dfui_option *
dfui_field_option_get_first(const struct dfui_field * fi)301 dfui_field_option_get_first(const struct dfui_field *fi)
302 {
303 if (fi == NULL)
304 return(NULL);
305 return(fi->option_head);
306 }
307
308 struct dfui_property *
dfui_field_property_set(struct dfui_field * fi,const char * name,const char * value)309 dfui_field_property_set(struct dfui_field *fi, const char *name, const char *value)
310 {
311 return(dfui_property_set(&fi->property_head, name, value));
312 }
313
314 const char *
dfui_field_property_get(const struct dfui_field * fi,const char * name)315 dfui_field_property_get(const struct dfui_field *fi, const char *name)
316 {
317 return(dfui_property_get(fi->property_head, name));
318 }
319
320 int
dfui_field_property_is(const struct dfui_field * fi,const char * name,const char * value)321 dfui_field_property_is(const struct dfui_field *fi, const char *name, const char *value)
322 {
323 struct dfui_property *h;
324
325 if (fi == NULL)
326 return(0);
327 if ((h = dfui_property_find(fi->property_head, name)) == NULL)
328 return(0);
329 return(!strcmp(h->value, value));
330 }
331
332 /*** OPTIONS ***/
333
334 struct dfui_option *
dfui_option_new(const char * value)335 dfui_option_new(const char *value)
336 {
337 struct dfui_option *o;
338
339 AURA_MALLOC(o, dfui_option);
340 o->value = aura_strdup(value);
341 o->next = NULL;
342
343 return(o);
344 }
345
346 void
dfui_option_free(struct dfui_option * o)347 dfui_option_free(struct dfui_option *o)
348 {
349 if (o == NULL)
350 return;
351 free(o->value);
352 AURA_FREE(o, dfui_option);
353 }
354
355 void
dfui_options_free(struct dfui_option * head)356 dfui_options_free(struct dfui_option *head)
357 {
358 struct dfui_option *o;
359
360 o = head;
361 while (o != NULL) {
362 head = o->next;
363 dfui_option_free(o);
364 o = head;
365 }
366 }
367
368 struct dfui_option *
dfui_option_get_next(const struct dfui_option * o)369 dfui_option_get_next(const struct dfui_option *o)
370 {
371 if (o == NULL)
372 return(NULL);
373 return(o->next);
374 }
375
376 const char *
dfui_option_get_value(const struct dfui_option * o)377 dfui_option_get_value(const struct dfui_option *o)
378 {
379 if (o == NULL)
380 return("");
381 return(o->value);
382 }
383
384 /*** ACTIONS ***/
385
386 struct dfui_action *
dfui_action_new(const char * id,struct dfui_info * info)387 dfui_action_new(const char *id, struct dfui_info *info)
388 {
389 struct dfui_action *a;
390
391 AURA_MALLOC(a, dfui_action);
392 a->id = aura_strdup(id);
393 a->info = info;
394 a->next = NULL;
395 a->property_head = NULL;
396
397 return(a);
398 }
399
400 void
dfui_action_free(struct dfui_action * a)401 dfui_action_free(struct dfui_action *a)
402 {
403 free(a->id);
404 dfui_info_free(a->info);
405 dfui_properties_free(a->property_head);
406 AURA_FREE(a, dfui_action);
407 }
408
409 void
dfui_actions_free(struct dfui_action * head)410 dfui_actions_free(struct dfui_action *head)
411 {
412 struct dfui_action *a;
413
414 a = head;
415 while (a != NULL) {
416 head = a->next;
417 dfui_action_free(a);
418 a = head;
419 }
420 }
421
422 struct dfui_action *
dfui_action_get_next(const struct dfui_action * a)423 dfui_action_get_next(const struct dfui_action *a)
424 {
425 if (a == NULL)
426 return(NULL);
427 return(a->next);
428 }
429
430 const char *
dfui_action_get_id(const struct dfui_action * a)431 dfui_action_get_id(const struct dfui_action *a)
432 {
433 if (a == NULL)
434 return(NULL);
435 return(a->id);
436 }
437
438 struct dfui_info *
dfui_action_get_info(const struct dfui_action * a)439 dfui_action_get_info(const struct dfui_action *a)
440 {
441 if (a == NULL)
442 return(NULL);
443 return(a->info);
444 }
445
446 struct dfui_property *
dfui_action_property_set(struct dfui_action * a,const char * name,const char * value)447 dfui_action_property_set(struct dfui_action *a, const char *name, const char *value)
448 {
449 return(dfui_property_set(&a->property_head, name, value));
450 }
451
452 const char *
dfui_action_property_get(const struct dfui_action * a,const char * name)453 dfui_action_property_get(const struct dfui_action *a, const char *name)
454 {
455 return(dfui_property_get(a->property_head, name));
456 }
457
458 int
dfui_action_property_is(const struct dfui_action * a,const char * name,const char * value)459 dfui_action_property_is(const struct dfui_action *a, const char *name, const char *value)
460 {
461 struct dfui_property *h;
462
463 if (a == NULL)
464 return(0);
465 if ((h = dfui_property_find(a->property_head, name)) == NULL)
466 return(0);
467 return(!strcmp(h->value, value));
468 }
469
470 /*** FORMS ***/
471
472 struct dfui_form *
dfui_form_new(const char * id,struct dfui_info * info)473 dfui_form_new(const char *id, struct dfui_info *info)
474 {
475 struct dfui_form *f;
476
477 AURA_MALLOC(f, dfui_form);
478 f->id = aura_strdup(id);
479 f->info = info;
480 f->multiple = 0;
481 f->extensible = 0;
482 f->field_head = NULL;
483 f->action_head = NULL;
484 f->dataset_head = NULL;
485 f->property_head = NULL;
486
487 return(f);
488 };
489
490 /*
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).
501 */
502 struct dfui_form *
dfui_form_create(const char * id,const char * name,const char * short_desc,const char * long_desc,...)503 dfui_form_create(const char *id, const char *name,
504 const char *short_desc, const char *long_desc, ...)
505 {
506 #define DFUI_FORM_CREATE_FORM 0
507 #define DFUI_FORM_CREATE_FIELD 1
508 #define DFUI_FORM_CREATE_ACTION 2
509
510 struct dfui_form *f;
511 struct dfui_info *i;
512 va_list args;
513 int state = DFUI_FORM_CREATE_FORM;
514 char *arg;
515 void *object = NULL;
516 const char *a_id;
517 char *a_name, *a_short_desc, *a_long_desc;
518
519 i = dfui_info_new(name, short_desc, long_desc);
520 f = dfui_form_new(id, i);
521
522 va_start(args, long_desc);
523 while ((arg = va_arg(args, char *)) != NULL) {
524 switch (arg[0]) {
525 case 'f':
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;
533 break;
534 case 'a':
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;
542 break;
543 case 'o':
544 a_name = va_arg(args, char *);
545 if (state == DFUI_FORM_CREATE_FIELD) {
546 dfui_field_option_add(object, a_name);
547 } else {
548 dfui_debug("form_create: can't add option to non-field\n");
549 }
550 break;
551 case 'h':
552 case 'p':
553 a_id = va_arg(args, char *);
554 a_short_desc = va_arg(args, char *);
555
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);
562 } else {
563 dfui_debug("form_create: can't add property in this state\n");
564 }
565 break;
566
567 default:
568 dfui_debug("form_create: unknown option `%c'\n", arg[0]);
569 break;
570 }
571 }
572
573 va_end(args);
574 return(f);
575 }
576
577 void
dfui_form_free(struct dfui_form * f)578 dfui_form_free(struct dfui_form *f)
579 {
580 free(f->id);
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);
587 }
588
589 struct dfui_field *
dfui_form_field_add(struct dfui_form * f,const char * id,struct dfui_info * info)590 dfui_form_field_add(struct dfui_form *f, const char *id, struct dfui_info *info)
591 {
592 struct dfui_field *fi;
593
594 if (f == NULL)
595 return(NULL);
596 fi = dfui_field_new(id, info);
597 fi->next = f->field_head;
598 f->field_head = fi;
599
600 return(fi);
601 }
602
603 struct dfui_field *
dfui_form_field_attach(struct dfui_form * f,struct dfui_field * fi)604 dfui_form_field_attach(struct dfui_form *f, struct dfui_field *fi)
605 {
606 if (f == NULL)
607 return(NULL);
608 fi->next = f->field_head;
609 f->field_head = fi;
610
611 return(fi);
612 }
613
614 struct dfui_action *
dfui_form_action_add(struct dfui_form * f,const char * id,struct dfui_info * info)615 dfui_form_action_add(struct dfui_form *f, const char *id, struct dfui_info *info)
616 {
617 struct dfui_action *a;
618
619 if (f == NULL)
620 return(NULL);
621 a = dfui_action_new(id, info);
622 a->next = f->action_head;
623 f->action_head = a;
624
625 return(a);
626 }
627
628 struct dfui_action *
dfui_form_action_attach(struct dfui_form * f,struct dfui_action * a)629 dfui_form_action_attach(struct dfui_form *f, struct dfui_action *a)
630 {
631 if (f == NULL)
632 return(NULL);
633 a->next = f->action_head;
634 f->action_head = a;
635
636 return(a);
637 }
638
639 void
dfui_form_dataset_add(struct dfui_form * f,struct dfui_dataset * ds)640 dfui_form_dataset_add(struct dfui_form *f, struct dfui_dataset *ds)
641 {
642 if (f == NULL || ds == NULL)
643 return;
644 ds->next = f->dataset_head;
645 f->dataset_head = ds;
646 }
647
648 struct dfui_dataset *
dfui_form_dataset_get_first(const struct dfui_form * f)649 dfui_form_dataset_get_first(const struct dfui_form *f)
650 {
651 if (f == NULL)
652 return(NULL);
653 return(f->dataset_head);
654 }
655
656 int
dfui_form_dataset_count(const struct dfui_form * f)657 dfui_form_dataset_count(const struct dfui_form *f)
658 {
659 int n = 0;
660 struct dfui_dataset *ds;
661
662 if (f == NULL)
663 return(0);
664
665 ds = f->dataset_head;
666 while (ds != NULL) {
667 n++;
668 ds = ds->next;
669 }
670
671 return(n);
672 }
673
674 void
dfui_form_datasets_free(struct dfui_form * f)675 dfui_form_datasets_free(struct dfui_form *f)
676 {
677 if (f == NULL)
678 return;
679 dfui_datasets_free(f->dataset_head);
680 f->dataset_head = NULL;
681 }
682
683 struct dfui_field *
dfui_form_field_find(const struct dfui_form * f,const char * id)684 dfui_form_field_find(const struct dfui_form *f, const char *id)
685 {
686 struct dfui_field *fi;
687
688 if (f == NULL)
689 return(NULL);
690
691 fi = f->field_head;
692 while (fi != NULL) {
693 if (!strcmp(id, fi->id))
694 return(fi);
695 fi = fi->next;
696 }
697
698 return(NULL);
699 }
700
701 struct dfui_field *
dfui_form_field_get_first(const struct dfui_form * f)702 dfui_form_field_get_first(const struct dfui_form *f)
703 {
704 if (f == NULL)
705 return(NULL);
706 return(f->field_head);
707 }
708
709 int
dfui_form_field_count(const struct dfui_form * f)710 dfui_form_field_count(const struct dfui_form *f)
711 {
712 int n = 0;
713 struct dfui_field *fi;
714
715 if (f == NULL)
716 return(0);
717
718 fi = f->field_head;
719 while (fi != NULL) {
720 n++;
721 fi = fi->next;
722 }
723
724 return(n);
725 }
726
727 struct dfui_action *
dfui_form_action_find(const struct dfui_form * f,const char * id)728 dfui_form_action_find(const struct dfui_form *f, const char *id)
729 {
730 struct dfui_action *a = f->action_head;
731
732 while (a != NULL) {
733 if (!strcmp(id, a->id))
734 return(a);
735 a = a->next;
736 }
737
738 return(NULL);
739 }
740
741 struct dfui_action *
dfui_form_action_get_first(const struct dfui_form * f)742 dfui_form_action_get_first(const struct dfui_form *f)
743 {
744 if (f == NULL)
745 return(NULL);
746 return(f->action_head);
747 }
748
749 int
dfui_form_action_count(const struct dfui_form * f)750 dfui_form_action_count(const struct dfui_form *f)
751 {
752 int n = 0;
753 struct dfui_action *a;
754
755 if (f == NULL)
756 return(0);
757
758 a = f->action_head;
759 while (a != NULL) {
760 n++;
761 a = a->next;
762 }
763
764 return(n);
765 }
766
767 struct dfui_property *
dfui_form_property_set(struct dfui_form * f,const char * name,const char * value)768 dfui_form_property_set(struct dfui_form *f, const char *name, const char *value)
769 {
770 return(dfui_property_set(&f->property_head, name, value));
771 }
772
773 const char *
dfui_form_property_get(const struct dfui_form * f,const char * name)774 dfui_form_property_get(const struct dfui_form *f, const char *name)
775 {
776 return(dfui_property_get(f->property_head, name));
777 }
778
779 int
dfui_form_property_is(const struct dfui_form * f,const char * name,const char * value)780 dfui_form_property_is(const struct dfui_form *f, const char *name, const char *value)
781 {
782 struct dfui_property *h;
783
784 if (f == NULL)
785 return(0);
786 if ((h = dfui_property_find(f->property_head, name)) == NULL)
787 return(0);
788 return(!strcmp(h->value, value));
789 }
790
791 const char *
dfui_form_get_id(const struct dfui_form * f)792 dfui_form_get_id(const struct dfui_form *f)
793 {
794 if (f == NULL)
795 return(NULL); /* XXX ? */
796 return(f->id);
797 }
798
799 struct dfui_info *
dfui_form_get_info(const struct dfui_form * f)800 dfui_form_get_info(const struct dfui_form *f)
801 {
802 if (f == NULL)
803 return(NULL);
804 return(f->info);
805 }
806
807 void
dfui_form_set_multiple(struct dfui_form * f,int multiple)808 dfui_form_set_multiple(struct dfui_form *f, int multiple)
809 {
810 if (f == NULL)
811 return;
812 f->multiple = multiple;
813 }
814
815 int
dfui_form_is_multiple(const struct dfui_form * f)816 dfui_form_is_multiple(const struct dfui_form *f)
817 {
818 if (f == NULL)
819 return(0);
820 return(f->multiple);
821 }
822
823 void
dfui_form_set_extensible(struct dfui_form * f,int extensible)824 dfui_form_set_extensible(struct dfui_form *f, int extensible)
825 {
826 if (f == NULL)
827 return;
828 f->extensible = extensible;
829 }
830
831 int
dfui_form_is_extensible(const struct dfui_form * f)832 dfui_form_is_extensible(const struct dfui_form *f)
833 {
834 if (f == NULL)
835 return(0);
836 return(f->extensible);
837 }
838
839 /*** CELLDATAS ***/
840
841 struct dfui_celldata *
dfui_celldata_new(const char * field_id,const char * value)842 dfui_celldata_new(const char *field_id, const char *value)
843 {
844 struct dfui_celldata *c;
845
846 AURA_MALLOC(c, dfui_celldata);
847 c->field_id = aura_strdup(field_id);
848 c->value = aura_strdup(value);
849
850 return(c);
851 }
852
853 void
dfui_celldata_free(struct dfui_celldata * c)854 dfui_celldata_free(struct dfui_celldata *c)
855 {
856 if (c == NULL)
857 return;
858 free(c->field_id);
859 free(c->value);
860 AURA_FREE(c, dfui_celldata);
861 }
862
863 void
dfui_celldatas_free(struct dfui_celldata * head)864 dfui_celldatas_free(struct dfui_celldata *head)
865 {
866 struct dfui_celldata *c;
867
868 c = head;
869 while (c != NULL) {
870 head = c->next;
871 dfui_celldata_free(c);
872 c = head;
873 }
874 }
875
876 struct dfui_celldata *
dfui_celldata_find(struct dfui_celldata * head,const char * id)877 dfui_celldata_find(struct dfui_celldata *head, const char *id)
878 {
879 struct dfui_celldata *c;
880
881 c = head;
882 while (c != NULL) {
883 if (!strcmp(id, c->field_id))
884 return(c);
885 c = c->next;
886 }
887
888 return(NULL);
889 }
890
891 struct dfui_celldata *
dfui_celldata_get_next(const struct dfui_celldata * cd)892 dfui_celldata_get_next(const struct dfui_celldata *cd)
893 {
894 if (cd != NULL) {
895 return(cd->next);
896 } else {
897 return(NULL);
898 }
899 }
900
901 const char *
dfui_celldata_get_field_id(const struct dfui_celldata * cd)902 dfui_celldata_get_field_id(const struct dfui_celldata *cd)
903 {
904 if (cd != NULL) {
905 return(cd->field_id);
906 } else {
907 return(NULL);
908 }
909 }
910
911 const char *
dfui_celldata_get_value(const struct dfui_celldata * cd)912 dfui_celldata_get_value(const struct dfui_celldata *cd)
913 {
914 if (cd != NULL) {
915 return(cd->value);
916 } else {
917 return("");
918 }
919 }
920
921 /*** DATASETS ***/
922
923 struct dfui_dataset *
dfui_dataset_new(void)924 dfui_dataset_new(void)
925 {
926 struct dfui_dataset *ds;
927
928 AURA_MALLOC(ds, dfui_dataset);
929 ds->celldata_head = NULL;
930 ds->next = NULL;
931
932 return(ds);
933 }
934
935 struct dfui_dataset *
dfui_dataset_dup(const struct dfui_dataset * ds)936 dfui_dataset_dup(const struct dfui_dataset *ds)
937 {
938 struct dfui_dataset *nds;
939 struct dfui_celldata *cd;
940
941 nds = dfui_dataset_new();
942
943 for (cd = ds->celldata_head; cd != NULL; cd = cd->next) {
944 dfui_dataset_celldata_add(nds,
945 cd->field_id, cd->value);
946 }
947
948 return(nds);
949 }
950
951 void
dfui_dataset_free(struct dfui_dataset * ds)952 dfui_dataset_free(struct dfui_dataset *ds)
953 {
954 dfui_celldatas_free(ds->celldata_head);
955 AURA_FREE(ds, dfui_dataset);
956 }
957
958 void
dfui_datasets_free(struct dfui_dataset * head)959 dfui_datasets_free(struct dfui_dataset *head)
960 {
961 struct dfui_dataset *ds;
962
963 ds = head;
964 while (ds != NULL) {
965 head = ds->next;
966 dfui_dataset_free(ds);
967 ds = head;
968 }
969 }
970
971 struct dfui_celldata *
dfui_dataset_celldata_add(struct dfui_dataset * ds,const char * field_id,const char * value)972 dfui_dataset_celldata_add(struct dfui_dataset *ds, const char *field_id, const char *value)
973 {
974 struct dfui_celldata *c;
975
976 if (ds == NULL)
977 return(NULL);
978
979 c = dfui_celldata_new(field_id, value);
980 c->next = ds->celldata_head;
981 ds->celldata_head = c;
982
983 return(c);
984 }
985
986 struct dfui_celldata *
dfui_dataset_celldata_get_first(const struct dfui_dataset * ds)987 dfui_dataset_celldata_get_first(const struct dfui_dataset *ds)
988 {
989 if (ds == NULL)
990 return(NULL);
991 return(ds->celldata_head);
992 }
993
994 struct dfui_celldata *
dfui_dataset_celldata_find(const struct dfui_dataset * ds,const char * field_id)995 dfui_dataset_celldata_find(const struct dfui_dataset *ds, const char *field_id)
996 {
997 if (ds == NULL)
998 return(NULL);
999 return(dfui_celldata_find(ds->celldata_head, field_id));
1000 }
1001
1002 struct dfui_dataset *
dfui_dataset_get_next(const struct dfui_dataset * ds)1003 dfui_dataset_get_next(const struct dfui_dataset *ds)
1004 {
1005 if (ds == NULL)
1006 return(NULL);
1007 return(ds->next);
1008 }
1009
1010 /*
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.
1015 */
1016 const char *
dfui_dataset_get_value(const struct dfui_dataset * ds,const char * id)1017 dfui_dataset_get_value(const struct dfui_dataset *ds, const char *id)
1018 {
1019 struct dfui_celldata *cd;
1020
1021 if ((cd = dfui_dataset_celldata_find(ds, id)) != NULL) {
1022 return(dfui_celldata_get_value(cd));
1023 } else {
1024 return("");
1025 }
1026 }
1027
1028 /*
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.
1034 */
1035 char *
dfui_dataset_dup_value(const struct dfui_dataset * ds,const char * id)1036 dfui_dataset_dup_value(const struct dfui_dataset *ds, const char *id)
1037 {
1038 return(aura_strdup(dfui_dataset_get_value(ds, id)));
1039 }
1040
1041 /*** RESPONSES ***/
1042
1043 struct dfui_response *
dfui_response_new(const char * form_id,const char * action_id)1044 dfui_response_new(const char *form_id, const char *action_id)
1045 {
1046 struct dfui_response *r;
1047
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;
1052
1053 return(r);
1054 }
1055
1056 void
dfui_response_free(struct dfui_response * r)1057 dfui_response_free(struct dfui_response *r)
1058 {
1059 free(r->form_id);
1060 free(r->action_id);
1061 dfui_datasets_free(r->dataset_head);
1062 AURA_FREE(r, dfui_response);
1063 }
1064
1065 void
dfui_response_dataset_add(struct dfui_response * r,struct dfui_dataset * ds)1066 dfui_response_dataset_add(struct dfui_response *r, struct dfui_dataset *ds)
1067 {
1068 if (ds == NULL || r == NULL)
1069 return;
1070 ds->next = r->dataset_head;
1071 r->dataset_head = ds;
1072 }
1073
1074 struct dfui_dataset *
dfui_response_dataset_get_first(const struct dfui_response * r)1075 dfui_response_dataset_get_first(const struct dfui_response *r)
1076 {
1077 if (r == NULL)
1078 return(NULL);
1079 return(r->dataset_head);
1080 }
1081
1082 int
dfui_response_dataset_count(const struct dfui_response * r)1083 dfui_response_dataset_count(const struct dfui_response *r)
1084 {
1085 int n = 0;
1086 struct dfui_dataset *ds;
1087
1088 if (r == NULL)
1089 return(0);
1090
1091 ds = r->dataset_head;
1092 while (ds != NULL) {
1093 n++;
1094 ds = ds->next;
1095 }
1096
1097 return(n);
1098 }
1099
1100 const char *
dfui_response_get_form_id(const struct dfui_response * r)1101 dfui_response_get_form_id(const struct dfui_response *r)
1102 {
1103 if (r == NULL)
1104 return(NULL); /* XXX ? */
1105 return(r->form_id);
1106 }
1107
1108 const char *
dfui_response_get_action_id(const struct dfui_response * r)1109 dfui_response_get_action_id(const struct dfui_response *r)
1110 {
1111 if (r == NULL)
1112 return(NULL); /* XXX ? */
1113 return(r->action_id);
1114 }
1115
1116 /* PROGRESS BARS */
1117
1118 struct dfui_progress *
dfui_progress_new(struct dfui_info * info,int amount)1119 dfui_progress_new(struct dfui_info *info, int amount)
1120 {
1121 struct dfui_progress *pr;
1122
1123 AURA_MALLOC(pr, dfui_progress);
1124 pr->info = info;
1125 pr->amount = amount;
1126 pr->streaming = 0;
1127 pr->msg_line = NULL;
1128
1129 return(pr);
1130 }
1131
1132 void
dfui_progress_free(struct dfui_progress * pr)1133 dfui_progress_free(struct dfui_progress *pr)
1134 {
1135 if (pr == NULL)
1136 return;
1137 dfui_info_free(pr->info);
1138 if (pr->msg_line != NULL)
1139 free(pr->msg_line);
1140 AURA_FREE(pr, dfui_progress);
1141 }
1142
1143 struct dfui_info *
dfui_progress_get_info(const struct dfui_progress * pr)1144 dfui_progress_get_info(const struct dfui_progress *pr)
1145 {
1146 if (pr == NULL)
1147 return(NULL);
1148 return(pr->info);
1149 }
1150
1151 void
dfui_progress_set_amount(struct dfui_progress * pr,int amount)1152 dfui_progress_set_amount(struct dfui_progress *pr, int amount)
1153 {
1154 if (pr == NULL)
1155 return;
1156 pr->amount = amount;
1157 }
1158
1159 int
dfui_progress_get_amount(const struct dfui_progress * pr)1160 dfui_progress_get_amount(const struct dfui_progress *pr)
1161 {
1162 if (pr == NULL)
1163 return(0);
1164 return(pr->amount);
1165 }
1166
1167 void
dfui_progress_set_streaming(struct dfui_progress * pr,int streaming)1168 dfui_progress_set_streaming(struct dfui_progress *pr, int streaming)
1169 {
1170 if (pr == NULL)
1171 return;
1172 pr->streaming = streaming;
1173 }
1174
1175 int
dfui_progress_get_streaming(const struct dfui_progress * pr)1176 dfui_progress_get_streaming(const struct dfui_progress *pr)
1177 {
1178 if (pr == NULL)
1179 return(0);
1180 return(pr->streaming);
1181 }
1182
1183 void
dfui_progress_set_msg_line(struct dfui_progress * pr,const char * msg_line)1184 dfui_progress_set_msg_line(struct dfui_progress *pr, const char *msg_line)
1185 {
1186 if (pr == NULL)
1187 return;
1188 if (pr->msg_line != NULL)
1189 free(pr->msg_line);
1190 pr->msg_line = aura_strdup(msg_line);
1191 }
1192
1193 const char *
dfui_progress_get_msg_line(const struct dfui_progress * pr)1194 dfui_progress_get_msg_line(const struct dfui_progress *pr)
1195 {
1196 if (pr == NULL)
1197 return("");
1198 if (pr->msg_line == NULL)
1199 return("");
1200 return(pr->msg_line);
1201 }
1202