2 (c) Copyright 1996 Hewlett-Packard Company
3 (c) Copyright 1996 International Business Machines Corp.
4 (c) Copyright 1996 Sun Microsystems, Inc.
5 (c) Copyright 1996 Novell, Inc.
6 (c) Copyright 1996 Digital Equipment Corp.
7 (c) Copyright 1996 Fujitsu Limited
8 (c) Copyright 1996 Hitachi, Ltd.
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 Except as contained in this notice, the names of the copyright holders shall
28 not be used in advertising or otherwise to promote the sale, use or other
29 dealings in this Software without prior written authorization from said
33 #ifdef HAVE_DIX_CONFIG_H
34 #include <dix-config.h>
37 #include "attributes.h"
40 * XpOidNotify value strings
42 #define NOTIFY_EMAIL_STR "{{event-report-job-completed} electronic-mail}"
43 #define NOTIFY_NONE_STR "{}"
45 #define SafeStrLen(s) ((s) ? strlen((s)) : 0)
48 * entry type for the object identifier string map
50 typedef struct _XpOidStringMapEntry
56 const char* default_message
;
58 } XpOidStringMapEntry
;
61 * include the auto-generated static XpOidStringMap
66 * XpOid static function declarations
68 static XpOid
XpOidParse(const char* value_string
,
69 const char** ptr_return
);
71 * XpOidList static function declarations
73 static XpOidList
* XpOidListParse(const char* value_string
,
74 const XpOidList
* valid_oids
,
75 const char** ptr_return
, int i
);
78 * XpOidList static function declarations
80 static XpOidCardList
* XpOidCardListParse(const char* value_string
,
81 const XpOidCardList
* valid_cards
,
82 const char** ptr_return
, int i
);
85 * XpOidMediumSourceSize static function declarations
87 static XpOidMediumSS
* MediumSSParse(const char* value_string
,
88 const XpOidList
* valid_trays
,
89 const XpOidList
* valid_medium_sizes
,
90 const char** ptr_return
, int i
);
91 static XpOidMediumContinuousSize
* MediumContinuousSizeParse(const char*,
93 static void MediumContinuousSizeDelete(XpOidMediumContinuousSize
* me
);
94 static XpOidMediumDiscreteSizeList
* MediumDiscreteSizeListParse(const char*,
98 static void MediumDiscreteSizeListDelete(XpOidMediumDiscreteSizeList
* list
);
100 static BOOL
ParseArea(const char* value_string
,
101 const char** ptr_return
,
102 XpOidArea
* area_return
);
103 static BOOL
ParseRealRange(const char* value_string
,
104 const char** ptr_return
,
105 XpOidRealRange
* range_return
);
108 * XpOidTrayMediumList static function declarations
110 static XpOidTrayMediumList
* TrayMediumListParse(const char* value_string
,
111 const XpOidList
* valid_trays
,
112 const char** ptr_return
,
114 static void TrayMediumListValidate(XpOidTrayMediumList
* me
,
115 const XpOidMediumSS
* msss
);
120 static BOOL
XpOidDocFmtNext(XpOidDocFmt
* doc_fmt
,
121 const char* value_string
,
122 const char** ptr_return
);
125 * XpOidDocFmtListParse
127 static XpOidDocFmtList
* XpOidDocFmtListParse(const char* value_string
,
128 const XpOidDocFmtList
* valid_fmts
,
129 const char** ptr_return
, int i
);
132 * misc. parsing static function declarations
134 static BOOL
ParseBoolValue(const char* value_string
,
135 const char** ptr_return
,
137 static BOOL
ParseRealValue(const char* value_string
,
138 const char** ptr_return
,
140 static BOOL
ParseSeqEnd(
141 const char* value_string
,
142 const char** ptr_return
);
143 static BOOL
ParseSeqStart(
144 const char* value_string
,
145 const char** ptr_return
);
146 static BOOL
ParseUnspecifiedValue(
147 const char* value_string
,
148 const char** ptr_return
);
149 static int SpanToken(
151 static int SpanWhitespace(
155 * String comparison function.
157 #ifdef HAVE_STRCASECMP
158 # define StrnCaseCmp(s1, s2, len) strncasecmp(s1, s2, len)
160 static int StrnCaseCmp(const char *s1
, const char *s2
, size_t len
);
164 * ------------------------------------------------------------------------
169 * Obtain the string representation of an XpOid.
171 * Example: XpOidString(xpoid_copy_count) returns "copy-count".
175 * A const pointer to the string.
178 XpOidString(XpOid xp_oid
)
181 * XpOid enum values are index values into the string map
183 return XpOidStringMap
[xp_oid
].string
;
187 * ------------------------------------------------------------------------
188 * Name: XpOidStringLength
192 * Obtain the length of the string representation for a given
197 * The string length in bytes.
201 XpOidStringLength(XpOid xp_oid
)
204 * XpOid enum values are index values into the string map
206 return XpOidStringMap
[xp_oid
].length
;
210 * ------------------------------------------------------------------------
211 * Name: XpOidFromString
215 * Obtains the XpOid given a string representation of an XpOid.
217 * Example: XpOidFromString("copy-count") returns 'xpoid_copy_count'.
221 * The XpOid if successful. 'xpoid_none' if the string pointed to by
222 * 'value is not recognized or if 'value' is NULL.
225 XpOidFromString(const char* value
)
227 if(value
== (const char*)NULL
)
230 return XpOidParse(value
, (const char**)NULL
);
234 * ------------------------------------------------------------------------
239 * Parse the next whitespace-delimited string from 'value_string'
240 * updating 'ptr_return' to point to the next unparsed location in
241 * 'value_string'. 'ptr_return' can be NULL.
245 * The corresponding XpOid for the parsed name string.
246 * A return value of xpoid_none is returned if the parsed name
247 * was not a valid oid or if no name was found.
251 XpOidParse(const char* value_string
,
252 const char** ptr_return
)
258 * skip leading whitespace
260 ptr
= value_string
+ SpanWhitespace(value_string
);
262 * get the whitespace-delimited token length
264 length
= SpanToken(ptr
);
266 * match the oid string in the map
268 for(i
= 0; i
< XpOidStringMapCount
; i
++)
269 if(length
== XpOidStringMap
[i
].length
)
270 if(strncmp(ptr
, XpOidStringMap
[i
].string
, length
) == 0)
272 if(i
== XpOidStringMapCount
)
275 * update the return pointer and return
277 if(ptr_return
!= (const char**)NULL
)
278 *ptr_return
= ptr
+length
;
283 * ------------------------------------------------------------------------
288 * Creates a new XpOidList initialized from a whitespace-delimited
289 * list of recognized string representations of oids. The returned
290 * list will contain only oids found within the passed 'valid_oids'
293 * Note: One may notice that in order to create an XpOidList with
294 * this function, an XpOidList is needed; the 'valid_oids' list
295 * is often an statically initialized structure. XpOidListInit
300 * NULL if the passed 'value_string' is NULL.
302 * If the list indicated by 'value_string' is empty or contains only
303 * unrecognized oid string representations, a new XpOidList
304 * containing zero elements is returned.
306 * If 'valid_oids' is NULL all oids are considered valid.
310 XpOidListNew(const char* value_string
,
311 const XpOidList
* valid_oids
)
313 if(value_string
== (const char*)NULL
)
314 return (XpOidList
*)NULL
;
318 return XpOidListParse(value_string
, valid_oids
, &ptr
, 0);
323 * ------------------------------------------------------------------------
324 * Name: XpOidListDelete
328 * Frees the memory allocated for 'list'.
336 XpOidListDelete(XpOidList
* list
)
338 if(list
!= (XpOidList
*)NULL
)
340 XpOidFree((char*)list
->list
);
341 XpOidFree((char*)list
);
346 * ------------------------------------------------------------------------
347 * Name: XpOidListParse
351 * This function recursively parses the whitespace-delimited list of
352 * oid string representations passed via 'value_string'. Oids are
353 * only added to the resulting list if they are found within the
354 * passed 'valid_oids' XpOidList.
356 * 'ptr_return' points to a char* variable allocated by the
357 * caller, and is really only of use during recursion (upon return to
358 * the original caller, it will point to the end of value_string).
360 * 'value_string' and 'ptr_return' *cannot* be NULL.
364 * A newly allocated and initialized XpOidList.
366 * If the list indicated by 'value_string' is empty or contains only
367 * unrecognized oid string representations, a new XpOidList
368 * containing zero elements is returned.
370 * If 'valid_oids' is NULL all oids are considered valid.
374 XpOidListParse(const char* value_string
,
375 const XpOidList
* valid_oids
,
376 const char** ptr_return
,
382 * parse the next valid oid out of the value string
384 ptr_return
= &value_string
;
387 if(**ptr_return
== '\0')
390 * end of value string; stop parsing
396 * parse the next oid from the value
398 oid
= XpOidParse(*ptr_return
, ptr_return
);
399 if(xpoid_none
== oid
)
402 * unrecognized oid; keep parsing
406 if((const XpOidList
*)NULL
== valid_oids
408 XpOidListHasOid(valid_oids
, oid
))
411 * valid oid found; stop parsing
417 if(oid
== xpoid_none
)
420 * end of value string; allocate the list structure
422 list
= (XpOidList
*)XpOidCalloc(1, sizeof(XpOidList
));
424 list
->list
= (XpOid
*)XpOidCalloc(i
, sizeof(XpOid
));
431 list
= XpOidListParse(*ptr_return
, valid_oids
, ptr_return
, i
+1);
433 * set the oid in the list
444 * ------------------------------------------------------------------------
445 * Name: XpOidListHasOid
449 * Determines if 'oid' is an element of 'list'.
453 * xTrue if the oid is found in the list.
455 * xFalse if the oid is not in the list, or if 'list' is NULL.
459 XpOidListHasOid(const XpOidList
* list
, XpOid oid
)
462 if(list
!= (XpOidList
*)NULL
)
463 for(i
= 0; i
< list
->count
; i
++)
464 if(list
->list
[i
] == oid
)
470 * ------------------------------------------------------------------------
471 * Name: XpOidListGetIndex
475 * Returns the array index of 'oid' in 'list'
479 * The index of 'oid' in list.
481 * -1 if the oid is not in the list, or if 'list' is NULL.
485 XpOidListGetIndex(const XpOidList
* list
, XpOid oid
)
488 if(list
!= (XpOidList
*)NULL
)
489 for(i
= 0; i
< list
->count
; i
++)
490 if(list
->list
[i
] == oid
)
496 * ------------------------------------------------------------------------
497 * Name: XpOidListString
501 * Creates a string representation of an XpOidList structure.
509 XpOidListString(const XpOidList
* me
)
516 * allocate enough memory for the oid string representations,
517 * including intervening whitespace
519 for(i
= 0, length
= 0; i
< XpOidListCount(me
); i
++)
520 length
+= XpOidStringLength(XpOidListGetOid(me
, i
)) + 1;
521 str
= XpOidMalloc(length
+1);
525 for(i
= 0, ptr
= str
; i
< XpOidListCount(me
); i
++)
526 #if defined(sun) && !defined(SVR4)
528 sprintf(ptr
, "%s ", XpOidString(XpOidListGetOid(me
, i
)));
532 ptr
+= sprintf(ptr
, "%s ", XpOidString(XpOidListGetOid(me
, i
)));
535 * chop trailing whitespace or terminate empty string
545 * ------------------------------------------------------------------------
546 * Name: XpOidLinkedListNew
550 * Creates a new instance of an empty XpOidLinkedList.
554 * The new XpOidLinkedList.
560 return (XpOidLinkedList
*)XpOidCalloc(1, sizeof(XpOidLinkedList
));
564 * ------------------------------------------------------------------------
565 * Name: XpOidLinkedListDelete
569 * Frees the memory allocated for a XpOidLinkedList.
577 XpOidLinkedListDelete(XpOidLinkedList
* me
)
579 if(me
!= (XpOidLinkedList
*)NULL
)
583 me
->current
= me
->head
;
584 me
->head
= me
->current
->next
;
585 XpOidFree((char*)me
->current
);
587 XpOidFree((char*)me
);
592 * ------------------------------------------------------------------------
593 * Name: XpOidLinkedListGetOid
597 * Retrieves the oid at position 'i' (zero-based) in the
598 * XpOidLinkedList 'me'.
602 * The oid at position 'i'.
604 * xpoid_none if the oid was not found, or the list is empty (or if
605 * the list contains xpoid_none at position 'i').
608 XpOidLinkedListGetOid(XpOidLinkedList
* me
, int i
)
610 if(me
== (XpOidLinkedList
*)NULL
|| i
< 0 || i
>= me
->count
)
616 me
->current
= me
->head
;
617 while(i
--) me
->current
= me
->current
->next
;
618 return me
->current
->oid
;
623 * ------------------------------------------------------------------------
624 * Name: XpOidLinkedListAddOid
628 * Adds an oid to the end of an XpOidLinkedList.
636 XpOidLinkedListAddOid(XpOidLinkedList
* me
, XpOid oid
)
638 me
->current
= (XpOidNode
)XpOidCalloc(1, sizeof(struct XpOidNodeStruct
));
639 me
->current
->oid
= oid
;
643 me
->tail
->next
= me
->current
;
644 me
->tail
= me
->current
;
647 me
->head
= me
->tail
= me
->current
;
651 * ------------------------------------------------------------------------
652 * Name: XpOidLinkedListGetIndex
656 * Returns the position of an oid in a XpOidLinkedList.
660 * The zero-based position of 'oid' in the list.
662 * -1 if the oid is not in the list, or if 'me' is NULL.
666 XpOidLinkedListGetIndex(XpOidLinkedList
* me
, XpOid oid
)
668 if((XpOidLinkedList
*)NULL
!= me
)
671 me
->current
= me
->head
;
673 if(me
->current
->oid
== oid
)
680 me
->current
= me
->current
->next
;
687 * ------------------------------------------------------------------------
688 * Name: XpOidLinkedListHasOid
692 * Determines if an oid is an element of a XpOidLinkedList.
696 * xTrue if the oid is found in the list.
698 * xFalse if the oid is not in the list, or if 'me' is NULL.
701 XpOidLinkedListHasOid(XpOidLinkedList
* me
,
704 if((XpOidLinkedList
*)NULL
!= me
)
706 me
->current
= me
->head
;
708 if(me
->current
->oid
== oid
)
711 me
->current
= me
->current
->next
;
717 * ------------------------------------------------------------------------
718 * Name: XpOidLinkedListFirstOid
722 * Positions the XpOidLinkedList 'current' pointer to the first entry
727 * The first oid in the list, or xpoid_none if the list NULL or
731 XpOidLinkedListFirstOid(XpOidLinkedList
* me
)
733 if((XpOidLinkedList
*)NULL
!= me
&& (me
->current
= me
->head
))
734 return me
->current
->oid
;
740 * ------------------------------------------------------------------------
741 * Name: XpOidLinkedListNextOid
745 * Positions the XpOidLinkedList 'current' pointer to the next entry
750 * The next oid, or xpoid_none if the end of the list has been
754 XpOidLinkedListNextOid(XpOidLinkedList
* me
)
756 if(me
->current
? (me
->current
= me
->current
->next
) : xFalse
)
757 return me
->current
->oid
;
763 * ------------------------------------------------------------------------
764 * Name: XpOidMediumSSNew
768 * Creates a new XpOidMediumSS initialized from a string value
769 * specified using the medium-source-sizes syntax. See
770 * MediumSSParse() below for parsing details.
774 * NULL if the passed 'value_string' is NULL, or if a syntax error is
775 * encountered while parsing the medium-source-sizes value.
779 XpOidMediumSSNew(const char* value_string
,
780 const XpOidList
* valid_trays
,
781 const XpOidList
* valid_medium_sizes
)
783 if(value_string
== (const char*)NULL
)
784 return (XpOidMediumSS
*)NULL
;
787 const char* ptr
= value_string
+ SpanWhitespace(value_string
);
789 return (XpOidMediumSS
*)NULL
;
791 return MediumSSParse(ptr
, valid_trays
, valid_medium_sizes
,
797 * ------------------------------------------------------------------------
798 * Name: MediumSSParse
802 * 'ptr_return' *cannot* be NULL.
810 static XpOidMediumSS
*
811 MediumSSParse(const char* value_string
,
812 const XpOidList
* valid_trays
,
813 const XpOidList
* valid_medium_sizes
,
814 const char** ptr_return
,
817 XpOidMediumSS
* medium_ss
;
818 XpOidMediumSourceSize mss
;
820 * check for the start of a new MediumSourceSize sequence
822 if(ParseSeqStart(value_string
, ptr_return
))
825 * check for an unspecified tray value
827 if(ParseUnspecifiedValue(*ptr_return
, ptr_return
))
828 mss
.input_tray
= xpoid_unspecified
;
831 const char* tray_str
;
832 *ptr_return
+= SpanWhitespace(*ptr_return
);
833 tray_str
= *ptr_return
;
835 * parse out the input tray
837 mss
.input_tray
= XpOidParse(*ptr_return
, ptr_return
);
838 if((const XpOidList
*)NULL
!= valid_trays
840 !XpOidListHasOid(valid_trays
, mss
.input_tray
)
842 mss
.input_tray
= xpoid_none
;
843 if(xpoid_none
== mss
.input_tray
)
845 char* invalid_tray_str
;
846 int len
= *ptr_return
- tray_str
;
849 invalid_tray_str
= XpOidMalloc(len
+1);
850 strncpy(invalid_tray_str
, tray_str
, len
);
851 invalid_tray_str
[len
] = '\0';
852 ErrorF("%s\nInvalid tray (%s) found. Will attempt to continue parsing.\n",
853 XPMSG_WARN_MSS
, invalid_tray_str
);
854 XpOidFree(invalid_tray_str
);
859 * attempt to parse a Continuous MediumSize sequence
861 mss
.ms
.continuous_size
=
862 MediumContinuousSizeParse(*ptr_return
, ptr_return
);
863 if(mss
.ms
.continuous_size
!= (XpOidMediumContinuousSize
*)NULL
)
865 mss
.mstag
= XpOidMediumSS_CONTINUOUS
;
870 * not continuous, try Discrete MediumSize
873 MediumDiscreteSizeListParse(*ptr_return
, valid_medium_sizes
,
875 if(mss
.ms
.discrete
== (XpOidMediumDiscreteSizeList
*)NULL
)
877 const char* tray_str
;
879 * syntax error (MediumDiscreteSizeListParse reports error)
881 switch(mss
.input_tray
)
884 tray_str
= "an invalid";
886 case xpoid_unspecified
:
887 tray_str
= "default (tray specifier omitted)";
890 tray_str
= XpOidString(mss
.input_tray
);
893 ErrorF("%s\nError occurred while parsing medium sizes for %s tray.\n",
894 XPMSG_WARN_MSS
, tray_str
);
897 mss
.mstag
= XpOidMediumSS_DISCRETE
;
900 * parse out the MediumSourceSize sequence end
902 if(!ParseSeqEnd(*ptr_return
, ptr_return
))
907 ErrorF("%s\nSequence End expected. Unparsed data: %s\n",
908 XPMSG_WARN_MSS
, *ptr_return
);
912 * recurse to parse the next MediumSourceSize sequence
914 medium_ss
= MediumSSParse(*ptr_return
,
915 valid_trays
, valid_medium_sizes
,
917 xpoid_none
== mss
.input_tray
? i
: i
+1);
918 if(medium_ss
== (XpOidMediumSS
*)NULL
920 xpoid_none
== mss
.input_tray
)
923 * syntax error or invalid tray - clean up
927 case XpOidMediumSS_CONTINUOUS
:
928 MediumContinuousSizeDelete(mss
.ms
.continuous_size
);
930 case XpOidMediumSS_DISCRETE
:
931 MediumDiscreteSizeListDelete(mss
.ms
.discrete
);
934 if(medium_ss
== (XpOidMediumSS
*)NULL
)
936 * syntax error - return
940 if(xpoid_none
!= mss
.input_tray
)
943 * copy the current MediumSourceSize into the array
945 memmove((medium_ss
->mss
)+i
, &mss
, sizeof(XpOidMediumSourceSize
));
951 * MediumSourceSize sequence start not found
953 if(**ptr_return
== '\0')
957 ErrorF("%s\nNo valid trays found.\n", XPMSG_WARN_MSS
);
961 * end of value string; allocate the MediumSS structure
963 medium_ss
= (XpOidMediumSS
*)XpOidCalloc(1, sizeof(XpOidMediumSS
));
964 medium_ss
->count
= i
;
965 medium_ss
->mss
= (XpOidMediumSourceSize
*)
966 XpOidCalloc(i
, sizeof(XpOidMediumSourceSize
));
973 ErrorF("%s\nSequence Start expected.\nunparsed data: %s\n",
974 XPMSG_WARN_MSS
, *ptr_return
);
982 * ------------------------------------------------------------------------
983 * Name: XpOidMediumSSDelete
995 XpOidMediumSSDelete(XpOidMediumSS
* me
)
997 if(me
!= (XpOidMediumSS
*)NULL
)
1000 for(i
= 0; i
< me
->count
; i
++)
1002 switch((me
->mss
)[i
].mstag
)
1004 case XpOidMediumSS_CONTINUOUS
:
1005 MediumContinuousSizeDelete((me
->mss
)[i
].ms
.continuous_size
);
1007 case XpOidMediumSS_DISCRETE
:
1008 MediumDiscreteSizeListDelete((me
->mss
)[i
].ms
.discrete
);
1012 XpOidFree((char*)me
);
1017 * ------------------------------------------------------------------------
1018 * Name: XpOidMediumSSHasSize
1030 XpOidMediumSSHasSize(XpOidMediumSS
* me
, XpOid page_size
)
1033 XpOidMediumDiscreteSizeList
* ds_list
;
1035 if(me
!= (XpOidMediumSS
*)NULL
&& page_size
!= xpoid_none
)
1036 for(i_mss
= 0; i_mss
< me
->count
; i_mss
++)
1038 switch((me
->mss
)[i_mss
].mstag
)
1040 case XpOidMediumSS_DISCRETE
:
1041 ds_list
= (me
->mss
)[i_mss
].ms
.discrete
;
1042 for(i_ds
= 0; i_ds
< ds_list
->count
; i_ds
++)
1043 if(page_size
== (ds_list
->list
)[i_ds
].page_size
)
1047 case XpOidMediumSS_CONTINUOUS
:
1061 * ------------------------------------------------------------------------
1062 * Name: XpOidMediumSSString
1066 * Creates a string representation of an XpOidMediumSS structure.
1073 char* XpOidMediumSSString(const XpOidMediumSS
* me
)
1076 int valid_size_count
;
1080 XpOidMediumDiscreteSize
* ds
;
1083 * determine the size of the string representation
1085 for(itray
= 0, length
= 0; itray
< XpOidMediumSSCount(me
); itray
++)
1087 if(xpoid_none
== me
->mss
[itray
].input_tray
1089 XpOidMediumSS_CONTINUOUS
== me
->mss
[itray
].mstag
)
1092 * skip invalid tray or unsupported continuous size spec
1096 for(isize
= 0, valid_size_count
= 0;
1097 isize
< me
->mss
[itray
].ms
.discrete
->count
;
1100 ds
= me
->mss
[itray
].ms
.discrete
->list
+isize
;
1101 if(ds
->page_size
== xpoid_none
)
1104 length
+= XpOidStringLength(ds
->page_size
);
1105 length
+= ds
->long_edge_feeds
? 4 : 5; /* "True" or "False" */
1106 #if defined(sun) && !defined(SVR4)
1107 sprintf(buf
, "{%.4f %.4f %.4f %.4f}",
1108 ds
->assured_reproduction_area
.minimum_x
,
1109 ds
->assured_reproduction_area
.maximum_x
,
1110 ds
->assured_reproduction_area
.minimum_y
,
1111 ds
->assured_reproduction_area
.maximum_y
);
1112 length
+= strlen(buf
);
1114 length
+= sprintf(buf
, "{%.4f %.4f %.4f %.4f}",
1115 ds
->assured_reproduction_area
.minimum_x
,
1116 ds
->assured_reproduction_area
.maximum_x
,
1117 ds
->assured_reproduction_area
.minimum_y
,
1118 ds
->assured_reproduction_area
.maximum_y
);
1120 length
+= 5; /* "{<size> <feed> <area>} " */
1122 if(valid_size_count
== 0)
1125 * no valid sizes, skip
1129 if(xpoid_unspecified
== me
->mss
[itray
].input_tray
)
1130 length
+= 2; /* "''" */
1132 length
+= XpOidStringLength(me
->mss
[itray
].input_tray
);
1133 length
+= 4; /* "{<tray> <sizes>} " */
1138 str
= XpOidMalloc(length
+1);
1142 for(itray
= 0, ptr
= str
; itray
< XpOidMediumSSCount(me
); itray
++)
1144 if(xpoid_none
== me
->mss
[itray
].input_tray
1146 XpOidMediumSS_CONTINUOUS
== me
->mss
[itray
].mstag
)
1149 * skip invalid tray or unsupported continuous size spec
1154 * check to ensure all of the specified sizes are valid
1156 for(isize
= 0, valid_size_count
= 0;
1157 isize
< me
->mss
[itray
].ms
.discrete
->count
;
1160 ds
= me
->mss
[itray
].ms
.discrete
->list
+isize
;
1161 if(ds
->page_size
!= xpoid_none
)
1164 if(valid_size_count
== 0)
1167 * no valid sizes, skip
1172 if(xpoid_unspecified
== me
->mss
[itray
].input_tray
)
1174 #if defined(sun) && !defined(SVR4)
1175 sprintf(ptr
, "{'' ");
1178 ptr
+= sprintf(ptr
, "{'' ");
1183 #if defined(sun) && !defined(SVR4)
1184 sprintf(ptr
, "{%s ", XpOidString(me
->mss
[itray
].input_tray
));
1187 ptr
+= sprintf(ptr
, "{%s ",
1188 XpOidString(me
->mss
[itray
].input_tray
));
1191 for(isize
= 0; isize
< me
->mss
[itray
].ms
.discrete
->count
; isize
++)
1193 ds
= me
->mss
[itray
].ms
.discrete
->list
+isize
;
1194 if(ds
->page_size
!= xpoid_none
)
1195 #if defined(sun) && !defined(SVR4)
1197 sprintf(ptr
, "{%s %s {%.4f %.4f %.4f %.4f}} ",
1198 XpOidString(ds
->page_size
),
1199 ds
->long_edge_feeds
? "True" : "False",
1200 ds
->assured_reproduction_area
.minimum_x
,
1201 ds
->assured_reproduction_area
.maximum_x
,
1202 ds
->assured_reproduction_area
.minimum_y
,
1203 ds
->assured_reproduction_area
.maximum_y
);
1207 ptr
+= sprintf(ptr
, "{%s %s {%.4f %.4f %.4f %.4f}} ",
1208 XpOidString(ds
->page_size
),
1209 ds
->long_edge_feeds
? "True" : "False",
1210 ds
->assured_reproduction_area
.minimum_x
,
1211 ds
->assured_reproduction_area
.maximum_x
,
1212 ds
->assured_reproduction_area
.minimum_y
,
1213 ds
->assured_reproduction_area
.maximum_y
);
1216 #if defined(sun) && !defined(SVR4)
1220 ptr
+= sprintf(ptr
, "} ");
1224 * chop trailing whitespace or terminate empty string
1234 * ------------------------------------------------------------------------
1235 * Name: MediumContinuousSizeParse
1239 * 'ptr_return' *cannot* be NULL.
1247 static XpOidMediumContinuousSize
*
1248 MediumContinuousSizeParse(const char* value_string
,
1249 const char** ptr_return
)
1251 const char* first_nonws_ptr
;
1252 XpOidMediumContinuousSize
* mcs
= NULL
;
1254 * skip leading whitespace
1256 first_nonws_ptr
= value_string
+ SpanWhitespace(value_string
);
1258 * parse out the MediumSize sequence start char
1260 if(!ParseSeqStart(first_nonws_ptr
, ptr_return
))
1261 goto MediumContinuousSizeParse_error
;
1263 * peek ahead to see if it looks like we actually have a continuous
1264 * size spec (looking for the sequence start char on the 1st range spec)
1266 if(!ParseSeqStart(*ptr_return
, (const char**)NULL
))
1267 goto MediumContinuousSizeParse_error
;
1269 * Ok, let's go for it
1271 mcs
= (XpOidMediumContinuousSize
*)
1272 XpOidCalloc(1, sizeof(XpOidMediumContinuousSize
));
1274 * "range across the feed direction"
1276 if(!ParseRealRange(*ptr_return
, ptr_return
, &mcs
->range_across_feed
))
1277 goto MediumContinuousSizeParse_error
;
1279 * "increment across the feed direction" (optional, default 0)
1281 if(!ParseUnspecifiedValue(*ptr_return
, ptr_return
))
1282 if(!ParseRealValue(*ptr_return
, ptr_return
,
1283 &mcs
->increment_across_feed
))
1284 goto MediumContinuousSizeParse_error
;
1286 * "range in the feed direction"
1288 if(!ParseRealRange(*ptr_return
, ptr_return
, &mcs
->range_in_feed
))
1289 goto MediumContinuousSizeParse_error
;
1291 * "increment in the feed direction" (optional, default 0)
1293 if(!ParseUnspecifiedValue(*ptr_return
, ptr_return
))
1294 if(!ParseRealValue(*ptr_return
, ptr_return
,
1295 &mcs
->increment_in_feed
))
1296 goto MediumContinuousSizeParse_error
;
1298 * "long edge feeds" flag (default TRUE)
1300 if(ParseUnspecifiedValue(*ptr_return
, ptr_return
))
1301 mcs
->long_edge_feeds
= xTrue
;
1303 if(!ParseBoolValue(*ptr_return
, ptr_return
, &mcs
->long_edge_feeds
))
1304 goto MediumContinuousSizeParse_error
;
1306 * "generic assured reproduction area"
1308 if(!ParseArea(*ptr_return
, ptr_return
, &mcs
->assured_reproduction_area
))
1309 goto MediumContinuousSizeParse_error
;
1311 * parse out the MediumSize sequence end character
1313 if(!ParseSeqEnd(*ptr_return
, ptr_return
))
1314 goto MediumContinuousSizeParse_error
;
1321 MediumContinuousSizeParse_error
:
1323 * syntax error - don't log since this function may be called
1326 *ptr_return
= first_nonws_ptr
;
1327 XpOidFree((char*)mcs
);
1332 * ------------------------------------------------------------------------
1333 * Name: MediumContinuousSizeDelete
1337 * 'ptr_return' *cannot* be NULL.
1346 MediumContinuousSizeDelete(XpOidMediumContinuousSize
* me
)
1348 XpOidFree((char*)me
);
1352 * ------------------------------------------------------------------------
1353 * Name: MediumDiscreteSizeListParse
1357 * 'ptr_return' *cannot* be NULL.
1364 static XpOidMediumDiscreteSizeList
*
1365 MediumDiscreteSizeListParse(const char* value_string
,
1366 const XpOidList
* valid_medium_sizes
,
1367 const char** ptr_return
,
1370 XpOidMediumDiscreteSizeList
* list
;
1371 XpOidMediumDiscreteSize mds
;
1373 * check for the start of a new MediumSize sequence
1375 if(ParseSeqStart(value_string
, ptr_return
))
1380 mds
.page_size
= XpOidParse(*ptr_return
, ptr_return
);
1381 if((const XpOidList
*)NULL
!= valid_medium_sizes
1383 !XpOidListHasOid(valid_medium_sizes
, mds
.page_size
)
1385 mds
.page_size
= xpoid_none
;
1387 * "long edge feeds" flag (default TRUE)
1389 if(ParseUnspecifiedValue(*ptr_return
, ptr_return
))
1390 mds
.long_edge_feeds
= xTrue
;
1392 if(!ParseBoolValue(*ptr_return
, ptr_return
,
1393 &mds
.long_edge_feeds
))
1398 ErrorF("%s\nBoolean expected.\nunparsed data: %s\n",
1399 XPMSG_WARN_MSS
, *ptr_return
);
1400 return (XpOidMediumDiscreteSizeList
*)NULL
;
1403 * "assured reproduction area"
1405 if(!ParseArea(*ptr_return
, ptr_return
,
1406 &mds
.assured_reproduction_area
))
1411 ErrorF("%s\nArea specification error.\nunparsed data: %s\n",
1412 XPMSG_WARN_MSS
, *ptr_return
);
1413 return (XpOidMediumDiscreteSizeList
*)NULL
;
1416 * parse out the MediumSize sequence end character
1418 if(!ParseSeqEnd(*ptr_return
, ptr_return
))
1420 ErrorF("%s\nSequence End expected. Unparsed data: %s\n",
1421 XPMSG_WARN_MSS
, *ptr_return
);
1422 return (XpOidMediumDiscreteSizeList
*)NULL
;
1425 * recurse to parse the next Discrete MediumSize sequence
1427 if(mds
.page_size
== xpoid_none
)
1429 list
= MediumDiscreteSizeListParse(*ptr_return
, valid_medium_sizes
,
1434 list
= MediumDiscreteSizeListParse(*ptr_return
, valid_medium_sizes
,
1436 if(list
!= (XpOidMediumDiscreteSizeList
*)NULL
)
1439 * copy the current discrete MediumSize into the list
1441 memmove((list
->list
)+i
, &mds
, sizeof(XpOidMediumDiscreteSize
));
1448 * MediumSize sequence start not found; end of the discrete sizes
1453 ErrorF("%s\nNo valid medium sizes found for tray.\n",
1455 return (XpOidMediumDiscreteSizeList
*)NULL
;
1457 list
= (XpOidMediumDiscreteSizeList
*)
1458 XpOidCalloc(1, sizeof(XpOidMediumDiscreteSizeList
));
1460 list
->list
= (XpOidMediumDiscreteSize
*)
1461 XpOidCalloc(i
, sizeof(XpOidMediumDiscreteSize
));
1467 * ------------------------------------------------------------------------
1468 * Name: MediumDiscreteSizeListDelete
1480 MediumDiscreteSizeListDelete(XpOidMediumDiscreteSizeList
* list
)
1482 if(list
!= (XpOidMediumDiscreteSizeList
*)NULL
)
1484 XpOidFree((char*)list
->list
);
1485 XpOidFree((char*)list
);
1490 * ------------------------------------------------------------------------
1491 * Name: XpOidTrayMediumListNew
1495 * Only need the valid trays; validation requires bumping up against
1496 * msss using TrayMediumListValidate; this needs valid trays
1497 * because of unspecified trays ion msss, but
1498 * TrayMediumListValidate will take care of invalid sizes...
1505 XpOidTrayMediumList
*
1506 XpOidTrayMediumListNew(const char* value_string
,
1507 const XpOidList
* valid_trays
,
1508 const XpOidMediumSS
* msss
)
1510 if(value_string
== (const char*)NULL
)
1511 return (XpOidTrayMediumList
*)NULL
;
1515 XpOidTrayMediumList
* me
;
1516 me
= TrayMediumListParse(value_string
, valid_trays
, &ptr
, 0);
1517 if((XpOidTrayMediumList
*)NULL
!= me
)
1518 TrayMediumListValidate(me
, msss
);
1524 * ------------------------------------------------------------------------
1525 * Name: XpOidTrayMediumListDelete
1537 XpOidTrayMediumListDelete(XpOidTrayMediumList
* list
)
1539 if(list
!= (XpOidTrayMediumList
*)NULL
)
1541 XpOidFree((char*)list
->list
);
1542 XpOidFree((char*)list
);
1547 * ------------------------------------------------------------------------
1548 * Name: TrayMediumListParse
1552 * 'ptr_return' *cannot* be NULL.
1559 static XpOidTrayMediumList
*
1560 TrayMediumListParse(const char* value_string
,
1561 const XpOidList
* valid_trays
,
1562 const char** ptr_return
, int i
)
1565 XpOidTrayMediumList
* list
;
1567 * check for the start of a new InputTrayMedium sequence
1569 if(ParseSeqStart(value_string
, ptr_return
))
1574 tm
.input_tray
= XpOidParse(*ptr_return
, ptr_return
);
1575 if((XpOidList
*)NULL
!= valid_trays
1577 !XpOidListHasOid(valid_trays
, tm
.input_tray
)
1579 tm
.input_tray
= xpoid_none
;
1583 tm
.medium
= XpOidParse(*ptr_return
, ptr_return
);
1585 * parse out the InputTrayMedium sequence end character
1587 if(!ParseSeqEnd(*ptr_return
, ptr_return
))
1589 ErrorF("%s\n", XPMSG_WARN_ITM
);
1593 * recurse to parse the next InputTrayMedium sequence
1595 list
= TrayMediumListParse(*ptr_return
, valid_trays
, ptr_return
, i
+1);
1596 if(list
!= (XpOidTrayMediumList
*)NULL
)
1599 * copy the current InputTrayMedium into the list
1601 memmove((list
->list
)+i
, &tm
, sizeof(XpOidTrayMedium
));
1607 * InputTrayMedium sequence start not found
1609 if(**ptr_return
== '\0')
1614 list
= (XpOidTrayMediumList
*)
1615 XpOidCalloc(1, sizeof(XpOidTrayMediumList
));
1617 list
->list
= (XpOidTrayMedium
*)
1618 XpOidCalloc(i
, sizeof(XpOidTrayMedium
));
1625 ErrorF("%s\n", XPMSG_WARN_ITM
);
1636 * ------------------------------------------------------------------------
1637 * Name: TrayMediumListValidate
1641 * Validate the input-trays-medium list based on a passed
1642 * medium-source-sizes-supported structure. The validated
1643 * input-trays-medium list will have the same number of entries upon
1644 * return from this function. Invalid entries are indicated by
1645 * setting the tray specification to xpoid_none.
1653 TrayMediumListValidate(XpOidTrayMediumList
* me
,
1654 const XpOidMediumSS
* msss
)
1656 int i_mss
, i_ds
, i_itm
;
1657 XpOid current_tray
, current_medium
;
1658 XpOidMediumDiscreteSizeList
* unspecified_tray_ds
;
1659 XpOidMediumDiscreteSizeList
* tray_ds
;
1661 if(msss
== (XpOidMediumSS
*)NULL
1663 me
== (XpOidTrayMediumList
*)NULL
)
1668 * loop through the input trays medium list
1670 for(i_itm
= 0; i_itm
< XpOidTrayMediumListCount(me
); i_itm
++)
1672 current_tray
= XpOidTrayMediumListTray(me
, i_itm
);
1673 if(current_tray
== xpoid_none
)
1675 current_medium
= XpOidTrayMediumListMedium(me
, i_itm
);
1676 if(current_medium
== xpoid_none
)
1679 * no medium; invalidate this entry
1681 me
->list
[i_itm
].input_tray
= xpoid_none
;
1685 * loop through the MediumSourceSizes, looking for an appropriate
1686 * discrete sizes spec for the current tray
1688 unspecified_tray_ds
= (XpOidMediumDiscreteSizeList
*)NULL
;
1689 tray_ds
= (XpOidMediumDiscreteSizeList
*)NULL
;
1691 i_mss
< msss
->count
&&
1692 tray_ds
== (XpOidMediumDiscreteSizeList
*)NULL
;
1695 switch((msss
->mss
)[i_mss
].mstag
)
1697 case XpOidMediumSS_DISCRETE
:
1698 if((msss
->mss
)[i_mss
].input_tray
== current_tray
)
1699 tray_ds
= (msss
->mss
)[i_mss
].ms
.discrete
;
1700 else if((msss
->mss
)[i_mss
].input_tray
== xpoid_unspecified
)
1701 unspecified_tray_ds
= (msss
->mss
)[i_mss
].ms
.discrete
;
1704 case XpOidMediumSS_CONTINUOUS
:
1712 * if the tray was not matched, use the unspecified tray size
1715 if(tray_ds
== (XpOidMediumDiscreteSizeList
*)NULL
)
1717 if(unspecified_tray_ds
== (XpOidMediumDiscreteSizeList
*)NULL
)
1720 * not even an unspecified tray, invalidate this
1721 * input-trays-medium entry.
1723 me
->list
[i_itm
].input_tray
= xpoid_none
;
1727 tray_ds
= unspecified_tray_ds
;
1730 * loop through the discrete sizes list, looking for a size that
1731 * matches the medium for the current input tray
1733 for(i_ds
= 0; i_ds
< tray_ds
->count
; i_ds
++)
1736 * check to see if the current input tray's medium size
1737 * matches the current discrete size
1739 * Note: in the CDEnext SI, medium identifiers coincide with
1740 * medium-size identifiers. If the DP-Medium object is
1741 * ever implemented, this check would need to be
1742 * changed so that the input tray's medium size is
1743 * obtained from the indicated Medium object, and not
1744 * inferred from the medium identifier itself.
1746 if((tray_ds
->list
)[i_ds
].page_size
== current_medium
)
1749 * The current input tray's medium size matches the
1750 * current discrete medium size.
1755 if(i_ds
== tray_ds
->count
)
1758 * The current input tray's medium size was not found in the
1759 * discrete size list; mark the input tray medium entry
1762 me
->list
[i_itm
].input_tray
= xpoid_none
;
1769 * ------------------------------------------------------------------------
1770 * Name: XpOidTrayMediumListString
1774 * Creates a string representation of an XpOidTrayMediumList structure.
1781 char* XpOidTrayMediumListString(const XpOidTrayMediumList
* me
)
1789 * allocate enough memory for the string representation,
1790 * including intervening delimiters and whitespace
1792 for(i
= 0, length
= 0; i
< XpOidTrayMediumListCount(me
); i
++)
1794 tray
= XpOidTrayMediumListTray(me
, i
);
1795 if(xpoid_none
!= tray
)
1797 length
+= XpOidStringLength(tray
);
1798 length
+= XpOidStringLength(XpOidTrayMediumListMedium(me
, i
));
1802 str
= XpOidMalloc(length
+1);
1806 for(i
= 0, ptr
= str
; i
< XpOidTrayMediumListCount(me
); i
++)
1808 tray
= XpOidTrayMediumListTray(me
, i
);
1809 if(xpoid_none
!= tray
)
1811 #if defined(sun) && !defined(SVR4)
1812 sprintf(ptr
, "{%s %s} ",
1814 XpOidString(XpOidTrayMediumListMedium(me
, i
)));
1817 ptr
+= sprintf(ptr
, "{%s %s} ",
1819 XpOidString(XpOidTrayMediumListMedium(me
, i
)));
1824 * chop trailing whitespace or terminate empty string
1834 * ------------------------------------------------------------------------
1835 * Name: XpOidTrayMediumListHasTray
1839 * Determines if 'tray' is found in 'list'.
1843 * xTrue if the tray is found in the list.
1845 * xFalse if the tray is not in the list, or if 'list' is NULL.
1849 XpOidTrayMediumListHasTray(const XpOidTrayMediumList
* list
, XpOid tray
)
1852 if(list
!= (XpOidTrayMediumList
*)NULL
&& tray
!= xpoid_none
)
1853 for(i
= 0; i
< list
->count
; i
++)
1854 if(XpOidTrayMediumListTray(list
, i
) == tray
)
1860 * ------------------------------------------------------------------------
1865 * Skips leading whitespace and parses out and returns a XpOidArea.
1869 * xTrue if the XpOidArea was successfully parsed. ptr_return is
1870 * updated to point to location where the parsing ended.
1872 * xFalse if a XpOidArea was not found; ptr_return is updated
1873 * to point to the first non-whitespace char in value_string.
1877 ParseArea(const char* value_string
,
1878 const char** ptr_return
,
1879 XpOidArea
* area_return
)
1881 const char* first_nonws_ptr
;
1884 * skip leading whitespace
1886 first_nonws_ptr
= value_string
+ SpanWhitespace(value_string
);
1888 * parse out the area sequence start
1890 if(!ParseSeqStart(first_nonws_ptr
, &ptr
))
1891 goto ParseArea_error
;
1893 * parse the minimum x value
1895 if(!ParseRealValue(ptr
, &ptr
,
1896 area_return
? &area_return
->minimum_x
: NULL
))
1897 goto ParseArea_error
;
1899 * parse the maximum x value
1901 if(!ParseRealValue(ptr
, &ptr
,
1902 area_return
? &area_return
->maximum_x
: NULL
))
1903 goto ParseArea_error
;
1905 * parse the minimum y value
1907 if(!ParseRealValue(ptr
, &ptr
,
1908 area_return
? &area_return
->minimum_y
: NULL
))
1909 goto ParseArea_error
;
1911 * parse the maximum y value
1913 if(!ParseRealValue(ptr
, &ptr
,
1914 area_return
? &area_return
->maximum_y
: NULL
))
1915 goto ParseArea_error
;
1917 * parse out the area sequence end
1919 if(!ParseSeqEnd(ptr
, &ptr
))
1920 goto ParseArea_error
;
1922 * update the return pointer
1924 if(ptr_return
!= (const char**)NULL
)
1936 if(ptr_return
!= (const char**)NULL
)
1937 *ptr_return
= first_nonws_ptr
;
1942 * ------------------------------------------------------------------------
1943 * Name: ParseRealRange
1947 * Skips leading whitespace and parses out and returns a
1952 * xTrue if the XpOidRealRange was successfully
1953 * parsed. ptr_return is updated to point to location where the
1956 * xFalse if a XpOidRealRange was not found; ptr_return is
1957 * updated to point to the first non-whitespace char in value_string.
1961 ParseRealRange(const char* value_string
,
1962 const char** ptr_return
,
1963 XpOidRealRange
* range_return
)
1965 const char* first_nonws_ptr
;
1968 * skip leading whitespace
1970 first_nonws_ptr
= value_string
+ SpanWhitespace(value_string
);
1972 * parse out the range sequence start
1974 if(!ParseSeqStart(first_nonws_ptr
, &ptr
))
1975 goto ParseRealRange_error
;
1977 * parse the lower bound
1979 if(!ParseRealValue(ptr
, &ptr
,
1980 range_return
? &range_return
->lower_bound
: NULL
))
1981 goto ParseRealRange_error
;
1983 * parse the upper bound
1985 if(!ParseRealValue(ptr
, &ptr
,
1986 range_return
? &range_return
->upper_bound
: NULL
))
1987 goto ParseRealRange_error
;
1989 * parse out the range sequence end
1991 if(!ParseSeqEnd(ptr
, &ptr
))
1992 goto ParseRealRange_error
;
1994 * update the return pointer
1996 if(ptr_return
!= (const char**)NULL
)
2004 ParseRealRange_error
:
2008 if(ptr_return
!= (const char**)NULL
)
2009 *ptr_return
= first_nonws_ptr
;
2014 * ------------------------------------------------------------------------
2015 * Name: XpOidNotifyParse
2024 XpOidNotify
XpOidNotifyParse(const char* value_string
)
2026 const char* ptr
= value_string
;
2028 if(value_string
== (const char*)NULL
)
2029 return XPOID_NOTIFY_NONE
;
2031 * look for an event handling profile sequence start
2033 if(!ParseSeqStart(value_string
, &ptr
))
2037 * empty value is valid
2039 return XPOID_NOTIFY_NONE
;
2041 return XPOID_NOTIFY_UNSUPPORTED
;
2044 * look for an event set sequence start
2046 if(!ParseSeqStart(ptr
, &ptr
))
2049 * check for an empty event handling profile
2051 if(ParseSeqEnd(ptr
, &ptr
))
2053 ptr
+= SpanWhitespace(ptr
);
2056 * valid empty event handling profile sequence
2058 return XPOID_NOTIFY_NONE
;
2060 return XPOID_NOTIFY_UNSUPPORTED
;
2063 * the only event in the set should be report job completed
2065 if(xpoid_val_event_report_job_completed
!= XpOidParse(ptr
, &ptr
))
2066 return XPOID_NOTIFY_UNSUPPORTED
;
2068 * event set sequence end
2070 if(!ParseSeqEnd(ptr
, &ptr
))
2071 return XPOID_NOTIFY_UNSUPPORTED
;
2073 * delivery method of electronic mail
2075 if(xpoid_val_delivery_method_electronic_mail
!= XpOidParse(ptr
, &ptr
))
2076 return XPOID_NOTIFY_UNSUPPORTED
;
2078 * event handling profile sequence end
2080 if(!ParseSeqEnd(ptr
, &ptr
))
2081 return XPOID_NOTIFY_UNSUPPORTED
;
2085 ptr
+= SpanWhitespace(ptr
);
2088 * valid supported notification profile
2090 return XPOID_NOTIFY_EMAIL
;
2092 return XPOID_NOTIFY_UNSUPPORTED
;
2096 * ------------------------------------------------------------------------
2097 * Name: XpOidNotifyString
2106 const char* XpOidNotifyString(XpOidNotify notify
)
2110 case XPOID_NOTIFY_NONE
:
2111 return NOTIFY_NONE_STR
;
2112 case XPOID_NOTIFY_EMAIL
:
2113 return NOTIFY_EMAIL_STR
;
2114 case XPOID_NOTIFY_UNSUPPORTED
:
2115 return (const char *)NULL
;
2118 ErrorF("XpOidNotifyString: Unsupported notify=%ld\n", (long)notify
);
2119 return (const char *)NULL
;
2123 * ------------------------------------------------------------------------
2124 * Name: XpOidDocFmtNew
2134 XpOidDocFmtNew(const char* value_string
)
2136 XpOidDocFmt
* doc_fmt
;
2139 if((const char*)NULL
== value_string
)
2140 return (XpOidDocFmt
*)NULL
;
2141 ptr
= value_string
+ SpanWhitespace(value_string
);
2143 return (XpOidDocFmt
*)NULL
;
2145 * get the document format from the value string
2147 doc_fmt
= (XpOidDocFmt
*)XpOidCalloc(1, sizeof(XpOidDocFmt
));
2148 if(xTrue
== XpOidDocFmtNext(doc_fmt
, ptr
, &ptr
))
2151 * verify that the document format is the only value specified
2153 ptr
+= SpanWhitespace(ptr
);
2156 * valid document-format value
2163 XpOidDocFmtDelete(doc_fmt
);
2164 ErrorF("%s\n", XPMSG_WARN_DOC_FMT
);
2165 return (XpOidDocFmt
*)NULL
;
2169 * ------------------------------------------------------------------------
2170 * Name: XpOidDocFmtDelete
2180 XpOidDocFmtDelete(XpOidDocFmt
* doc_fmt
)
2182 if((XpOidDocFmt
*)NULL
!= doc_fmt
)
2184 XpOidFree(doc_fmt
->format
);
2185 XpOidFree(doc_fmt
->variant
);
2186 XpOidFree(doc_fmt
->version
);
2192 * ------------------------------------------------------------------------
2193 * Name: XpOidDocFmtString
2203 XpOidDocFmtString(XpOidDocFmt
* doc_fmt
)
2205 if((XpOidDocFmt
*)NULL
!= doc_fmt
)
2207 if((char*)NULL
!= doc_fmt
->format
)
2209 char* str
= XpOidMalloc(1+SafeStrLen(doc_fmt
->format
)+
2210 1+SafeStrLen(doc_fmt
->variant
)+
2211 1+SafeStrLen(doc_fmt
->version
)+
2213 sprintf(str
, "{%s %s %s}", doc_fmt
->format
,
2214 (char*)NULL
!= doc_fmt
->variant
? doc_fmt
->variant
: "",
2215 (char*)NULL
!= doc_fmt
->version
? doc_fmt
->version
: "");
2223 * ------------------------------------------------------------------------
2224 * Name: XpOidDocFmtNext
2228 * Assumes non-NULL value string.
2235 XpOidDocFmtNext(XpOidDocFmt
* doc_fmt
,
2236 const char* value_string
,
2237 const char** ptr_return
)
2240 const char* first_nonws_ptr
;
2242 const char* variant
;
2243 const char* version
;
2248 * skip leading whitespace
2250 ptr
= value_string
+ SpanWhitespace(value_string
);
2251 first_nonws_ptr
= ptr
;
2255 if(!ParseSeqStart(ptr
, &ptr
))
2256 goto XpOidDocFmtNext_error
;
2258 * skip whitepace to the start of the document format, and save the
2261 ptr
+= SpanWhitespace(ptr
);
2266 if(0 == (format_len
= SpanToken(ptr
)))
2267 goto XpOidDocFmtNext_error
;
2272 ptr
+= SpanWhitespace(ptr
);
2274 if(0 != (variant_len
= SpanToken(ptr
)))
2280 ptr
+= SpanWhitespace(ptr
);
2282 version_len
= SpanToken(ptr
);
2290 if(!ParseSeqEnd(ptr
, &ptr
))
2291 goto XpOidDocFmtNext_error
;
2293 * update return pointer
2295 if((const char**)NULL
!= ptr_return
)
2298 * update the passed document format struct
2300 memset(doc_fmt
, 0, sizeof(XpOidDocFmt
));
2301 doc_fmt
->format
= XpOidMalloc(format_len
+1);
2302 strncpy(doc_fmt
->format
, format
, format_len
);
2303 doc_fmt
->format
[format_len
] = '\0';
2306 doc_fmt
->variant
= XpOidMalloc(variant_len
+1);
2307 strncpy(doc_fmt
->variant
, variant
, variant_len
);
2308 doc_fmt
->variant
[variant_len
] = '\0';
2311 doc_fmt
->version
= XpOidMalloc(version_len
+1);
2312 strncpy(doc_fmt
->version
, version
, version_len
);
2313 doc_fmt
->version
[version_len
] = '\0';
2318 XpOidDocFmtNext_error
:
2319 if((const char**)NULL
!= ptr_return
)
2320 *ptr_return
= first_nonws_ptr
;
2325 * ------------------------------------------------------------------------
2326 * Name: XpOidDocFmtListNew
2336 XpOidDocFmtListNew(const char* value_string
,
2337 const XpOidDocFmtList
* valid_fmts
)
2339 if((char*)NULL
!= value_string
)
2342 return XpOidDocFmtListParse(value_string
, valid_fmts
, &ptr
, 0);
2344 return (XpOidDocFmtList
*)NULL
;
2348 * ------------------------------------------------------------------------
2349 * Name: XpOidDocFmtListDelete
2359 XpOidDocFmtListDelete(XpOidDocFmtList
* list
)
2361 if((XpOidDocFmtList
*)NULL
!= list
)
2364 for(i
= 0; i
< list
->count
; i
++)
2366 XpOidFree(list
->list
[i
].format
);
2367 XpOidFree(list
->list
[i
].variant
);
2368 XpOidFree(list
->list
[i
].version
);
2370 XpOidFree(list
->list
);
2376 * ------------------------------------------------------------------------
2377 * Name: XpOidDocFmtListString
2381 * Assumes the passed structure is valid.
2388 XpOidDocFmtListString(const XpOidDocFmtList
* list
)
2390 if((XpOidDocFmtList
*)NULL
!= list
)
2399 * allocate the return string
2401 for(i
= 0, str_len
= 0; i
< list
->count
; i
++)
2404 1 + SafeStrLen(list
->list
[i
].format
) +
2405 1 + SafeStrLen(list
->list
[i
].variant
) +
2406 1 + SafeStrLen(list
->list
[i
].version
) + 2;
2408 str
= XpOidMalloc(str_len
+1);
2410 * print the list into the string and return it
2413 for(i
= 0; i
< list
->count
; i
++)
2415 XpOidDocFmt
* df
= &list
->list
[i
];
2417 #if defined(sun) && !defined(SVR4)
2418 sprintf(ptr
, "{%s %s %s} ",
2420 (char*)NULL
!= df
->variant
? df
->variant
: "",
2421 (char*)NULL
!= df
->version
? df
->version
: "");
2425 sprintf(ptr
, "{%s %s %s} ",
2427 (char*)NULL
!= df
->variant
? df
->variant
: "",
2428 (char*)NULL
!= df
->version
? df
->version
: "");
2438 * ------------------------------------------------------------------------
2439 * Name: XpOidDocFmtListParse
2443 * Assumes the passed value_string and ptr_return are non-NULL.
2449 static XpOidDocFmtList
*
2450 XpOidDocFmtListParse(const char* value_string
,
2451 const XpOidDocFmtList
* valid_fmts
,
2452 const char** ptr_return
,
2455 XpOidDocFmt doc_fmt
;
2456 XpOidDocFmtList
* list
;
2459 * get the next document-format from the value string, skipping
2460 * values not found in the passed list of valid formats
2462 *ptr_return
= value_string
;
2463 while((status
= XpOidDocFmtNext(&doc_fmt
, *ptr_return
, ptr_return
))
2465 (const XpOidDocFmtList
*)NULL
!= valid_fmts
2467 !XpOidDocFmtListHasFmt(valid_fmts
, &doc_fmt
)
2470 if(xFalse
== status
)
2472 if('\0' == **ptr_return
)
2477 * empty value string
2479 return (XpOidDocFmtList
*)NULL
;
2484 * done parsing; allocate the list and return
2487 (XpOidDocFmtList
*)XpOidCalloc(1, sizeof(XpOidDocFmtList
));
2489 list
->list
= (XpOidDocFmt
*)XpOidCalloc(i
, sizeof(XpOidDocFmt
));
2496 * invalid document format
2498 ErrorF("%s\n", XPMSG_WARN_DOCFMT_LIST
);
2499 return (XpOidDocFmtList
*)NULL
;
2505 * recurse to parse remaining document formats
2507 list
= XpOidDocFmtListParse(*ptr_return
, valid_fmts
, ptr_return
, i
+1);
2508 if((XpOidDocFmtList
*)NULL
!= list
)
2511 * add this doc fmt to the list
2513 list
->list
[i
].format
= doc_fmt
.format
;
2514 list
->list
[i
].variant
= doc_fmt
.variant
;
2515 list
->list
[i
].version
= doc_fmt
.version
;
2522 * ------------------------------------------------------------------------
2523 * Name: XpOidDocFmtListHasFmt
2527 * Assumes the passed structure is valid.
2534 XpOidDocFmtListHasFmt(const XpOidDocFmtList
* list
,
2535 const XpOidDocFmt
* fmt
)
2538 if(list
!= (XpOidDocFmtList
*)NULL
2540 fmt
!= (XpOidDocFmt
*)NULL
2542 fmt
->format
!= (char*)NULL
2545 for(i
= 0; i
< list
->count
; i
++)
2548 * formats must match
2550 if(strcmp(fmt
->format
, list
->list
[i
].format
) != 0)
2553 * variants must both be NULL or match
2555 if(fmt
->variant
== (char*)NULL
)
2557 if(list
->list
[i
].variant
== (char*)NULL
)
2562 if(list
->list
[i
].variant
== (char*)NULL
)
2564 if(strcmp(fmt
->variant
, list
->list
[i
].variant
) != 0)
2567 * versions must both be NULL or match
2569 if(fmt
->version
== (char*)NULL
)
2571 if(list
->list
[i
].version
== (char*)NULL
)
2576 if(list
->list
[i
].version
== (char*)NULL
)
2578 if(strcmp(fmt
->version
, list
->list
[i
].version
) == 0)
2586 * ------------------------------------------------------------------------
2587 * Name: XpOidCardListNew
2597 XpOidCardListNew(const char* value_string
, const XpOidCardList
* valid_cards
)
2599 if((const char*)NULL
!= value_string
)
2603 return XpOidCardListParse(value_string
, valid_cards
, &ptr
, 0);
2606 return (XpOidCardList
*)NULL
;
2610 * ------------------------------------------------------------------------
2611 * Name: XpOidCardListDelete
2621 XpOidCardListDelete(XpOidCardList
* list
)
2623 if((XpOidCardList
*)NULL
!= list
)
2625 XpOidFree(list
->list
);
2631 * ------------------------------------------------------------------------
2632 * Name: XpOidCardListString
2642 XpOidCardListString(const XpOidCardList
* list
)
2644 if((XpOidCardList
*)NULL
!= list
)
2652 * allocate the output string
2654 for(i
= 0, str_len
= 0; i
< list
->count
; i
++)
2655 #if defined(sun) && !defined(SVR4)
2657 sprintf(buf
, "%lu", list
->list
[i
]) + 1;
2658 str_len
+= strlen(buf
);
2661 str_len
+= sprintf(buf
, "%lu", list
->list
[i
]) + 1;
2663 str
= XpOidMalloc(str_len
+1);
2665 * write the list to the string
2667 for(i
= 0, ptr
= str
; i
< list
->count
; i
++)
2668 #if defined(sun) && !defined(SVR4)
2670 sprintf(ptr
, "%lu ", list
->list
[i
]);
2674 ptr
+= sprintf(ptr
, "%lu ", list
->list
[i
]);
2683 * ------------------------------------------------------------------------
2684 * Name: XpOidCardListHasCard
2688 * Determines if 'card' is an element of 'list'.
2692 * xTrue if the card is found in the list.
2694 * xFalse if the card is not in the list, or if 'list' is NULL.
2698 XpOidCardListHasCard(const XpOidCardList
* list
, unsigned long card
)
2701 if(list
!= (XpOidCardList
*)NULL
)
2702 for(i
= 0; i
< list
->count
; i
++)
2703 if(list
->list
[i
] == card
)
2709 * ------------------------------------------------------------------------
2710 * Name: XpOidCardListParse
2714 * Assumes the passed value_string and ptr_return are non-NULL.
2720 static XpOidCardList
*
2721 XpOidCardListParse(const char* value_string
,
2722 const XpOidCardList
* valid_cards
,
2723 const char** ptr_return
,
2727 XpOidCardList
* list
;
2731 * get the next card from the value string, skipping values not
2732 * found in the passed list of valid cards
2734 *ptr_return
= value_string
;
2735 while((status
= XpOidParseUnsignedValue(*ptr_return
, ptr_return
, &card
))
2737 (const XpOidCardList
*)NULL
!= valid_cards
2739 !XpOidCardListHasCard(valid_cards
, card
)
2742 if(xFalse
== status
)
2744 if('\0' == **ptr_return
)
2749 * empty value string
2751 return (XpOidCardList
*)NULL
;
2756 * done parsing; allocate the list and return
2758 list
= (XpOidCardList
*)XpOidCalloc(1, sizeof(XpOidCardList
));
2761 (unsigned long*)XpOidCalloc(i
, sizeof(unsigned long));
2770 ErrorF("%s\n", XPMSG_WARN_CARD_LIST
);
2771 return (XpOidCardList
*)NULL
;
2777 * recurse to parse remaining cardinal values
2779 list
= XpOidCardListParse(*ptr_return
, valid_cards
, ptr_return
, i
+1);
2780 if((XpOidCardList
*)NULL
!= list
)
2783 * add this value to the list
2785 list
->list
[i
] = card
;
2792 * ------------------------------------------------------------------------
2793 * Name: ParseBoolValue
2803 ParseBoolValue(const char* value_string
,
2804 const char** ptr_return
,
2811 * skip leading whitespace
2813 ptr
= value_string
+ SpanWhitespace(value_string
);
2815 * get the whitespace-delimited token length
2817 length
= SpanToken(ptr
);
2819 * determine if true or false or bad
2821 if(StrnCaseCmp(ptr
, "TRUE", length
) == 0)
2823 if(bool_return
!= (BOOL
*)NULL
)
2824 *bool_return
= xTrue
;
2827 else if(StrnCaseCmp(ptr
, "FALSE", length
) == 0)
2829 if(bool_return
!= (BOOL
*)NULL
)
2830 *bool_return
= xFalse
;
2841 * update the return pointer and return
2843 if(ptr_return
!= (const char**)NULL
)
2844 *ptr_return
= status
? ptr
+length
: ptr
;
2849 * ------------------------------------------------------------------------
2850 * Name: XpOidParseUnsignedValue
2854 * Skips leading whitespace and parses out and returns a unsigned number.
2858 * xTrue if a unsigned number was successfully parsed. ptr_return is
2859 * updated to point to location where the unsigned number parsing
2862 * xFalse if a unsigned number was not found; ptr_return is updated
2863 * to point to the first non-whitespace char in value_string.
2867 XpOidParseUnsignedValue(const char* value_string
,
2868 const char** ptr_return
,
2869 unsigned long* unsigned_return
)
2873 const char* first_nonws_ptr
;
2876 * skip leading whitespace
2878 first_nonws_ptr
= value_string
+ SpanWhitespace(value_string
);
2879 value
= strtol(first_nonws_ptr
, (char**)(&ptr
), 0);
2880 if(ptr
== first_nonws_ptr
|| value
< 0)
2885 * update return parms
2887 if(ptr_return
!= (const char**)NULL
)
2889 if(unsigned_return
!= (unsigned long*)NULL
)
2890 *unsigned_return
= (unsigned long)value
;
2898 * ------------------------------------------------------------------------
2899 * Name: ParseRealValue
2903 * Skips leading whitespace and parses out and returns a real number.
2907 * xTrue if a real number was successfully parsed. ptr_return is
2908 * updated to point to location where the real number parsing
2911 * xFalse if a real number was not found; ptr_return is updated
2912 * to point to the first non-whitespace char in value_string.
2916 ParseRealValue(const char* value_string
,
2917 const char** ptr_return
,
2922 const char* first_nonws_ptr
;
2925 * skip leading whitespace
2927 first_nonws_ptr
= value_string
+ SpanWhitespace(value_string
);
2928 real_value
= (float)strtod(first_nonws_ptr
, (char**)(&ptr
));
2929 if(ptr
== first_nonws_ptr
)
2934 * update return parms
2936 if(ptr_return
!= (const char**)NULL
)
2938 if(real_return
!= (float*)NULL
)
2939 *real_return
= real_value
;
2947 * ------------------------------------------------------------------------
2954 * Skips leading whitespace and parses out the sequence end
2959 * xTrue if the sequence end character was parsed; ptr_return is
2960 * updated to point to the first char following the sequence end
2963 * xFalse if the sequence end character was not found; ptr_return is
2964 * updated to point to the first non-whitespace char in value_string.
2968 ParseSeqEnd(const char* value_string
,
2969 const char** ptr_return
)
2974 * skip leading whitespace
2976 ptr
= value_string
+ SpanWhitespace(value_string
);
2978 * parse out the sequence end character
2988 * update the return pointer
2990 if(ptr_return
!= (const char**)NULL
)
2999 * ------------------------------------------------------------------------
3000 * Name: ParseSeqStart
3004 * Skips leading whitespace and parses out the sequence start
3009 * xTrue if the sequence start character was parsed; ptr_return is
3010 * updated to point to the first char following the sequence start
3013 * xFalse if the sequence start character was not found; ptr_return is
3014 * updated to point to the first non-whitespace char in value_string.
3018 ParseSeqStart(const char* value_string
,
3019 const char** ptr_return
)
3024 * skip leading whitespace
3026 ptr
= value_string
+ SpanWhitespace(value_string
);
3028 * parse out the sequence start character
3038 * update the return pointer
3040 if(ptr_return
!= (const char**)NULL
)
3049 * ------------------------------------------------------------------------
3050 * Name: ParseUnspecifiedValue
3054 * Skips leading whitespace and parses out an unspecified optional
3055 * value (i.e. matching '' or "" - skips all data between the set of
3060 * xTrue if an unspecified value was parsed; ptr_return is updated to
3061 * point to the first char following the trailing quote.
3063 * xFalse if an unspecified value was not found; ptr_return is updated
3064 * to point to the first non-whitespace char in value_string.
3068 ParseUnspecifiedValue(const char* value_string
,
3069 const char** ptr_return
)
3074 * skip leading whitespace
3076 ptr
= value_string
+ SpanWhitespace(value_string
);
3078 * parse out an unspecified optional value ('' or "")
3080 if(*ptr
== '\'' || *ptr
== '"')
3084 if(ptr_return
!= (const char**)NULL
)
3089 * skip over the matching delimiter
3092 ptr
+= strcspn(ptr
, delim
);
3101 * update the return pointer
3103 if(ptr_return
!= (const char**)NULL
)
3112 * ------------------------------------------------------------------------
3117 * Returns the length of the initial segment of the passed string
3118 * that consists entirely of non-whitespace and non-sequence
3119 * delimiter characters.
3124 SpanToken(const char* string
)
3128 *ptr
!= '\0' && !isspace(*ptr
) && *ptr
!= '{' && *ptr
!= '}';
3130 return ptr
- string
;
3134 * ------------------------------------------------------------------------
3135 * Name: SpanWhitespace
3139 * Returns the length of the initial segment of the passed string
3140 * that consists entirely of whitespace characters.
3145 SpanWhitespace(const char* string
)
3148 for(ptr
= string
; *ptr
!= '\0' && isspace(*ptr
); ++ptr
);
3149 return ptr
- string
;
3152 #ifndef HAVE_STRCASECMP
3154 * ------------------------------------------------------------------------
3159 * Implements strncasecmp() for those platforms that need it.
3164 StrnCaseCmp(const char *s1
, const char *s2
, size_t len
)
3173 result
= tolower(c1
) - tolower(c2
);