2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: PdmOid.c /main/12 1997/11/20 16:37:12 bill $ */
28 * (c) Copyright 1996 Digital Equipment Corporation.
29 * (c) Copyright 1996 Hewlett-Packard Company.
30 * (c) Copyright 1996 International Business Machines Corp.
31 * (c) Copyright 1996 Sun Microsystems, Inc.
32 * (c) Copyright 1996 Novell, Inc.
33 * (c) Copyright 1996 FUJITSU LIMITED.
34 * (c) Copyright 1996 Hitachi.
41 #include <Dt/DtNlUtils.h>
46 * PdmOidNotify value strings
48 #define NOTIFY_EMAIL_STR "{{event-report-job-completed} electronic-mail}"
49 #define NOTIFY_NONE_STR "{}"
52 * entry type for the object identifier string map
54 typedef struct _PdmOidStringMapEntry
60 const char* default_message;
62 } PdmOidStringMapEntry;
65 * include the auto-generated static PdmOidStringMap
67 #include "PdmOidStrs.h"
70 * PdmOid static function declarations
72 static PdmOid PdmOidParse(const char* value_string,
73 const char** ptr_return);
75 * PdmOidList static function declarations
77 static PdmOidList* PdmOidListParse(const char* value_string,
78 const char** ptr_return, int i);
82 * PdmOidMediumSourceSize static function declarations
84 static PdmOidMediumSS* MediumSSParse(const char* value_string,
85 const char** ptr_return, int i);
86 static PdmOidMediumContinuousSize* MediumContinuousSizeParse(const char*,
88 static void MediumContinuousSizeDelete(PdmOidMediumContinuousSize* me);
89 static PdmOidMediumDiscreteSizeList* MediumDiscreteSizeListParse(const char*,
92 static void MediumDiscreteSizeListDelete(PdmOidMediumDiscreteSizeList* list);
94 static Boolean ParseArea(const char* value_string,
95 const char** ptr_return,
96 PdmOidArea* area_return);
97 static Boolean ParseUnsignedRange(const char* value_string,
98 const char** ptr_return,
99 PdmOidUnsignedRange* range_return);
102 * PdmOidTrayMediumList static function declarations
104 static PdmOidTrayMediumList* TrayMediumListParse(const char* value_string,
105 const char** ptr_return,
109 * PdmOidDocumentFormat
111 static char* PdmOidDocumentFormatNext(const char* value_string,
112 const char** ptr_return);
114 * misc. parsing static function declarations
116 static Boolean ParseBooleanValue(const char* value_string,
117 const char** ptr_return,
118 Boolean* boolean_return);
119 static Boolean ParseUnsignedValue(const char* value_string,
120 const char** ptr_return,
121 unsigned long* unsigned_return);
122 static Boolean ParseRealValue(const char* value_string,
123 const char** ptr_return,
125 static Boolean ParseSeqEnd(
126 const char* value_string,
127 const char** ptr_return);
128 static Boolean ParseSeqStart(
129 const char* value_string,
130 const char** ptr_return);
131 static Boolean ParseUnspecifiedValue(
132 const char* value_string,
133 const char** ptr_return);
134 static int SpanToken(
136 static int SpanWhitespace(
141 * ------------------------------------------------------------------------
151 PdmOidString(PdmOid pdm_oid)
154 * PdmOid enum values are index values into the string map
156 return PdmOidStringMap[pdm_oid].string;
160 * ------------------------------------------------------------------------
170 PdmOidMsgSet(PdmOid pdm_oid)
173 * PdmOid enum values are index values into the string map
175 return PdmOidStringMap[pdm_oid].msg_set;
179 * ------------------------------------------------------------------------
189 PdmOidMsgNum(PdmOid pdm_oid)
192 * PdmOid enum values are index values into the string map
194 return PdmOidStringMap[pdm_oid].msg_number;
198 * ------------------------------------------------------------------------
199 * Name: PdmOidDefaultMsg
208 PdmOidDefaultMsg(PdmOid pdm_oid)
210 if(PdmOidStringMap[pdm_oid].default_message == (const char*)NULL)
211 return PdmOidStringMap[pdm_oid].string;
213 return PdmOidStringMap[pdm_oid].default_message;
217 * ------------------------------------------------------------------------
218 * Name: PdmOidStringLength
227 PdmOidStringLength(PdmOid pdm_oid)
230 * PdmOid enum values are index values into the string map
232 return PdmOidStringMap[pdm_oid].length;
236 * ------------------------------------------------------------------------
237 * Name: PdmOidFromString
246 PdmOidFromString(const char* value)
248 if(value == (const char*)NULL)
251 return PdmOidParse(value, (const char**)NULL);
255 * ------------------------------------------------------------------------
260 * Parse the next whitespace-delimited string from 'value_string'
261 * updating 'ptr_return' to point to the next unparsed location in
262 * 'value_string'. 'ptr_return' can be NULL.
266 * The corresponding PdmOid for the parsed name string.
267 * A return value of pdmoid_none is returned if the parsed name
268 * was not a valid oid or if no name was found.
272 PdmOidParse(const char* value_string,
273 const char** ptr_return)
280 * skip leading whitespace
282 ptr = value_string + SpanWhitespace(value_string);
284 * get the whitespace-delimited token length
286 length = SpanToken(ptr);
288 * match the oid string in the map
290 for(i = 0; i < PdmOidStringMapCount; i++)
291 if(length == PdmOidStringMap[i].length)
292 if(strncmp(ptr, PdmOidStringMap[i].string, length) == 0)
294 if(i == PdmOidStringMapCount)
297 * update the return pointer and return
299 if(ptr_return != (const char**)NULL)
300 *ptr_return = ptr+length;
305 * ------------------------------------------------------------------------
306 * Name: PdmOidListNew
317 PdmOidListNew(const char* value_string)
319 if(value_string == (const char*)NULL)
320 return (PdmOidList*)NULL;
324 return PdmOidListParse(value_string, &ptr, 0);
330 * ------------------------------------------------------------------------
331 * Name: PdmOidListParse
335 * 'ptr_return' *cannot* be NULL.
343 PdmOidListParse(const char* value_string,
344 const char** ptr_return, int i)
346 PdmOid oid = pdmoid_none;
349 * parse the next valid oid out of the value string
351 ptr_return = &value_string;
352 while(**ptr_return != '\0' &&
353 (oid = PdmOidParse(*ptr_return, ptr_return)) == pdmoid_none);
354 if(oid == pdmoid_none)
357 * end of value string; allocate the list structure
359 list = (PdmOidList*)XtCalloc(1, sizeof(PdmOidList));
361 list->list = (PdmOid*)XtCalloc(i, sizeof(PdmOid));
368 list = PdmOidListParse(*ptr_return, ptr_return, i+1);
370 * set the oid in the list
381 * ------------------------------------------------------------------------
382 * Name: PdmOidListHasOid
394 PdmOidListHasOid(const PdmOidList* list, PdmOid oid)
397 if(list != (PdmOidList*)NULL)
398 for(i = 0; i < list->count; i++)
399 if(list->list[i] == oid)
405 * ------------------------------------------------------------------------
406 * Name: PdmOidListGetIndex
418 PdmOidListGetIndex(const PdmOidList* list, PdmOid oid)
421 if(list != (PdmOidList*)NULL)
422 for(i = 0; i < list->count; i++)
423 if(list->list[i] == oid)
429 * ------------------------------------------------------------------------
430 * Name: PdmOidListDelete
442 PdmOidListDelete(PdmOidList* list)
444 if(list != (PdmOidList*)NULL)
446 XtFree((char*)list->list);
452 * ------------------------------------------------------------------------
453 * Name: PdmOidLinkedListNew
462 PdmOidLinkedListNew()
464 return (PdmOidLinkedList*)XtCalloc(1, sizeof(PdmOidLinkedList));
468 * ------------------------------------------------------------------------
469 * Name: PdmOidLinkedListDelete
478 PdmOidLinkedListDelete(PdmOidLinkedList* me)
480 if(me != (PdmOidLinkedList*)NULL)
484 me->current = me->head;
485 me->head = me->current->next;
486 XtFree((char*)me->current);
493 * ------------------------------------------------------------------------
494 * Name: PdmOidLinkedListGetOid
503 PdmOidLinkedListGetOid(PdmOidLinkedList* me, int i)
505 if(i < 0 || i >= me->count) return pdmoid_none;
506 me->current = me->head;
507 while(i--) me->current = me->current->next;
508 return me->current->oid;
512 * ------------------------------------------------------------------------
513 * Name: PdmOidLinkedListAddOid
522 PdmOidLinkedListAddOid(PdmOidLinkedList* me, PdmOid oid)
524 me->current = (PdmOidNode)XtCalloc(1, sizeof(struct PdmOidNodeStruct));
525 me->current->oid = oid;
529 me->tail->next = me->current;
530 me->tail = me->current;
533 me->head = me->tail = me->current;
537 * ------------------------------------------------------------------------
538 * Name: PdmOidLinkedListGetIndex
547 PdmOidLinkedListGetIndex(PdmOidLinkedList* me, PdmOid oid)
550 me->current = me->head;
552 if(me->current->oid == oid)
557 me->current = me->current->next;
563 * ------------------------------------------------------------------------
564 * Name: PdmOidLinkedListHasOid
573 PdmOidLinkedListHasOid(PdmOidLinkedList* me,
576 me->current = me->head;
578 if(me->current->oid == oid)
581 me->current = me->current->next;
586 * ------------------------------------------------------------------------
587 * Name: PdmOidLinkedListFirstOid
596 PdmOidLinkedListFirstOid(PdmOidLinkedList* me)
598 if(me->current = me->head)
599 return me->current->oid;
605 * ------------------------------------------------------------------------
606 * Name: PdmOidLinkedListNextOid
615 PdmOidLinkedListNextOid(PdmOidLinkedList* me)
617 if(me->current ? me->current = me->current->next : False)
618 return me->current->oid;
624 * ------------------------------------------------------------------------
625 * Name: PdmOidLocalString
634 PdmOidLocalString(PdmOid pdm_oid)
637 * PdmOid enum values are index values into the string map
639 if(PdmOidStringMap[pdm_oid].msg_set != -1)
641 return DTPDM_GETMESSAGE(PdmOidStringMap[pdm_oid].msg_set,
642 PdmOidStringMap[pdm_oid].msg_number,
643 PdmOidStringMap[pdm_oid].string);
646 return PdmOidStringMap[pdm_oid].string;
650 * ------------------------------------------------------------------------
651 * Name: PdmOidMediumSSNew
663 PdmOidMediumSSNew(const char* value_string)
665 if(value_string == (const char*)NULL)
666 return (PdmOidMediumSS*)NULL;
670 return MediumSSParse(value_string, &ptr, 0);
675 * ------------------------------------------------------------------------
676 * Name: MediumSSParse
680 * 'ptr_return' *cannot* be NULL.
688 static PdmOidMediumSS*
689 MediumSSParse(const char* value_string,
690 const char** ptr_return, int i)
692 PdmOidMediumSS* medium_ss;
693 PdmOidMediumSourceSize mss;
695 * check for the start of a new MediumSourceSize sequence
697 if(ParseSeqStart(value_string, ptr_return))
700 * check for an unspecified tray value
702 if(ParseUnspecifiedValue(*ptr_return, ptr_return))
703 mss.input_tray = pdmoid_unspecified;
707 * parse out the input tray
709 mss.input_tray = PdmOidParse(*ptr_return, ptr_return);
712 * attempt to parse a Continuous MediumSize sequence
714 mss.ms.continuous_size =
715 MediumContinuousSizeParse(*ptr_return, ptr_return);
716 if(mss.ms.continuous_size != (PdmOidMediumContinuousSize*)NULL)
718 mss.mstag = PdmOidMediumSS_CONTINUOUS;
723 * not continuous, try Discrete MediumSize
726 MediumDiscreteSizeListParse(*ptr_return, ptr_return, 0);
727 if(mss.ms.discrete == (PdmOidMediumDiscreteSizeList*)NULL)
730 * syntax error (MediumDiscreteSizeListParse reports error)
734 mss.mstag = PdmOidMediumSS_DISCRETE;
737 * parse out the MediumSourceSize sequence end
739 if(!ParseSeqEnd(*ptr_return, ptr_return))
744 fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
748 * recurse to parse the next MediumSourceSize sequence
750 medium_ss = MediumSSParse(*ptr_return, ptr_return, i+1);
751 if(medium_ss == (PdmOidMediumSS*)NULL)
754 * syntax error - clean up and return
758 case PdmOidMediumSS_CONTINUOUS:
759 MediumContinuousSizeDelete(mss.ms.continuous_size);
761 case PdmOidMediumSS_DISCRETE:
762 MediumDiscreteSizeListDelete(mss.ms.discrete);
768 * copy the current MediumSourceSize into the array
770 memmove((medium_ss->mss)+i, &mss, sizeof(PdmOidMediumSourceSize));
775 * MediumSourceSize sequence start not found
777 if(**ptr_return == '\0')
780 * end of value string; allocate the MediumSS structure
782 medium_ss = (PdmOidMediumSS*)XtCalloc(1, sizeof(PdmOidMediumSS));
783 medium_ss->count = i;
784 medium_ss->mss = (PdmOidMediumSourceSize*)
785 XtCalloc(i, sizeof(PdmOidMediumSourceSize));
792 fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
800 * ------------------------------------------------------------------------
801 * Name: PdmOidMediumSSDelete
813 PdmOidMediumSSDelete(PdmOidMediumSS* me)
815 if(me != (PdmOidMediumSS*)NULL)
818 for(i = 0; i < me->count; i++)
820 switch((me->mss)[i].mstag)
822 case PdmOidMediumSS_CONTINUOUS:
823 MediumContinuousSizeDelete((me->mss)[i].ms.continuous_size);
825 case PdmOidMediumSS_DISCRETE:
826 MediumDiscreteSizeListDelete((me->mss)[i].ms.discrete);
835 * ------------------------------------------------------------------------
836 * Name: PdmOidMediumSSGetAllSizes
848 PdmOidMediumSSGetAllSizes(PdmOidMediumSS* me)
850 PdmOidLinkedList* all_sizes;
852 PdmOidMediumDiscreteSizeList* ds_list;
855 if(me == (PdmOidMediumSS*)NULL)
856 return (PdmOidLinkedList*)NULL;
858 all_sizes = PdmOidLinkedListNew();
860 * loop through the MediumSourceSizes
862 for(i_mss = 0; i_mss < me->count; i_mss++)
864 switch((me->mss)[i_mss].mstag)
866 case PdmOidMediumSS_DISCRETE:
868 * add unique discrete sizes to the size list
870 ds_list = (me->mss)[i_mss].ms.discrete;
871 for(i_ds = 0; i_ds < ds_list->count; i_ds++)
873 page_size = (ds_list->list)[i_ds].page_size;
874 if(page_size == pdmoid_none)
876 if(!PdmOidLinkedListHasOid(all_sizes, page_size))
878 PdmOidLinkedListAddOid(all_sizes, page_size);
883 case PdmOidMediumSS_CONTINUOUS:
897 * ------------------------------------------------------------------------
898 * Name: PdmOidMediumSSGetTraysSizes
910 PdmOidMediumSSGetTraysSizes(PdmOidMediumSS* me,
911 PdmOidTrayMediumList* trays_medium,
915 int i_mss, i_ds, i_itm, i_its;
916 PdmOidMediumDiscreteSizeList* ds_list;
918 PdmOid current_tray, current_medium;
919 PdmOidMediumDiscreteSizeList* unspecified_tray_ds;
920 PdmOidMediumDiscreteSizeList* tray_ds;
922 if(me == (PdmOidMediumSS*)NULL
924 trays_medium == (PdmOidTrayMediumList*)NULL)
926 if(trays != (PdmOidList**)NULL) *trays = (PdmOidList*)NULL;
927 if(sizes != (PdmOidList**)NULL) *sizes = (PdmOidList*)NULL;
931 * allocate the trays and sizes lists
933 tray_count = PdmOidTrayMediumListCount(trays_medium);
936 if(trays != (PdmOidList**)NULL) *trays = (PdmOidList*)NULL;
937 if(sizes != (PdmOidList**)NULL) *sizes = (PdmOidList*)NULL;
940 if(trays != (PdmOidList**)NULL)
942 *trays = (PdmOidList*)XtCalloc(1, sizeof(PdmOidList));
943 (*trays)->list = (PdmOid*)XtCalloc(tray_count, sizeof(PdmOid));
945 if(sizes != (PdmOidList**)NULL)
947 *sizes = (PdmOidList*)XtCalloc(1, sizeof(PdmOidList));
948 (*sizes)->list = (PdmOid*)XtCalloc(tray_count, sizeof(PdmOid));
951 * loop through the input trays medium list
954 for(i_itm = 0; i_itm < tray_count; i_itm++)
956 current_tray = PdmOidTrayMediumListTray(trays_medium, i_itm);
957 if(current_tray == pdmoid_none)
959 current_medium = PdmOidTrayMediumListMedium(trays_medium, i_itm);
960 if(current_medium == pdmoid_none)
963 * loop through the MediumSourceSizes, looking for an appropriate
964 * discrete sizes spec for the current tray
966 unspecified_tray_ds = (PdmOidMediumDiscreteSizeList*)NULL;
967 tray_ds = (PdmOidMediumDiscreteSizeList*)NULL;
970 && tray_ds == (PdmOidMediumDiscreteSizeList*)NULL;
973 switch((me->mss)[i_mss].mstag)
975 case PdmOidMediumSS_DISCRETE:
976 if((me->mss)[i_mss].input_tray == current_tray)
977 tray_ds = (me->mss)[i_mss].ms.discrete;
978 else if ((me->mss)[i_mss].input_tray == pdmoid_unspecified)
979 unspecified_tray_ds = (me->mss)[i_mss].ms.discrete;
982 case PdmOidMediumSS_CONTINUOUS:
990 * if the tray was not matched, use the unspecifed tray size list
992 if(tray_ds == (PdmOidMediumDiscreteSizeList*)NULL)
993 if(unspecified_tray_ds == (PdmOidMediumDiscreteSizeList*)NULL)
996 * not even an unspecified tray, skip this
997 * input-trays-medium entry.
1002 tray_ds = unspecified_tray_ds;
1004 * loop through the discrete sizes list, looking for a size that
1005 * matches the medium for the current input tray
1007 for(i_ds = 0; i_ds < tray_ds->count; i_ds++)
1010 * check to see if the current input tray's medium size
1011 * matches the current discrete size
1013 * Note: in the CDEnext SI, medium identifiers coincide with
1014 * medium-size identifiers. If the DP-Medium object is
1015 * ever implemented, this check would need to be
1016 * changed so that the input tray's medium size is
1017 * obtained from the indicated Medium object, and not
1018 * inferred from the medium identifier itself.
1020 if((tray_ds->list)[i_ds].page_size == current_medium)
1023 * the current input tray's medium size matches the
1024 * current discrete size; add the tray and medium size
1025 * Oids to the return lists.
1027 if(trays != (PdmOidList**)NULL)
1028 (*trays)->list[i_its] = current_tray;
1029 if(sizes != (PdmOidList**)NULL)
1030 (*sizes)->list[i_its] = (tray_ds->list)[i_ds].page_size;
1036 if(trays != (PdmOidList**)NULL) (*trays)->count = i_its;
1037 if(sizes != (PdmOidList**)NULL) (*sizes)->count = i_its;
1041 * ------------------------------------------------------------------------
1042 * Name: MediumContinuousSizeParse
1046 * 'ptr_return' *cannot* be NULL.
1054 static PdmOidMediumContinuousSize*
1055 MediumContinuousSizeParse(const char* value_string,
1056 const char** ptr_return)
1058 const char* first_nonws_ptr;
1059 PdmOidMediumContinuousSize* mcs = NULL;
1061 * skip leading whitespace
1063 first_nonws_ptr = value_string + SpanWhitespace(value_string);
1065 * parse out the MediumSize sequence start char
1067 if(!ParseSeqStart(first_nonws_ptr, ptr_return))
1068 goto MediumContinuousSizeParse_error;
1070 * peek ahead to see if it looks like we actually have a continuous
1071 * size spec (looking for the sequence start char on the 1st range spec)
1073 if(!ParseSeqStart(*ptr_return, (const char**)NULL))
1074 goto MediumContinuousSizeParse_error;
1076 * Ok, let's go for it
1078 mcs = (PdmOidMediumContinuousSize*)
1079 XtCalloc(1, sizeof(PdmOidMediumContinuousSize));
1081 * "range across the feed direction"
1083 if(!ParseUnsignedRange(*ptr_return, ptr_return, &mcs->range_across_feed))
1084 goto MediumContinuousSizeParse_error;
1086 * "increment across the feed direction" (optional, default 0)
1088 if(!ParseUnspecifiedValue(*ptr_return, ptr_return))
1089 if(!ParseUnsignedValue(*ptr_return, ptr_return,
1090 &mcs->increment_across_feed))
1091 goto MediumContinuousSizeParse_error;
1093 * "range in the feed direction"
1095 if(!ParseUnsignedRange(*ptr_return, ptr_return, &mcs->range_in_feed))
1096 goto MediumContinuousSizeParse_error;
1098 * "increment in the feed direction" (optional, default 0)
1100 if(!ParseUnspecifiedValue(*ptr_return, ptr_return))
1101 if(!ParseUnsignedValue(*ptr_return, ptr_return,
1102 &mcs->increment_in_feed))
1103 goto MediumContinuousSizeParse_error;
1105 * "long edge feeds" flag (default TRUE)
1107 if(ParseUnspecifiedValue(*ptr_return, ptr_return))
1108 mcs->long_edge_feeds = True;
1110 if(!ParseBooleanValue(*ptr_return, ptr_return, &mcs->long_edge_feeds))
1111 goto MediumContinuousSizeParse_error;
1113 * "generic assured reproduction area"
1115 if(!ParseArea(*ptr_return, ptr_return, &mcs->assured_reproduction_area))
1116 goto MediumContinuousSizeParse_error;
1118 * parse out the MediumSize sequence end character
1120 if(!ParseSeqEnd(*ptr_return, ptr_return))
1121 goto MediumContinuousSizeParse_error;
1128 MediumContinuousSizeParse_error:
1130 * syntax error - don't log since this function may be called
1133 *ptr_return = first_nonws_ptr;
1139 * ------------------------------------------------------------------------
1140 * Name: MediumContinuousSizeDelete
1144 * 'ptr_return' *cannot* be NULL.
1153 MediumContinuousSizeDelete(PdmOidMediumContinuousSize* me)
1159 * ------------------------------------------------------------------------
1160 * Name: MediumDiscreteSizeListParse
1164 * 'ptr_return' *cannot* be NULL.
1171 static PdmOidMediumDiscreteSizeList*
1172 MediumDiscreteSizeListParse(const char* value_string,
1173 const char** ptr_return, int i)
1175 PdmOidMediumDiscreteSizeList* list;
1176 PdmOidMediumDiscreteSize mds;
1178 * check for the start of a new MediumSize sequence
1180 if(ParseSeqStart(value_string, ptr_return))
1185 mds.page_size = PdmOidParse(*ptr_return, ptr_return);
1187 * "long edge feeds" flag (default TRUE)
1189 if(ParseUnspecifiedValue(*ptr_return, ptr_return))
1190 mds.long_edge_feeds = True;
1192 if(!ParseBooleanValue(*ptr_return, ptr_return,
1193 &mds.long_edge_feeds))
1198 fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
1202 * "assured reproduction area"
1204 if(!ParseArea(*ptr_return, ptr_return,
1205 &mds.assured_reproduction_area))
1210 fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
1214 * parse out the MediumSize sequence end character
1216 if(!ParseSeqEnd(*ptr_return, ptr_return))
1218 fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
1222 * recurse to parse the next Discrete MediumSize sequence
1224 list = MediumDiscreteSizeListParse(*ptr_return, ptr_return, i+1);
1225 if(list != (PdmOidMediumDiscreteSizeList*)NULL)
1228 * copy the current discrete MediumSize into the list
1230 memmove((list->list)+i, &mds, sizeof(PdmOidMediumDiscreteSize));
1236 * MediumSize sequence start not found; end of the discrete sizes
1239 list = (PdmOidMediumDiscreteSizeList*)
1240 XtCalloc(1, sizeof(PdmOidMediumDiscreteSizeList));
1242 list->list = (PdmOidMediumDiscreteSize*)
1243 XtCalloc(i, sizeof(PdmOidMediumDiscreteSize));
1249 * ------------------------------------------------------------------------
1250 * Name: MediumDiscreteSizeListDelete
1262 MediumDiscreteSizeListDelete(PdmOidMediumDiscreteSizeList* list)
1264 if(list != (PdmOidMediumDiscreteSizeList*)NULL)
1266 XtFree((char*)list->list);
1267 XtFree((char*)list);
1272 * ------------------------------------------------------------------------
1273 * Name: PdmOidTrayMediumListNew
1283 PdmOidTrayMediumList*
1284 PdmOidTrayMediumListNew(const char* value_string)
1286 if(value_string == (const char*)NULL)
1287 return (PdmOidTrayMediumList*)NULL;
1291 return TrayMediumListParse(value_string, &ptr, 0);
1296 * ------------------------------------------------------------------------
1297 * Name: TrayMediumListParse
1301 * 'ptr_return' *cannot* be NULL.
1308 static PdmOidTrayMediumList*
1309 TrayMediumListParse(const char* value_string,
1310 const char** ptr_return, int i)
1312 PdmOidTrayMedium tm;
1313 PdmOidTrayMediumList* list;
1315 * check for the start of a new InputTrayMedium sequence
1317 if(ParseSeqStart(value_string, ptr_return))
1322 tm.input_tray = PdmOidParse(*ptr_return, ptr_return);
1326 tm.medium = PdmOidParse(*ptr_return, ptr_return);
1328 * parse out the InputTrayMedium sequence end character
1330 if(!ParseSeqEnd(*ptr_return, ptr_return))
1332 fprintf(stderr, "%s\n", PDM_MSG_WARN_ITM);
1336 * recurse to parse the next InputTrayMedium sequence
1338 list = TrayMediumListParse(*ptr_return, ptr_return, i+1);
1339 if(list != (PdmOidTrayMediumList*)NULL)
1342 * copy the current InputTrayMedium into the list
1344 memmove((list->list)+i, &tm, sizeof(PdmOidTrayMedium));
1350 * InputTrayMedium sequence start not found
1352 if(**ptr_return == '\0')
1357 list = (PdmOidTrayMediumList*)
1358 XtCalloc(1, sizeof(PdmOidTrayMediumList));
1363 list->list = (PdmOidTrayMedium*)
1364 XtCalloc(i, sizeof(PdmOidTrayMedium));
1371 fprintf(stderr, "%s\n", PDM_MSG_WARN_ITM);
1382 * ------------------------------------------------------------------------
1383 * Name: PdmOidTrayMediumListDelete
1395 PdmOidTrayMediumListDelete(PdmOidTrayMediumList* list)
1397 if(list != (PdmOidTrayMediumList*)NULL)
1399 XtFree((char*)list->list);
1400 XtFree((char*)list);
1405 * ------------------------------------------------------------------------
1410 * Skips leading whitespace and parses out and returns a PdmOidArea.
1414 * True if the PdmOidArea was successfully parsed. ptr_return is
1415 * updated to point to location where the parsing ended.
1417 * False if a PdmOidArea was not found; ptr_return is updated
1418 * to point to the first non-whitespace char in value_string.
1422 ParseArea(const char* value_string,
1423 const char** ptr_return,
1424 PdmOidArea* area_return)
1426 const char* first_nonws_ptr;
1429 * skip leading whitespace
1431 first_nonws_ptr = value_string + SpanWhitespace(value_string);
1433 * parse out the area sequence start
1435 if(!ParseSeqStart(first_nonws_ptr, &ptr))
1436 goto ParseArea_error;
1438 * parse the minimum x value
1440 if(!ParseRealValue(ptr, &ptr,
1441 area_return ? &area_return->minimum_x : NULL))
1442 goto ParseArea_error;
1444 * parse the maximum x value
1446 if(!ParseRealValue(ptr, &ptr,
1447 area_return ? &area_return->maximum_x : NULL))
1448 goto ParseArea_error;
1450 * parse the minimum y value
1452 if(!ParseRealValue(ptr, &ptr,
1453 area_return ? &area_return->minimum_y : NULL))
1454 goto ParseArea_error;
1456 * parse the maximum y value
1458 if(!ParseRealValue(ptr, &ptr,
1459 area_return ? &area_return->maximum_y : NULL))
1460 goto ParseArea_error;
1462 * parse out the area sequence end
1464 if(!ParseSeqEnd(ptr, &ptr))
1465 goto ParseArea_error;
1467 * update the return pointer
1469 if(ptr_return != (const char**)NULL)
1481 if(ptr_return != (const char**)NULL)
1482 *ptr_return = first_nonws_ptr;
1487 * ------------------------------------------------------------------------
1488 * Name: ParseUnsignedRange
1492 * Skips leading whitespace and parses out and returns a
1493 * PdmOidUnsignedRange.
1497 * True if the PdmOidUnsignedRange was successfully
1498 * parsed. ptr_return is updated to point to location where the
1501 * False if a PdmOidUnsignedRange was not found; ptr_return is
1502 * updated to point to the first non-whitespace char in value_string.
1506 ParseUnsignedRange(const char* value_string,
1507 const char** ptr_return,
1508 PdmOidUnsignedRange* range_return)
1510 const char* first_nonws_ptr;
1513 * skip leading whitespace
1515 first_nonws_ptr = value_string + SpanWhitespace(value_string);
1517 * parse out the range sequence start
1519 if(!ParseSeqStart(first_nonws_ptr, &ptr))
1520 goto ParseUnsignedRange_error;
1522 * parse the lower bound
1524 if(!ParseUnsignedValue(ptr, &ptr,
1525 range_return ? &range_return->lower_bound : NULL))
1526 goto ParseUnsignedRange_error;
1528 * parse the upper bound
1530 if(!ParseUnsignedValue(ptr, &ptr,
1531 range_return ? &range_return->upper_bound : NULL))
1532 goto ParseUnsignedRange_error;
1534 * parse out the range sequence end
1536 if(!ParseSeqEnd(ptr, &ptr))
1537 goto ParseUnsignedRange_error;
1539 * update the return pointer
1541 if(ptr_return != (const char**)NULL)
1549 ParseUnsignedRange_error:
1553 if(ptr_return != (const char**)NULL)
1554 *ptr_return = first_nonws_ptr;
1559 * ------------------------------------------------------------------------
1560 * Name: PdmOidNotifyParse
1569 PdmOidNotify PdmOidNotifyParse(const char* value_string)
1571 const char* ptr = value_string;
1573 if(value_string == (const char*)NULL)
1574 return PDMOID_NOTIFY_NONE;
1576 * look for an event handling profile sequence start
1578 if(!ParseSeqStart(value_string, &ptr))
1582 * empty value is valid
1584 return PDMOID_NOTIFY_NONE;
1586 return PDMOID_NOTIFY_UNSUPPORTED;
1589 * look for an event set sequence start
1591 if(!ParseSeqStart(ptr, &ptr))
1594 * check for an empty event handling profile
1596 if(ParseSeqEnd(ptr, &ptr))
1598 ptr += SpanWhitespace(ptr);
1601 * valid empty event handling profile sequence
1603 return PDMOID_NOTIFY_NONE;
1605 return PDMOID_NOTIFY_UNSUPPORTED;
1608 * the only event in the set should be report job completed
1610 if(pdmoid_val_event_report_job_completed != PdmOidParse(ptr, &ptr))
1611 return PDMOID_NOTIFY_UNSUPPORTED;
1613 * event set sequence end
1615 if(!ParseSeqEnd(ptr, &ptr))
1616 return PDMOID_NOTIFY_UNSUPPORTED;
1618 * delivery method of electronic mail
1620 if(pdmoid_val_delivery_method_electronic_mail != PdmOidParse(ptr, &ptr))
1621 return PDMOID_NOTIFY_UNSUPPORTED;
1623 * event handling profile sequence end
1625 if(!ParseSeqEnd(ptr, &ptr))
1626 return PDMOID_NOTIFY_UNSUPPORTED;
1630 ptr += SpanWhitespace(ptr);
1633 * valid supported notification profile
1635 return PDMOID_NOTIFY_EMAIL;
1637 return PDMOID_NOTIFY_UNSUPPORTED;
1641 * ------------------------------------------------------------------------
1642 * Name: PdmOidNotifyString
1651 const char* PdmOidNotifyString(PdmOidNotify notify)
1655 case PDMOID_NOTIFY_UNSUPPORTED:
1656 return (const char*)NULL;
1658 case PDMOID_NOTIFY_NONE:
1659 return NOTIFY_NONE_STR;
1661 case PDMOID_NOTIFY_EMAIL:
1662 return NOTIFY_EMAIL_STR;
1668 * ------------------------------------------------------------------------
1669 * Name: PdmOidDocumentFormatParse
1679 PdmOidDocumentFormatParse(const char* value_string)
1681 char* document_format;
1685 * get the document format from the value string
1688 PdmOidDocumentFormatNext(value_string, &ptr);
1689 if((char*)NULL != document_format)
1692 * verify that the document format is the only value specified
1694 ptr += SpanWhitespace(ptr);
1697 * valid document-format value
1699 return document_format;
1704 XtFree(document_format);
1710 * ------------------------------------------------------------------------
1711 * Name: PdmOidDocumentFormatDefault
1721 PdmOidDocumentFormatDefault(const char* value_string)
1724 * return the first document format from the value string
1726 return PdmOidDocumentFormatNext(value_string, (const char**)NULL);
1730 * ------------------------------------------------------------------------
1731 * Name: PdmOidDocumentFormatNext
1741 PdmOidDocumentFormatNext(const char* value_string,
1742 const char** ptr_return)
1745 const char* first_nonws_ptr;
1746 const char* document_format_start;
1747 char* document_format;
1748 int document_format_len;
1751 if((const char*)NULL == value_string)
1754 * skip leading whitespace
1756 ptr = value_string + SpanWhitespace(value_string);
1757 first_nonws_ptr = ptr;
1761 if(!ParseSeqStart(ptr, &ptr))
1762 goto PdmOidDocumentFormatNext_error;
1764 * skip whitepace to the start of the document format, and save the
1767 ptr += SpanWhitespace(ptr);
1768 document_format_start = ptr;
1772 if(0 == (token_len = SpanToken(ptr)))
1773 goto PdmOidDocumentFormatNext_error;
1778 ptr += SpanWhitespace(ptr);
1779 if(0 != (token_len = SpanToken(ptr)))
1785 ptr += SpanWhitespace(ptr);
1786 ptr += SpanToken(ptr);
1789 * determine the length of the document format, excluding the
1790 * sequence delimeters
1792 document_format_len = ptr - document_format_start;
1796 if(!ParseSeqEnd(ptr, &ptr))
1797 goto PdmOidDocumentFormatNext_error;
1799 * update return pointer
1801 if((const char**)NULL != ptr_return)
1804 * build the return document format string, and return it
1806 document_format = XtMalloc(document_format_len+1);
1807 strncpy(document_format, document_format_start, document_format_len);
1808 document_format[document_format_len] = '\0';
1809 return document_format;
1811 PdmOidDocumentFormatNext_error:
1812 fprintf(stderr, "%s\n", PDM_MSG_WARN_DOC_FMT);
1813 if((const char**)NULL != ptr_return)
1814 *ptr_return = first_nonws_ptr;
1819 * ------------------------------------------------------------------------
1820 * Name: ParseBooleanValue
1830 ParseBooleanValue(const char* value_string,
1831 const char** ptr_return,
1832 Boolean* boolean_return)
1838 * skip leading whitespace
1840 ptr = value_string + SpanWhitespace(value_string);
1842 * get the whitespace-delimited token length
1844 length = SpanToken(ptr);
1846 * determine if true or false or bad
1848 if(strncasecmp(ptr, "TRUE", length) == 0)
1850 if(boolean_return != (Boolean*)NULL)
1851 *boolean_return = True;
1854 else if(strncasecmp(ptr, "FALSE", length) == 0)
1856 if(boolean_return != (Boolean*)NULL)
1857 *boolean_return = False;
1868 * update the return pointer and return
1870 if(ptr_return != (const char**)NULL)
1871 *ptr_return = status ? ptr+length : ptr;
1876 * ------------------------------------------------------------------------
1877 * Name: ParseUnsignedValue
1881 * Skips leading whitespace and parses out and returns a unsigned number.
1885 * True if a unsigned number was successfully parsed. ptr_return is
1886 * updated to point to location where the unsigned number parsing
1889 * False if a unsigned number was not found; ptr_return is updated
1890 * to point to the first non-whitespace char in value_string.
1894 ParseUnsignedValue(const char* value_string,
1895 const char** ptr_return,
1896 unsigned long* unsigned_return)
1898 unsigned long unsigned_value;
1900 const char* first_nonws_ptr;
1903 * skip leading whitespace
1905 first_nonws_ptr = value_string + SpanWhitespace(value_string);
1906 unsigned_value = strtoul(first_nonws_ptr, (char**)(&ptr), 0);
1907 if(ptr == first_nonws_ptr)
1912 * update return parms
1914 if(ptr_return != (const char**)NULL)
1916 if(unsigned_return != (unsigned long*)NULL)
1917 *unsigned_return = unsigned_value;
1925 * ------------------------------------------------------------------------
1926 * Name: ParseRealValue
1930 * Skips leading whitespace and parses out and returns a real number.
1934 * xTrue if a real number was successfully parsed. ptr_return is
1935 * updated to point to location where the real number parsing
1938 * xFalse if a real number was not found; ptr_return is updated
1939 * to point to the first non-whitespace char in value_string.
1943 ParseRealValue(const char* value_string,
1944 const char** ptr_return,
1949 const char* first_nonws_ptr;
1952 * skip leading whitespace
1954 first_nonws_ptr = value_string + SpanWhitespace(value_string);
1955 real_value = (float)strtod(first_nonws_ptr, (char**)(&ptr));
1956 if(ptr == first_nonws_ptr)
1961 * update return parms
1963 if(ptr_return != (const char**)NULL)
1965 if(real_return != (float*)NULL)
1966 *real_return = real_value;
1974 * ------------------------------------------------------------------------
1981 * Skips leading whitespace and parses out the sequence end
1986 * True if the sequence end character was parsed; ptr_return is
1987 * updated to point to the first char following the sequence end
1990 * False if the sequence end character was not found; ptr_return is
1991 * updated to point to the first non-whitespace char in value_string.
1995 ParseSeqEnd(const char* value_string,
1996 const char** ptr_return)
2001 * skip leading whitespace
2003 ptr = value_string + SpanWhitespace(value_string);
2005 * parse out the sequence end character
2015 * update the return pointer
2017 if(ptr_return != (const char**)NULL)
2026 * ------------------------------------------------------------------------
2027 * Name: ParseSeqStart
2031 * Skips leading whitespace and parses out the sequence start
2036 * True if the sequence start character was parsed; ptr_return is
2037 * updated to point to the first char following the sequence start
2040 * False if the sequence start character was not found; ptr_return is
2041 * updated to point to the first non-whitespace char in value_string.
2045 ParseSeqStart(const char* value_string,
2046 const char** ptr_return)
2051 * skip leading whitespace
2053 ptr = value_string + SpanWhitespace(value_string);
2055 * parse out the sequence start character
2065 * update the return pointer
2067 if(ptr_return != (const char**)NULL)
2076 * ------------------------------------------------------------------------
2077 * Name: ParseUnspecifiedValue
2081 * Skips leading whitespace and parses out an unspecified optional
2082 * value (i.e. matching '' or "" - skips all data between the set of
2087 * True if an unspecified value was parsed; ptr_return is updated to
2088 * point to the first char following the trailing quote.
2090 * False if an unspecified value was not found; ptr_return is updated
2091 * to point to the first non-whitespace char in value_string.
2095 ParseUnspecifiedValue(const char* value_string,
2096 const char** ptr_return)
2101 * skip leading whitespace
2103 ptr = value_string + SpanWhitespace(value_string);
2105 * parse out an unspecified optional value ('' or "")
2107 if(*ptr == '\'' || *ptr == '"')
2111 if(ptr_return != (const char**)NULL)
2116 * skip over the matching delimiter
2119 ptr += strcspn(ptr, delim);
2128 * update the return pointer
2130 if(ptr_return != (const char**)NULL)
2139 * ------------------------------------------------------------------------
2144 * Returns the length of the initial segment of the passed string
2145 * that consists entirely of non-whitespace and non-sequence
2146 * delimiter characters.
2151 SpanToken(const char* string)
2155 *ptr != '\0' && !DtIsspace((char*)ptr) && *ptr != '{' && *ptr != '}';
2156 ptr = DtNextChar((char*)ptr));
2157 return ptr - string;
2161 * ------------------------------------------------------------------------
2162 * Name: SpanWhitespace
2166 * Returns the length of the initial segment of the passed string
2167 * that consists entirely of whitespace characters.
2172 SpanWhitespace(const char* string)
2176 *ptr != '\0' && DtIsspace((char*)ptr);
2177 ptr = DtNextChar((char*)ptr));
2178 return ptr - string;