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
);