PdmOid.c 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $TOG: PdmOid.c /main/12 1997/11/20 16:37:12 bill $ */
  24. /*
  25. * dtpdm/PdmOid.c
  26. */
  27. /*
  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.
  35. */
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include "PdmOid.h"
  39. #include <Dt/DtNlUtils.h>
  40. #include "PdmMsgs.h"
  41. /*
  42. * PdmOidNotify value strings
  43. */
  44. #define NOTIFY_EMAIL_STR "{{event-report-job-completed} electronic-mail}"
  45. #define NOTIFY_NONE_STR "{}"
  46. /*
  47. * entry type for the object identifier string map
  48. */
  49. typedef struct _PdmOidStringMapEntry
  50. {
  51. const char* string;
  52. int length;
  53. int msg_set;
  54. int msg_number;
  55. const char* default_message;
  56. } PdmOidStringMapEntry;
  57. /*
  58. * include the auto-generated static PdmOidStringMap
  59. */
  60. #include "PdmOidStrs.h"
  61. /*
  62. * PdmOid static function declarations
  63. */
  64. static PdmOid PdmOidParse(const char* value_string,
  65. const char** ptr_return);
  66. /*
  67. * PdmOidList static function declarations
  68. */
  69. static PdmOidList* PdmOidListParse(const char* value_string,
  70. const char** ptr_return, int i);
  71. /*
  72. * PdmOidMediumSourceSize static function declarations
  73. */
  74. static PdmOidMediumSS* MediumSSParse(const char* value_string,
  75. const char** ptr_return, int i);
  76. static PdmOidMediumContinuousSize* MediumContinuousSizeParse(const char*,
  77. const char**);
  78. static void MediumContinuousSizeDelete(PdmOidMediumContinuousSize* me);
  79. static PdmOidMediumDiscreteSizeList* MediumDiscreteSizeListParse(const char*,
  80. const char**,
  81. int i);
  82. static void MediumDiscreteSizeListDelete(PdmOidMediumDiscreteSizeList* list);
  83. static Boolean ParseArea(const char* value_string,
  84. const char** ptr_return,
  85. PdmOidArea* area_return);
  86. static Boolean ParseUnsignedRange(const char* value_string,
  87. const char** ptr_return,
  88. PdmOidUnsignedRange* range_return);
  89. /*
  90. * PdmOidTrayMediumList static function declarations
  91. */
  92. static PdmOidTrayMediumList* TrayMediumListParse(const char* value_string,
  93. const char** ptr_return,
  94. int i);
  95. /*
  96. * PdmOidDocumentFormat
  97. */
  98. static char* PdmOidDocumentFormatNext(const char* value_string,
  99. const char** ptr_return);
  100. /*
  101. * misc. parsing static function declarations
  102. */
  103. static Boolean ParseBooleanValue(const char* value_string,
  104. const char** ptr_return,
  105. Boolean* boolean_return);
  106. static Boolean ParseUnsignedValue(const char* value_string,
  107. const char** ptr_return,
  108. unsigned long* unsigned_return);
  109. static Boolean ParseRealValue(const char* value_string,
  110. const char** ptr_return,
  111. float* real_return);
  112. static Boolean ParseSeqEnd(
  113. const char* value_string,
  114. const char** ptr_return);
  115. static Boolean ParseSeqStart(
  116. const char* value_string,
  117. const char** ptr_return);
  118. static Boolean ParseUnspecifiedValue(
  119. const char* value_string,
  120. const char** ptr_return);
  121. static int SpanToken(
  122. const char* string);
  123. static int SpanWhitespace(
  124. const char* string);
  125. /*
  126. * ------------------------------------------------------------------------
  127. * Name: PdmOidString
  128. *
  129. * Description:
  130. *
  131. *
  132. * Return value:
  133. *
  134. */
  135. const char*
  136. PdmOidString(PdmOid pdm_oid)
  137. {
  138. /*
  139. * PdmOid enum values are index values into the string map
  140. */
  141. return PdmOidStringMap[pdm_oid].string;
  142. }
  143. /*
  144. * ------------------------------------------------------------------------
  145. * Name: PdmOidMsgSet
  146. *
  147. * Description:
  148. *
  149. *
  150. * Return value:
  151. *
  152. */
  153. int
  154. PdmOidMsgSet(PdmOid pdm_oid)
  155. {
  156. /*
  157. * PdmOid enum values are index values into the string map
  158. */
  159. return PdmOidStringMap[pdm_oid].msg_set;
  160. }
  161. /*
  162. * ------------------------------------------------------------------------
  163. * Name: PdmOidMsgNum
  164. *
  165. * Description:
  166. *
  167. *
  168. * Return value:
  169. *
  170. */
  171. int
  172. PdmOidMsgNum(PdmOid pdm_oid)
  173. {
  174. /*
  175. * PdmOid enum values are index values into the string map
  176. */
  177. return PdmOidStringMap[pdm_oid].msg_number;
  178. }
  179. /*
  180. * ------------------------------------------------------------------------
  181. * Name: PdmOidDefaultMsg
  182. *
  183. * Description:
  184. *
  185. *
  186. * Return value:
  187. *
  188. */
  189. const char*
  190. PdmOidDefaultMsg(PdmOid pdm_oid)
  191. {
  192. if(PdmOidStringMap[pdm_oid].default_message == (const char*)NULL)
  193. return PdmOidStringMap[pdm_oid].string;
  194. else
  195. return PdmOidStringMap[pdm_oid].default_message;
  196. }
  197. /*
  198. * ------------------------------------------------------------------------
  199. * Name: PdmOidStringLength
  200. *
  201. * Description:
  202. *
  203. *
  204. * Return value:
  205. *
  206. */
  207. int
  208. PdmOidStringLength(PdmOid pdm_oid)
  209. {
  210. /*
  211. * PdmOid enum values are index values into the string map
  212. */
  213. return PdmOidStringMap[pdm_oid].length;
  214. }
  215. /*
  216. * ------------------------------------------------------------------------
  217. * Name: PdmOidFromString
  218. *
  219. * Description:
  220. *
  221. *
  222. * Return value:
  223. *
  224. */
  225. PdmOid
  226. PdmOidFromString(const char* value)
  227. {
  228. if(value == (const char*)NULL)
  229. return pdmoid_none;
  230. else
  231. return PdmOidParse(value, (const char**)NULL);
  232. }
  233. /*
  234. * ------------------------------------------------------------------------
  235. * Name: PdmOidParse
  236. *
  237. * Description:
  238. *
  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.
  242. *
  243. * Return value:
  244. *
  245. * The corresponding PdmOid for the parsed name string.
  246. * A return value of pdmoid_none is returned if the parsed name
  247. * was not a valid oid or if no name was found.
  248. *
  249. */
  250. static PdmOid
  251. PdmOidParse(const char* value_string,
  252. const char** ptr_return)
  253. {
  254. const char* ptr;
  255. int length;
  256. int i;
  257. /*
  258. * skip leading whitespace
  259. */
  260. ptr = value_string + SpanWhitespace(value_string);
  261. /*
  262. * get the whitespace-delimited token length
  263. */
  264. length = SpanToken(ptr);
  265. /*
  266. * match the oid string in the map
  267. */
  268. for(i = 0; i < PdmOidStringMapCount; i++)
  269. if(length == PdmOidStringMap[i].length)
  270. if(strncmp(ptr, PdmOidStringMap[i].string, length) == 0)
  271. break;
  272. if(i == PdmOidStringMapCount)
  273. i = pdmoid_none;
  274. /*
  275. * update the return pointer and return
  276. */
  277. if(ptr_return != (const char**)NULL)
  278. *ptr_return = ptr+length;
  279. return i;
  280. }
  281. /*
  282. * ------------------------------------------------------------------------
  283. * Name: PdmOidListNew
  284. *
  285. * Description:
  286. *
  287. *
  288. * Return value:
  289. *
  290. *
  291. *
  292. */
  293. PdmOidList*
  294. PdmOidListNew(const char* value_string)
  295. {
  296. if(value_string == (const char*)NULL)
  297. return (PdmOidList*)NULL;
  298. else
  299. {
  300. const char* ptr;
  301. return PdmOidListParse(value_string, &ptr, 0);
  302. }
  303. }
  304. /*
  305. * ------------------------------------------------------------------------
  306. * Name: PdmOidListParse
  307. *
  308. * Description:
  309. *
  310. * 'ptr_return' *cannot* be NULL.
  311. *
  312. * Return value:
  313. *
  314. *
  315. *
  316. */
  317. static PdmOidList*
  318. PdmOidListParse(const char* value_string,
  319. const char** ptr_return, int i)
  320. {
  321. PdmOid oid = pdmoid_none;
  322. PdmOidList* list;
  323. /*
  324. * parse the next valid oid out of the value string
  325. */
  326. ptr_return = &value_string;
  327. while(**ptr_return != '\0' &&
  328. (oid = PdmOidParse(*ptr_return, ptr_return)) == pdmoid_none);
  329. if(oid == pdmoid_none)
  330. {
  331. /*
  332. * end of value string; allocate the list structure
  333. */
  334. list = (PdmOidList*)XtCalloc(1, sizeof(PdmOidList));
  335. list->count = i;
  336. list->list = (PdmOid*)XtCalloc(i, sizeof(PdmOid));
  337. }
  338. else
  339. {
  340. /*
  341. * recurse
  342. */
  343. list = PdmOidListParse(*ptr_return, ptr_return, i+1);
  344. /*
  345. * set the oid in the list
  346. */
  347. list->list[i] = oid;
  348. }
  349. /*
  350. * return
  351. */
  352. return list;
  353. }
  354. /*
  355. * ------------------------------------------------------------------------
  356. * Name: PdmOidListHasOid
  357. *
  358. * Description:
  359. *
  360. *
  361. *
  362. * Return value:
  363. *
  364. *
  365. *
  366. */
  367. Boolean
  368. PdmOidListHasOid(const PdmOidList* list, PdmOid oid)
  369. {
  370. int i;
  371. if(list != (PdmOidList*)NULL)
  372. for(i = 0; i < list->count; i++)
  373. if(list->list[i] == oid)
  374. return 1;
  375. return 0;
  376. }
  377. /*
  378. * ------------------------------------------------------------------------
  379. * Name: PdmOidListGetIndex
  380. *
  381. * Description:
  382. *
  383. *
  384. *
  385. * Return value:
  386. *
  387. *
  388. *
  389. */
  390. int
  391. PdmOidListGetIndex(const PdmOidList* list, PdmOid oid)
  392. {
  393. int i;
  394. if(list != (PdmOidList*)NULL)
  395. for(i = 0; i < list->count; i++)
  396. if(list->list[i] == oid)
  397. return i;
  398. return -1;
  399. }
  400. /*
  401. * ------------------------------------------------------------------------
  402. * Name: PdmOidListDelete
  403. *
  404. * Description:
  405. *
  406. *
  407. *
  408. * Return value:
  409. *
  410. *
  411. *
  412. */
  413. void
  414. PdmOidListDelete(PdmOidList* list)
  415. {
  416. if(list != (PdmOidList*)NULL)
  417. {
  418. XtFree((char*)list->list);
  419. XtFree((char*)list);
  420. }
  421. }
  422. /*
  423. * ------------------------------------------------------------------------
  424. * Name: PdmOidLinkedListNew
  425. *
  426. * Description:
  427. *
  428. *
  429. * Return value:
  430. *
  431. */
  432. PdmOidLinkedList*
  433. PdmOidLinkedListNew(void)
  434. {
  435. return (PdmOidLinkedList*)XtCalloc(1, sizeof(PdmOidLinkedList));
  436. }
  437. /*
  438. * ------------------------------------------------------------------------
  439. * Name: PdmOidLinkedListDelete
  440. *
  441. * Description:
  442. *
  443. *
  444. * Return value:
  445. *
  446. */
  447. void
  448. PdmOidLinkedListDelete(PdmOidLinkedList* me)
  449. {
  450. if(me != (PdmOidLinkedList*)NULL)
  451. {
  452. while(me->head)
  453. {
  454. me->current = me->head;
  455. me->head = me->current->next;
  456. XtFree((char*)me->current);
  457. }
  458. XtFree((char*)me);
  459. }
  460. }
  461. /*
  462. * ------------------------------------------------------------------------
  463. * Name: PdmOidLinkedListGetOid
  464. *
  465. * Description:
  466. *
  467. *
  468. * Return value:
  469. *
  470. */
  471. PdmOid
  472. PdmOidLinkedListGetOid(PdmOidLinkedList* me, int i)
  473. {
  474. if(i < 0 || i >= me->count) return pdmoid_none;
  475. me->current = me->head;
  476. while(i--) me->current = me->current->next;
  477. return me->current->oid;
  478. }
  479. /*
  480. * ------------------------------------------------------------------------
  481. * Name: PdmOidLinkedListAddOid
  482. *
  483. * Description:
  484. *
  485. *
  486. * Return value:
  487. *
  488. */
  489. void
  490. PdmOidLinkedListAddOid(PdmOidLinkedList* me, PdmOid oid)
  491. {
  492. me->current = (PdmOidNode)XtCalloc(1, sizeof(struct PdmOidNodeStruct));
  493. me->current->oid = oid;
  494. ++me->count;
  495. if(me->tail)
  496. {
  497. me->tail->next = me->current;
  498. me->tail = me->current;
  499. }
  500. else
  501. me->head = me->tail = me->current;
  502. }
  503. /*
  504. * ------------------------------------------------------------------------
  505. * Name: PdmOidLinkedListGetIndex
  506. *
  507. * Description:
  508. *
  509. *
  510. * Return value:
  511. *
  512. */
  513. int
  514. PdmOidLinkedListGetIndex(PdmOidLinkedList* me, PdmOid oid)
  515. {
  516. int i = 0;
  517. me->current = me->head;
  518. while(me->current)
  519. if(me->current->oid == oid)
  520. return i;
  521. else
  522. {
  523. ++i;
  524. me->current = me->current->next;
  525. }
  526. return -1;
  527. }
  528. /*
  529. * ------------------------------------------------------------------------
  530. * Name: PdmOidLinkedListHasOid
  531. *
  532. * Description:
  533. *
  534. *
  535. * Return value:
  536. *
  537. */
  538. Boolean
  539. PdmOidLinkedListHasOid(PdmOidLinkedList* me,
  540. PdmOid oid)
  541. {
  542. me->current = me->head;
  543. while(me->current)
  544. if(me->current->oid == oid)
  545. return True;
  546. else
  547. me->current = me->current->next;
  548. return False;
  549. }
  550. /*
  551. * ------------------------------------------------------------------------
  552. * Name: PdmOidLinkedListFirstOid
  553. *
  554. * Description:
  555. *
  556. *
  557. * Return value:
  558. *
  559. */
  560. PdmOid
  561. PdmOidLinkedListFirstOid(PdmOidLinkedList* me)
  562. {
  563. if(me->current = me->head)
  564. return me->current->oid;
  565. else
  566. return pdmoid_none;
  567. }
  568. /*
  569. * ------------------------------------------------------------------------
  570. * Name: PdmOidLinkedListNextOid
  571. *
  572. * Description:
  573. *
  574. *
  575. * Return value:
  576. *
  577. */
  578. PdmOid
  579. PdmOidLinkedListNextOid(PdmOidLinkedList* me)
  580. {
  581. if(me->current ? me->current = me->current->next : False)
  582. return me->current->oid;
  583. else
  584. return pdmoid_none;
  585. }
  586. /*
  587. * ------------------------------------------------------------------------
  588. * Name: PdmOidLocalString
  589. *
  590. * Description:
  591. *
  592. *
  593. * Return value:
  594. *
  595. */
  596. const char*
  597. PdmOidLocalString(PdmOid pdm_oid)
  598. {
  599. /*
  600. * PdmOid enum values are index values into the string map
  601. */
  602. if(PdmOidStringMap[pdm_oid].msg_set != -1)
  603. {
  604. return DTPDM_GETMESSAGE(PdmOidStringMap[pdm_oid].msg_set,
  605. PdmOidStringMap[pdm_oid].msg_number,
  606. PdmOidStringMap[pdm_oid].string);
  607. }
  608. else
  609. return PdmOidStringMap[pdm_oid].string;
  610. }
  611. /*
  612. * ------------------------------------------------------------------------
  613. * Name: PdmOidMediumSSNew
  614. *
  615. * Description:
  616. *
  617. *
  618. *
  619. * Return value:
  620. *
  621. *
  622. *
  623. */
  624. PdmOidMediumSS*
  625. PdmOidMediumSSNew(const char* value_string)
  626. {
  627. if(value_string == (const char*)NULL)
  628. return (PdmOidMediumSS*)NULL;
  629. else
  630. {
  631. const char* ptr;
  632. return MediumSSParse(value_string, &ptr, 0);
  633. }
  634. }
  635. /*
  636. * ------------------------------------------------------------------------
  637. * Name: MediumSSParse
  638. *
  639. * Description:
  640. *
  641. * 'ptr_return' *cannot* be NULL.
  642. *
  643. *
  644. * Return value:
  645. *
  646. *
  647. *
  648. */
  649. static PdmOidMediumSS*
  650. MediumSSParse(const char* value_string,
  651. const char** ptr_return, int i)
  652. {
  653. PdmOidMediumSS* medium_ss;
  654. PdmOidMediumSourceSize mss;
  655. /*
  656. * check for the start of a new MediumSourceSize sequence
  657. */
  658. if(ParseSeqStart(value_string, ptr_return))
  659. {
  660. /*
  661. * check for an unspecified tray value
  662. */
  663. if(ParseUnspecifiedValue(*ptr_return, ptr_return))
  664. mss.input_tray = pdmoid_unspecified;
  665. else
  666. {
  667. /*
  668. * parse out the input tray
  669. */
  670. mss.input_tray = PdmOidParse(*ptr_return, ptr_return);
  671. }
  672. /*
  673. * attempt to parse a Continuous MediumSize sequence
  674. */
  675. mss.ms.continuous_size =
  676. MediumContinuousSizeParse(*ptr_return, ptr_return);
  677. if(mss.ms.continuous_size != (PdmOidMediumContinuousSize*)NULL)
  678. {
  679. mss.mstag = PdmOidMediumSS_CONTINUOUS;
  680. }
  681. else
  682. {
  683. /*
  684. * not continuous, try Discrete MediumSize
  685. */
  686. mss.ms.discrete =
  687. MediumDiscreteSizeListParse(*ptr_return, ptr_return, 0);
  688. if(mss.ms.discrete == (PdmOidMediumDiscreteSizeList*)NULL)
  689. {
  690. /*
  691. * syntax error (MediumDiscreteSizeListParse reports error)
  692. */
  693. return NULL;
  694. }
  695. mss.mstag = PdmOidMediumSS_DISCRETE;
  696. }
  697. /*
  698. * parse out the MediumSourceSize sequence end
  699. */
  700. if(!ParseSeqEnd(*ptr_return, ptr_return))
  701. {
  702. /*
  703. * syntax error
  704. */
  705. fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
  706. return NULL;
  707. }
  708. /*
  709. * recurse to parse the next MediumSourceSize sequence
  710. */
  711. medium_ss = MediumSSParse(*ptr_return, ptr_return, i+1);
  712. if(medium_ss == (PdmOidMediumSS*)NULL)
  713. {
  714. /*
  715. * syntax error - clean up and return
  716. */
  717. switch(mss.mstag)
  718. {
  719. case PdmOidMediumSS_CONTINUOUS:
  720. MediumContinuousSizeDelete(mss.ms.continuous_size);
  721. break;
  722. case PdmOidMediumSS_DISCRETE:
  723. MediumDiscreteSizeListDelete(mss.ms.discrete);
  724. break;
  725. }
  726. return NULL;
  727. }
  728. /*
  729. * copy the current MediumSourceSize into the array
  730. */
  731. memmove((medium_ss->mss)+i, &mss, sizeof(PdmOidMediumSourceSize));
  732. }
  733. else
  734. {
  735. /*
  736. * MediumSourceSize sequence start not found
  737. */
  738. if(**ptr_return == '\0')
  739. {
  740. /*
  741. * end of value string; allocate the MediumSS structure
  742. */
  743. medium_ss = (PdmOidMediumSS*)XtCalloc(1, sizeof(PdmOidMediumSS));
  744. medium_ss->count = i;
  745. medium_ss->mss = (PdmOidMediumSourceSize*)
  746. XtCalloc(i, sizeof(PdmOidMediumSourceSize));
  747. }
  748. else
  749. {
  750. /*
  751. * syntax error
  752. */
  753. fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
  754. return NULL;
  755. }
  756. }
  757. return medium_ss;
  758. }
  759. /*
  760. * ------------------------------------------------------------------------
  761. * Name: PdmOidMediumSSDelete
  762. *
  763. * Description:
  764. *
  765. *
  766. *
  767. * Return value:
  768. *
  769. *
  770. *
  771. */
  772. void
  773. PdmOidMediumSSDelete(PdmOidMediumSS* me)
  774. {
  775. if(me != (PdmOidMediumSS*)NULL)
  776. {
  777. int i;
  778. for(i = 0; i < me->count; i++)
  779. {
  780. switch((me->mss)[i].mstag)
  781. {
  782. case PdmOidMediumSS_CONTINUOUS:
  783. MediumContinuousSizeDelete((me->mss)[i].ms.continuous_size);
  784. break;
  785. case PdmOidMediumSS_DISCRETE:
  786. MediumDiscreteSizeListDelete((me->mss)[i].ms.discrete);
  787. break;
  788. }
  789. }
  790. XtFree((char*)me);
  791. }
  792. }
  793. /*
  794. * ------------------------------------------------------------------------
  795. * Name: PdmOidMediumSSGetAllSizes
  796. *
  797. * Description:
  798. *
  799. *
  800. *
  801. * Return value:
  802. *
  803. *
  804. *
  805. */
  806. PdmOidLinkedList*
  807. PdmOidMediumSSGetAllSizes(PdmOidMediumSS* me)
  808. {
  809. PdmOidLinkedList* all_sizes;
  810. int i_mss, i_ds;
  811. PdmOidMediumDiscreteSizeList* ds_list;
  812. PdmOid page_size;
  813. if(me == (PdmOidMediumSS*)NULL)
  814. return (PdmOidLinkedList*)NULL;
  815. all_sizes = PdmOidLinkedListNew();
  816. /*
  817. * loop through the MediumSourceSizes
  818. */
  819. for(i_mss = 0; i_mss < me->count; i_mss++)
  820. {
  821. switch((me->mss)[i_mss].mstag)
  822. {
  823. case PdmOidMediumSS_DISCRETE:
  824. /*
  825. * add unique discrete sizes to the size list
  826. */
  827. ds_list = (me->mss)[i_mss].ms.discrete;
  828. for(i_ds = 0; i_ds < ds_list->count; i_ds++)
  829. {
  830. page_size = (ds_list->list)[i_ds].page_size;
  831. if(page_size == pdmoid_none)
  832. continue;
  833. if(!PdmOidLinkedListHasOid(all_sizes, page_size))
  834. {
  835. PdmOidLinkedListAddOid(all_sizes, page_size);
  836. }
  837. }
  838. break;
  839. case PdmOidMediumSS_CONTINUOUS:
  840. /*
  841. * unsupported
  842. */
  843. break;
  844. }
  845. }
  846. /*
  847. * return
  848. */
  849. return all_sizes;
  850. }
  851. /*
  852. * ------------------------------------------------------------------------
  853. * Name: PdmOidMediumSSGetTraysSizes
  854. *
  855. * Description:
  856. *
  857. *
  858. *
  859. * Return value:
  860. *
  861. *
  862. *
  863. */
  864. void
  865. PdmOidMediumSSGetTraysSizes(PdmOidMediumSS* me,
  866. PdmOidTrayMediumList* trays_medium,
  867. PdmOidList** trays,
  868. PdmOidList** sizes)
  869. {
  870. int i_mss, i_ds, i_itm, i_its;
  871. PdmOidMediumDiscreteSizeList* ds_list;
  872. int tray_count;
  873. PdmOid current_tray, current_medium;
  874. PdmOidMediumDiscreteSizeList* unspecified_tray_ds;
  875. PdmOidMediumDiscreteSizeList* tray_ds;
  876. if(me == (PdmOidMediumSS*)NULL
  877. ||
  878. trays_medium == (PdmOidTrayMediumList*)NULL)
  879. {
  880. if(trays != (PdmOidList**)NULL) *trays = (PdmOidList*)NULL;
  881. if(sizes != (PdmOidList**)NULL) *sizes = (PdmOidList*)NULL;
  882. return;
  883. }
  884. /*
  885. * allocate the trays and sizes lists
  886. */
  887. tray_count = PdmOidTrayMediumListCount(trays_medium);
  888. if(tray_count == 0)
  889. {
  890. if(trays != (PdmOidList**)NULL) *trays = (PdmOidList*)NULL;
  891. if(sizes != (PdmOidList**)NULL) *sizes = (PdmOidList*)NULL;
  892. return;
  893. }
  894. if(trays != (PdmOidList**)NULL)
  895. {
  896. *trays = (PdmOidList*)XtCalloc(1, sizeof(PdmOidList));
  897. (*trays)->list = (PdmOid*)XtCalloc(tray_count, sizeof(PdmOid));
  898. }
  899. if(sizes != (PdmOidList**)NULL)
  900. {
  901. *sizes = (PdmOidList*)XtCalloc(1, sizeof(PdmOidList));
  902. (*sizes)->list = (PdmOid*)XtCalloc(tray_count, sizeof(PdmOid));
  903. }
  904. /*
  905. * loop through the input trays medium list
  906. */
  907. i_its = 0;
  908. for(i_itm = 0; i_itm < tray_count; i_itm++)
  909. {
  910. current_tray = PdmOidTrayMediumListTray(trays_medium, i_itm);
  911. if(current_tray == pdmoid_none)
  912. continue;
  913. current_medium = PdmOidTrayMediumListMedium(trays_medium, i_itm);
  914. if(current_medium == pdmoid_none)
  915. continue;
  916. /*
  917. * loop through the MediumSourceSizes, looking for an appropriate
  918. * discrete sizes spec for the current tray
  919. */
  920. unspecified_tray_ds = (PdmOidMediumDiscreteSizeList*)NULL;
  921. tray_ds = (PdmOidMediumDiscreteSizeList*)NULL;
  922. for(i_mss = 0;
  923. i_mss < me->count
  924. && tray_ds == (PdmOidMediumDiscreteSizeList*)NULL;
  925. i_mss++)
  926. {
  927. switch((me->mss)[i_mss].mstag)
  928. {
  929. case PdmOidMediumSS_DISCRETE:
  930. if((me->mss)[i_mss].input_tray == current_tray)
  931. tray_ds = (me->mss)[i_mss].ms.discrete;
  932. else if ((me->mss)[i_mss].input_tray == pdmoid_unspecified)
  933. unspecified_tray_ds = (me->mss)[i_mss].ms.discrete;
  934. break;
  935. case PdmOidMediumSS_CONTINUOUS:
  936. /*
  937. * unsupported
  938. */
  939. break;
  940. }
  941. }
  942. /*
  943. * if the tray was not matched, use the unspecifed tray size list
  944. */
  945. if(tray_ds == (PdmOidMediumDiscreteSizeList*)NULL)
  946. if(unspecified_tray_ds == (PdmOidMediumDiscreteSizeList*)NULL)
  947. {
  948. /*
  949. * not even an unspecified tray, skip this
  950. * input-trays-medium entry.
  951. */
  952. continue;
  953. }
  954. else
  955. tray_ds = unspecified_tray_ds;
  956. /*
  957. * loop through the discrete sizes list, looking for a size that
  958. * matches the medium for the current input tray
  959. */
  960. for(i_ds = 0; i_ds < tray_ds->count; i_ds++)
  961. {
  962. /*
  963. * check to see if the current input tray's medium size
  964. * matches the current discrete size
  965. *
  966. * Note: in the CDEnext SI, medium identifiers coincide with
  967. * medium-size identifiers. If the DP-Medium object is
  968. * ever implemented, this check would need to be
  969. * changed so that the input tray's medium size is
  970. * obtained from the indicated Medium object, and not
  971. * inferred from the medium identifier itself.
  972. */
  973. if((tray_ds->list)[i_ds].page_size == current_medium)
  974. {
  975. /*
  976. * the current input tray's medium size matches the
  977. * current discrete size; add the tray and medium size
  978. * Oids to the return lists.
  979. */
  980. if(trays != (PdmOidList**)NULL)
  981. (*trays)->list[i_its] = current_tray;
  982. if(sizes != (PdmOidList**)NULL)
  983. (*sizes)->list[i_its] = (tray_ds->list)[i_ds].page_size;
  984. ++i_its;
  985. break;
  986. }
  987. }
  988. }
  989. if(trays != (PdmOidList**)NULL) (*trays)->count = i_its;
  990. if(sizes != (PdmOidList**)NULL) (*sizes)->count = i_its;
  991. }
  992. /*
  993. * ------------------------------------------------------------------------
  994. * Name: MediumContinuousSizeParse
  995. *
  996. * Description:
  997. *
  998. * 'ptr_return' *cannot* be NULL.
  999. *
  1000. *
  1001. * Return value:
  1002. *
  1003. *
  1004. *
  1005. */
  1006. static PdmOidMediumContinuousSize*
  1007. MediumContinuousSizeParse(const char* value_string,
  1008. const char** ptr_return)
  1009. {
  1010. const char* first_nonws_ptr;
  1011. PdmOidMediumContinuousSize* mcs = NULL;
  1012. /*
  1013. * skip leading whitespace
  1014. */
  1015. first_nonws_ptr = value_string + SpanWhitespace(value_string);
  1016. /*
  1017. * parse out the MediumSize sequence start char
  1018. */
  1019. if(!ParseSeqStart(first_nonws_ptr, ptr_return))
  1020. goto MediumContinuousSizeParse_error;
  1021. /*
  1022. * peek ahead to see if it looks like we actually have a continuous
  1023. * size spec (looking for the sequence start char on the 1st range spec)
  1024. */
  1025. if(!ParseSeqStart(*ptr_return, (const char**)NULL))
  1026. goto MediumContinuousSizeParse_error;
  1027. /*
  1028. * Ok, let's go for it
  1029. */
  1030. mcs = (PdmOidMediumContinuousSize*)
  1031. XtCalloc(1, sizeof(PdmOidMediumContinuousSize));
  1032. /*
  1033. * "range across the feed direction"
  1034. */
  1035. if(!ParseUnsignedRange(*ptr_return, ptr_return, &mcs->range_across_feed))
  1036. goto MediumContinuousSizeParse_error;
  1037. /*
  1038. * "increment across the feed direction" (optional, default 0)
  1039. */
  1040. if(!ParseUnspecifiedValue(*ptr_return, ptr_return))
  1041. if(!ParseUnsignedValue(*ptr_return, ptr_return,
  1042. &mcs->increment_across_feed))
  1043. goto MediumContinuousSizeParse_error;
  1044. /*
  1045. * "range in the feed direction"
  1046. */
  1047. if(!ParseUnsignedRange(*ptr_return, ptr_return, &mcs->range_in_feed))
  1048. goto MediumContinuousSizeParse_error;
  1049. /*
  1050. * "increment in the feed direction" (optional, default 0)
  1051. */
  1052. if(!ParseUnspecifiedValue(*ptr_return, ptr_return))
  1053. if(!ParseUnsignedValue(*ptr_return, ptr_return,
  1054. &mcs->increment_in_feed))
  1055. goto MediumContinuousSizeParse_error;
  1056. /*
  1057. * "long edge feeds" flag (default TRUE)
  1058. */
  1059. if(ParseUnspecifiedValue(*ptr_return, ptr_return))
  1060. mcs->long_edge_feeds = True;
  1061. else
  1062. if(!ParseBooleanValue(*ptr_return, ptr_return, &mcs->long_edge_feeds))
  1063. goto MediumContinuousSizeParse_error;
  1064. /*
  1065. * "generic assured reproduction area"
  1066. */
  1067. if(!ParseArea(*ptr_return, ptr_return, &mcs->assured_reproduction_area))
  1068. goto MediumContinuousSizeParse_error;
  1069. /*
  1070. * parse out the MediumSize sequence end character
  1071. */
  1072. if(!ParseSeqEnd(*ptr_return, ptr_return))
  1073. goto MediumContinuousSizeParse_error;
  1074. /*
  1075. * return
  1076. */
  1077. return mcs;
  1078. MediumContinuousSizeParse_error:
  1079. /*
  1080. * syntax error - don't log since this function may be called
  1081. * as a lookahead
  1082. */
  1083. *ptr_return = first_nonws_ptr;
  1084. XtFree((char*)mcs);
  1085. return NULL;
  1086. }
  1087. /*
  1088. * ------------------------------------------------------------------------
  1089. * Name: MediumContinuousSizeDelete
  1090. *
  1091. * Description:
  1092. *
  1093. * 'ptr_return' *cannot* be NULL.
  1094. *
  1095. *
  1096. * Return value:
  1097. *
  1098. *
  1099. *
  1100. */
  1101. static void
  1102. MediumContinuousSizeDelete(PdmOidMediumContinuousSize* me)
  1103. {
  1104. XtFree((char*)me);
  1105. }
  1106. /*
  1107. * ------------------------------------------------------------------------
  1108. * Name: MediumDiscreteSizeListParse
  1109. *
  1110. * Description:
  1111. *
  1112. * 'ptr_return' *cannot* be NULL.
  1113. *
  1114. * Return value:
  1115. *
  1116. *
  1117. *
  1118. */
  1119. static PdmOidMediumDiscreteSizeList*
  1120. MediumDiscreteSizeListParse(const char* value_string,
  1121. const char** ptr_return, int i)
  1122. {
  1123. PdmOidMediumDiscreteSizeList* list;
  1124. PdmOidMediumDiscreteSize mds;
  1125. /*
  1126. * check for the start of a new MediumSize sequence
  1127. */
  1128. if(ParseSeqStart(value_string, ptr_return))
  1129. {
  1130. /*
  1131. * "page size"
  1132. */
  1133. mds.page_size = PdmOidParse(*ptr_return, ptr_return);
  1134. /*
  1135. * "long edge feeds" flag (default TRUE)
  1136. */
  1137. if(ParseUnspecifiedValue(*ptr_return, ptr_return))
  1138. mds.long_edge_feeds = True;
  1139. else
  1140. if(!ParseBooleanValue(*ptr_return, ptr_return,
  1141. &mds.long_edge_feeds))
  1142. {
  1143. /*
  1144. * syntax error
  1145. */
  1146. fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
  1147. return NULL;
  1148. }
  1149. /*
  1150. * "assured reproduction area"
  1151. */
  1152. if(!ParseArea(*ptr_return, ptr_return,
  1153. &mds.assured_reproduction_area))
  1154. {
  1155. /*
  1156. * syntax error
  1157. */
  1158. fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
  1159. return NULL;
  1160. }
  1161. /*
  1162. * parse out the MediumSize sequence end character
  1163. */
  1164. if(!ParseSeqEnd(*ptr_return, ptr_return))
  1165. {
  1166. fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
  1167. return NULL;
  1168. }
  1169. /*
  1170. * recurse to parse the next Discrete MediumSize sequence
  1171. */
  1172. list = MediumDiscreteSizeListParse(*ptr_return, ptr_return, i+1);
  1173. if(list != (PdmOidMediumDiscreteSizeList*)NULL)
  1174. {
  1175. /*
  1176. * copy the current discrete MediumSize into the list
  1177. */
  1178. memmove((list->list)+i, &mds, sizeof(PdmOidMediumDiscreteSize));
  1179. }
  1180. }
  1181. else
  1182. {
  1183. /*
  1184. * MediumSize sequence start not found; end of the discrete sizes
  1185. * list
  1186. */
  1187. list = (PdmOidMediumDiscreteSizeList*)
  1188. XtCalloc(1, sizeof(PdmOidMediumDiscreteSizeList));
  1189. list->count = i;
  1190. list->list = (PdmOidMediumDiscreteSize*)
  1191. XtCalloc(i, sizeof(PdmOidMediumDiscreteSize));
  1192. }
  1193. return list;
  1194. }
  1195. /*
  1196. * ------------------------------------------------------------------------
  1197. * Name: MediumDiscreteSizeListDelete
  1198. *
  1199. * Description:
  1200. *
  1201. *
  1202. *
  1203. * Return value:
  1204. *
  1205. *
  1206. *
  1207. */
  1208. static void
  1209. MediumDiscreteSizeListDelete(PdmOidMediumDiscreteSizeList* list)
  1210. {
  1211. if(list != (PdmOidMediumDiscreteSizeList*)NULL)
  1212. {
  1213. XtFree((char*)list->list);
  1214. XtFree((char*)list);
  1215. }
  1216. }
  1217. /*
  1218. * ------------------------------------------------------------------------
  1219. * Name: PdmOidTrayMediumListNew
  1220. *
  1221. * Description:
  1222. *
  1223. *
  1224. * Return value:
  1225. *
  1226. *
  1227. *
  1228. */
  1229. PdmOidTrayMediumList*
  1230. PdmOidTrayMediumListNew(const char* value_string)
  1231. {
  1232. if(value_string == (const char*)NULL)
  1233. return (PdmOidTrayMediumList*)NULL;
  1234. else
  1235. {
  1236. const char* ptr;
  1237. return TrayMediumListParse(value_string, &ptr, 0);
  1238. }
  1239. }
  1240. /*
  1241. * ------------------------------------------------------------------------
  1242. * Name: TrayMediumListParse
  1243. *
  1244. * Description:
  1245. *
  1246. * 'ptr_return' *cannot* be NULL.
  1247. *
  1248. * Return value:
  1249. *
  1250. *
  1251. *
  1252. */
  1253. static PdmOidTrayMediumList*
  1254. TrayMediumListParse(const char* value_string,
  1255. const char** ptr_return, int i)
  1256. {
  1257. PdmOidTrayMedium tm;
  1258. PdmOidTrayMediumList* list;
  1259. /*
  1260. * check for the start of a new InputTrayMedium sequence
  1261. */
  1262. if(ParseSeqStart(value_string, ptr_return))
  1263. {
  1264. /*
  1265. * "input tray"
  1266. */
  1267. tm.input_tray = PdmOidParse(*ptr_return, ptr_return);
  1268. /*
  1269. * "medium"
  1270. */
  1271. tm.medium = PdmOidParse(*ptr_return, ptr_return);
  1272. /*
  1273. * parse out the InputTrayMedium sequence end character
  1274. */
  1275. if(!ParseSeqEnd(*ptr_return, ptr_return))
  1276. {
  1277. fprintf(stderr, "%s\n", PDM_MSG_WARN_ITM);
  1278. return NULL;
  1279. }
  1280. /*
  1281. * recurse to parse the next InputTrayMedium sequence
  1282. */
  1283. list = TrayMediumListParse(*ptr_return, ptr_return, i+1);
  1284. if(list != (PdmOidTrayMediumList*)NULL)
  1285. {
  1286. /*
  1287. * copy the current InputTrayMedium into the list
  1288. */
  1289. memmove((list->list)+i, &tm, sizeof(PdmOidTrayMedium));
  1290. }
  1291. }
  1292. else
  1293. {
  1294. /*
  1295. * InputTrayMedium sequence start not found
  1296. */
  1297. if(**ptr_return == '\0')
  1298. {
  1299. /*
  1300. * end of the list
  1301. */
  1302. list = (PdmOidTrayMediumList*)
  1303. XtCalloc(1, sizeof(PdmOidTrayMediumList));
  1304. list->count = i;
  1305. if (i == 0)
  1306. list->list = NULL;
  1307. else
  1308. list->list = (PdmOidTrayMedium*)
  1309. XtCalloc(i, sizeof(PdmOidTrayMedium));
  1310. }
  1311. else
  1312. {
  1313. /*
  1314. * syntax error
  1315. */
  1316. fprintf(stderr, "%s\n", PDM_MSG_WARN_ITM);
  1317. return NULL;
  1318. }
  1319. }
  1320. /*
  1321. * return
  1322. */
  1323. return list;
  1324. }
  1325. /*
  1326. * ------------------------------------------------------------------------
  1327. * Name: PdmOidTrayMediumListDelete
  1328. *
  1329. * Description:
  1330. *
  1331. *
  1332. *
  1333. * Return value:
  1334. *
  1335. *
  1336. *
  1337. */
  1338. void
  1339. PdmOidTrayMediumListDelete(PdmOidTrayMediumList* list)
  1340. {
  1341. if(list != (PdmOidTrayMediumList*)NULL)
  1342. {
  1343. XtFree((char*)list->list);
  1344. XtFree((char*)list);
  1345. }
  1346. }
  1347. /*
  1348. * ------------------------------------------------------------------------
  1349. * Name: ParseArea
  1350. *
  1351. * Description:
  1352. *
  1353. * Skips leading whitespace and parses out and returns a PdmOidArea.
  1354. *
  1355. * Return value:
  1356. *
  1357. * True if the PdmOidArea was successfully parsed. ptr_return is
  1358. * updated to point to location where the parsing ended.
  1359. *
  1360. * False if a PdmOidArea was not found; ptr_return is updated
  1361. * to point to the first non-whitespace char in value_string.
  1362. *
  1363. */
  1364. static Boolean
  1365. ParseArea(const char* value_string,
  1366. const char** ptr_return,
  1367. PdmOidArea* area_return)
  1368. {
  1369. const char* first_nonws_ptr;
  1370. const char* ptr;
  1371. /*
  1372. * skip leading whitespace
  1373. */
  1374. first_nonws_ptr = value_string + SpanWhitespace(value_string);
  1375. /*
  1376. * parse out the area sequence start
  1377. */
  1378. if(!ParseSeqStart(first_nonws_ptr, &ptr))
  1379. goto ParseArea_error;
  1380. /*
  1381. * parse the minimum x value
  1382. */
  1383. if(!ParseRealValue(ptr, &ptr,
  1384. area_return ? &area_return->minimum_x : NULL))
  1385. goto ParseArea_error;
  1386. /*
  1387. * parse the maximum x value
  1388. */
  1389. if(!ParseRealValue(ptr, &ptr,
  1390. area_return ? &area_return->maximum_x : NULL))
  1391. goto ParseArea_error;
  1392. /*
  1393. * parse the minimum y value
  1394. */
  1395. if(!ParseRealValue(ptr, &ptr,
  1396. area_return ? &area_return->minimum_y : NULL))
  1397. goto ParseArea_error;
  1398. /*
  1399. * parse the maximum y value
  1400. */
  1401. if(!ParseRealValue(ptr, &ptr,
  1402. area_return ? &area_return->maximum_y : NULL))
  1403. goto ParseArea_error;
  1404. /*
  1405. * parse out the area sequence end
  1406. */
  1407. if(!ParseSeqEnd(ptr, &ptr))
  1408. goto ParseArea_error;
  1409. /*
  1410. * update the return pointer
  1411. */
  1412. if(ptr_return != (const char**)NULL)
  1413. *ptr_return = ptr;
  1414. /*
  1415. * return
  1416. */
  1417. return True;
  1418. ParseArea_error:
  1419. /*
  1420. * syntax error
  1421. */
  1422. if(ptr_return != (const char**)NULL)
  1423. *ptr_return = first_nonws_ptr;
  1424. return False;
  1425. }
  1426. /*
  1427. * ------------------------------------------------------------------------
  1428. * Name: ParseUnsignedRange
  1429. *
  1430. * Description:
  1431. *
  1432. * Skips leading whitespace and parses out and returns a
  1433. * PdmOidUnsignedRange.
  1434. *
  1435. * Return value:
  1436. *
  1437. * True if the PdmOidUnsignedRange was successfully
  1438. * parsed. ptr_return is updated to point to location where the
  1439. * parsing ended.
  1440. *
  1441. * False if a PdmOidUnsignedRange was not found; ptr_return is
  1442. * updated to point to the first non-whitespace char in value_string.
  1443. *
  1444. */
  1445. static Boolean
  1446. ParseUnsignedRange(const char* value_string,
  1447. const char** ptr_return,
  1448. PdmOidUnsignedRange* range_return)
  1449. {
  1450. const char* first_nonws_ptr;
  1451. const char* ptr;
  1452. /*
  1453. * skip leading whitespace
  1454. */
  1455. first_nonws_ptr = value_string + SpanWhitespace(value_string);
  1456. /*
  1457. * parse out the range sequence start
  1458. */
  1459. if(!ParseSeqStart(first_nonws_ptr, &ptr))
  1460. goto ParseUnsignedRange_error;
  1461. /*
  1462. * parse the lower bound
  1463. */
  1464. if(!ParseUnsignedValue(ptr, &ptr,
  1465. range_return ? &range_return->lower_bound : NULL))
  1466. goto ParseUnsignedRange_error;
  1467. /*
  1468. * parse the upper bound
  1469. */
  1470. if(!ParseUnsignedValue(ptr, &ptr,
  1471. range_return ? &range_return->upper_bound : NULL))
  1472. goto ParseUnsignedRange_error;
  1473. /*
  1474. * parse out the range sequence end
  1475. */
  1476. if(!ParseSeqEnd(ptr, &ptr))
  1477. goto ParseUnsignedRange_error;
  1478. /*
  1479. * update the return pointer
  1480. */
  1481. if(ptr_return != (const char**)NULL)
  1482. *ptr_return = ptr;
  1483. /*
  1484. * return
  1485. */
  1486. return True;
  1487. ParseUnsignedRange_error:
  1488. /*
  1489. * syntax error
  1490. */
  1491. if(ptr_return != (const char**)NULL)
  1492. *ptr_return = first_nonws_ptr;
  1493. return False;
  1494. }
  1495. /*
  1496. * ------------------------------------------------------------------------
  1497. * Name: PdmOidNotifyParse
  1498. *
  1499. * Description:
  1500. *
  1501. *
  1502. * Return value:
  1503. *
  1504. *
  1505. */
  1506. PdmOidNotify PdmOidNotifyParse(const char* value_string)
  1507. {
  1508. const char* ptr = value_string;
  1509. if(value_string == (const char*)NULL)
  1510. return PDMOID_NOTIFY_NONE;
  1511. /*
  1512. * look for an event handling profile sequence start
  1513. */
  1514. if(!ParseSeqStart(value_string, &ptr))
  1515. {
  1516. if('\0' == *ptr)
  1517. /*
  1518. * empty value is valid
  1519. */
  1520. return PDMOID_NOTIFY_NONE;
  1521. else
  1522. return PDMOID_NOTIFY_UNSUPPORTED;
  1523. }
  1524. /*
  1525. * look for an event set sequence start
  1526. */
  1527. if(!ParseSeqStart(ptr, &ptr))
  1528. {
  1529. /*
  1530. * check for an empty event handling profile
  1531. */
  1532. if(ParseSeqEnd(ptr, &ptr))
  1533. {
  1534. ptr += SpanWhitespace(ptr);
  1535. if(*ptr == '\0')
  1536. /*
  1537. * valid empty event handling profile sequence
  1538. */
  1539. return PDMOID_NOTIFY_NONE;
  1540. }
  1541. return PDMOID_NOTIFY_UNSUPPORTED;
  1542. }
  1543. /*
  1544. * the only event in the set should be report job completed
  1545. */
  1546. if(pdmoid_val_event_report_job_completed != PdmOidParse(ptr, &ptr))
  1547. return PDMOID_NOTIFY_UNSUPPORTED;
  1548. /*
  1549. * event set sequence end
  1550. */
  1551. if(!ParseSeqEnd(ptr, &ptr))
  1552. return PDMOID_NOTIFY_UNSUPPORTED;
  1553. /*
  1554. * delivery method of electronic mail
  1555. */
  1556. if(pdmoid_val_delivery_method_electronic_mail != PdmOidParse(ptr, &ptr))
  1557. return PDMOID_NOTIFY_UNSUPPORTED;
  1558. /*
  1559. * event handling profile sequence end
  1560. */
  1561. if(!ParseSeqEnd(ptr, &ptr))
  1562. return PDMOID_NOTIFY_UNSUPPORTED;
  1563. /*
  1564. * end of value
  1565. */
  1566. ptr += SpanWhitespace(ptr);
  1567. if('\0' == *ptr)
  1568. /*
  1569. * valid supported notification profile
  1570. */
  1571. return PDMOID_NOTIFY_EMAIL;
  1572. else
  1573. return PDMOID_NOTIFY_UNSUPPORTED;
  1574. }
  1575. /*
  1576. * ------------------------------------------------------------------------
  1577. * Name: PdmOidNotifyString
  1578. *
  1579. * Description:
  1580. *
  1581. *
  1582. * Return value:
  1583. *
  1584. *
  1585. */
  1586. const char* PdmOidNotifyString(PdmOidNotify notify)
  1587. {
  1588. switch(notify)
  1589. {
  1590. case PDMOID_NOTIFY_UNSUPPORTED:
  1591. return (const char*)NULL;
  1592. break;
  1593. case PDMOID_NOTIFY_NONE:
  1594. return NOTIFY_NONE_STR;
  1595. break;
  1596. case PDMOID_NOTIFY_EMAIL:
  1597. return NOTIFY_EMAIL_STR;
  1598. break;
  1599. }
  1600. }
  1601. /*
  1602. * ------------------------------------------------------------------------
  1603. * Name: PdmOidDocumentFormatParse
  1604. *
  1605. * Description:
  1606. *
  1607. *
  1608. * Return value:
  1609. *
  1610. *
  1611. */
  1612. char*
  1613. PdmOidDocumentFormatParse(const char* value_string)
  1614. {
  1615. char* document_format;
  1616. const char* ptr;
  1617. /*
  1618. * get the document format from the value string
  1619. */
  1620. document_format =
  1621. PdmOidDocumentFormatNext(value_string, &ptr);
  1622. if((char*)NULL != document_format)
  1623. {
  1624. /*
  1625. * verify that the document format is the only value specified
  1626. */
  1627. ptr += SpanWhitespace(ptr);
  1628. if('\0' == *ptr)
  1629. /*
  1630. * valid document-format value
  1631. */
  1632. return document_format;
  1633. else
  1634. /*
  1635. * invalid; clean up
  1636. */
  1637. XtFree(document_format);
  1638. }
  1639. return (char*)NULL;
  1640. }
  1641. /*
  1642. * ------------------------------------------------------------------------
  1643. * Name: PdmOidDocumentFormatDefault
  1644. *
  1645. * Description:
  1646. *
  1647. *
  1648. * Return value:
  1649. *
  1650. *
  1651. */
  1652. char*
  1653. PdmOidDocumentFormatDefault(const char* value_string)
  1654. {
  1655. /*
  1656. * return the first document format from the value string
  1657. */
  1658. return PdmOidDocumentFormatNext(value_string, (const char**)NULL);
  1659. }
  1660. /*
  1661. * ------------------------------------------------------------------------
  1662. * Name: PdmOidDocumentFormatNext
  1663. *
  1664. * Description:
  1665. *
  1666. *
  1667. * Return value:
  1668. *
  1669. *
  1670. */
  1671. static char*
  1672. PdmOidDocumentFormatNext(const char* value_string,
  1673. const char** ptr_return)
  1674. {
  1675. const char* ptr;
  1676. const char* first_nonws_ptr;
  1677. const char* document_format_start;
  1678. char* document_format;
  1679. int document_format_len;
  1680. int token_len;
  1681. if((const char*)NULL == value_string)
  1682. return (char*)NULL;
  1683. /*
  1684. * skip leading whitespace
  1685. */
  1686. ptr = value_string + SpanWhitespace(value_string);
  1687. first_nonws_ptr = ptr;
  1688. /*
  1689. * sequence start
  1690. */
  1691. if(!ParseSeqStart(ptr, &ptr))
  1692. goto PdmOidDocumentFormatNext_error;
  1693. /*
  1694. * skip whitepace to the start of the document format, and save the
  1695. * location
  1696. */
  1697. ptr += SpanWhitespace(ptr);
  1698. document_format_start = ptr;
  1699. /*
  1700. * document format
  1701. */
  1702. if(0 == (token_len = SpanToken(ptr)))
  1703. goto PdmOidDocumentFormatNext_error;
  1704. ptr += token_len;
  1705. /*
  1706. * optional variant
  1707. */
  1708. ptr += SpanWhitespace(ptr);
  1709. if(0 != (token_len = SpanToken(ptr)))
  1710. {
  1711. ptr += token_len;
  1712. /*
  1713. * optional version
  1714. */
  1715. ptr += SpanWhitespace(ptr);
  1716. ptr += SpanToken(ptr);
  1717. }
  1718. /*
  1719. * determine the length of the document format, excluding the
  1720. * sequence delimeters
  1721. */
  1722. document_format_len = ptr - document_format_start;
  1723. /*
  1724. * sequence end
  1725. */
  1726. if(!ParseSeqEnd(ptr, &ptr))
  1727. goto PdmOidDocumentFormatNext_error;
  1728. /*
  1729. * update return pointer
  1730. */
  1731. if((const char**)NULL != ptr_return)
  1732. *ptr_return = ptr;
  1733. /*
  1734. * build the return document format string, and return it
  1735. */
  1736. document_format = XtMalloc(document_format_len+1);
  1737. strncpy(document_format, document_format_start, document_format_len);
  1738. document_format[document_format_len] = '\0';
  1739. return document_format;
  1740. PdmOidDocumentFormatNext_error:
  1741. fprintf(stderr, "%s\n", PDM_MSG_WARN_DOC_FMT);
  1742. if((const char**)NULL != ptr_return)
  1743. *ptr_return = first_nonws_ptr;
  1744. return (char*)NULL;
  1745. }
  1746. /*
  1747. * ------------------------------------------------------------------------
  1748. * Name: ParseBooleanValue
  1749. *
  1750. * Description:
  1751. *
  1752. *
  1753. * Return value:
  1754. *
  1755. *
  1756. */
  1757. static Boolean
  1758. ParseBooleanValue(const char* value_string,
  1759. const char** ptr_return,
  1760. Boolean* boolean_return)
  1761. {
  1762. const char* ptr;
  1763. int length;
  1764. Boolean status;
  1765. /*
  1766. * skip leading whitespace
  1767. */
  1768. ptr = value_string + SpanWhitespace(value_string);
  1769. /*
  1770. * get the whitespace-delimited token length
  1771. */
  1772. length = SpanToken(ptr);
  1773. /*
  1774. * determine if true or false or bad
  1775. */
  1776. if(strncasecmp(ptr, "TRUE", length) == 0)
  1777. {
  1778. if(boolean_return != (Boolean*)NULL)
  1779. *boolean_return = True;
  1780. status = True;
  1781. }
  1782. else if(strncasecmp(ptr, "FALSE", length) == 0)
  1783. {
  1784. if(boolean_return != (Boolean*)NULL)
  1785. *boolean_return = False;
  1786. status = True;
  1787. }
  1788. else
  1789. {
  1790. /*
  1791. * syntax error
  1792. */
  1793. status = False;
  1794. }
  1795. /*
  1796. * update the return pointer and return
  1797. */
  1798. if(ptr_return != (const char**)NULL)
  1799. *ptr_return = status ? ptr+length : ptr;
  1800. return status;
  1801. }
  1802. /*
  1803. * ------------------------------------------------------------------------
  1804. * Name: ParseUnsignedValue
  1805. *
  1806. * Description:
  1807. *
  1808. * Skips leading whitespace and parses out and returns a unsigned number.
  1809. *
  1810. * Return value:
  1811. *
  1812. * True if a unsigned number was successfully parsed. ptr_return is
  1813. * updated to point to location where the unsigned number parsing
  1814. * ended.
  1815. *
  1816. * False if a unsigned number was not found; ptr_return is updated
  1817. * to point to the first non-whitespace char in value_string.
  1818. *
  1819. */
  1820. static Boolean
  1821. ParseUnsignedValue(const char* value_string,
  1822. const char** ptr_return,
  1823. unsigned long* unsigned_return)
  1824. {
  1825. unsigned long unsigned_value;
  1826. Boolean status;
  1827. const char* first_nonws_ptr;
  1828. const char* ptr;
  1829. /*
  1830. * skip leading whitespace
  1831. */
  1832. first_nonws_ptr = value_string + SpanWhitespace(value_string);
  1833. unsigned_value = strtoul(first_nonws_ptr, (char**)(&ptr), 0);
  1834. if(ptr == first_nonws_ptr)
  1835. status = False;
  1836. else
  1837. status = True;
  1838. /*
  1839. * update return parms
  1840. */
  1841. if(ptr_return != (const char**)NULL)
  1842. *ptr_return = ptr;
  1843. if(unsigned_return != (unsigned long*)NULL)
  1844. *unsigned_return = unsigned_value;
  1845. /*
  1846. * return
  1847. */
  1848. return status;
  1849. }
  1850. /*
  1851. * ------------------------------------------------------------------------
  1852. * Name: ParseRealValue
  1853. *
  1854. * Description:
  1855. *
  1856. * Skips leading whitespace and parses out and returns a real number.
  1857. *
  1858. * Return value:
  1859. *
  1860. * xTrue if a real number was successfully parsed. ptr_return is
  1861. * updated to point to location where the real number parsing
  1862. * ended.
  1863. *
  1864. * xFalse if a real number was not found; ptr_return is updated
  1865. * to point to the first non-whitespace char in value_string.
  1866. *
  1867. */
  1868. static Boolean
  1869. ParseRealValue(const char* value_string,
  1870. const char** ptr_return,
  1871. float* real_return)
  1872. {
  1873. float real_value;
  1874. Boolean status;
  1875. const char* first_nonws_ptr;
  1876. const char* ptr;
  1877. /*
  1878. * skip leading whitespace
  1879. */
  1880. first_nonws_ptr = value_string + SpanWhitespace(value_string);
  1881. real_value = (float)strtod(first_nonws_ptr, (char**)(&ptr));
  1882. if(ptr == first_nonws_ptr)
  1883. status = False;
  1884. else
  1885. status = True;
  1886. /*
  1887. * update return parms
  1888. */
  1889. if(ptr_return != (const char**)NULL)
  1890. *ptr_return = ptr;
  1891. if(real_return != (float*)NULL)
  1892. *real_return = real_value;
  1893. /*
  1894. * return
  1895. */
  1896. return status;
  1897. }
  1898. /*
  1899. * ------------------------------------------------------------------------
  1900. * Name: ParseSeqEnd
  1901. *
  1902. * Description:
  1903. *
  1904. * Description:
  1905. *
  1906. * Skips leading whitespace and parses out the sequence end
  1907. * character '}'.
  1908. *
  1909. * Return value:
  1910. *
  1911. * True if the sequence end character was parsed; ptr_return is
  1912. * updated to point to the first char following the sequence end
  1913. * character.
  1914. *
  1915. * False if the sequence end character was not found; ptr_return is
  1916. * updated to point to the first non-whitespace char in value_string.
  1917. *
  1918. */
  1919. static Boolean
  1920. ParseSeqEnd(const char* value_string,
  1921. const char** ptr_return)
  1922. {
  1923. const char* ptr;
  1924. Boolean status;
  1925. /*
  1926. * skip leading whitespace
  1927. */
  1928. ptr = value_string + SpanWhitespace(value_string);
  1929. /*
  1930. * parse out the sequence end character
  1931. */
  1932. if(*ptr == '}')
  1933. {
  1934. status = True;
  1935. ++ptr;
  1936. }
  1937. else
  1938. status = False;
  1939. /*
  1940. * update the return pointer
  1941. */
  1942. if(ptr_return != (const char**)NULL)
  1943. *ptr_return = ptr;
  1944. /*
  1945. * return
  1946. */
  1947. return status;
  1948. }
  1949. /*
  1950. * ------------------------------------------------------------------------
  1951. * Name: ParseSeqStart
  1952. *
  1953. * Description:
  1954. *
  1955. * Skips leading whitespace and parses out the sequence start
  1956. * character '{'.
  1957. *
  1958. * Return value:
  1959. *
  1960. * True if the sequence start character was parsed; ptr_return is
  1961. * updated to point to the first char following the sequence start
  1962. * character.
  1963. *
  1964. * False if the sequence start character was not found; ptr_return is
  1965. * updated to point to the first non-whitespace char in value_string.
  1966. *
  1967. */
  1968. static Boolean
  1969. ParseSeqStart(const char* value_string,
  1970. const char** ptr_return)
  1971. {
  1972. const char* ptr;
  1973. Boolean status;
  1974. /*
  1975. * skip leading whitespace
  1976. */
  1977. ptr = value_string + SpanWhitespace(value_string);
  1978. /*
  1979. * parse out the sequence start character
  1980. */
  1981. if(*ptr == '{')
  1982. {
  1983. status = True;
  1984. ++ptr;
  1985. }
  1986. else
  1987. status = False;
  1988. /*
  1989. * update the return pointer
  1990. */
  1991. if(ptr_return != (const char**)NULL)
  1992. *ptr_return = ptr;
  1993. /*
  1994. * return
  1995. */
  1996. return status;
  1997. }
  1998. /*
  1999. * ------------------------------------------------------------------------
  2000. * Name: ParseUnspecifiedValue
  2001. *
  2002. * Description:
  2003. *
  2004. * Skips leading whitespace and parses out an unspecified optional
  2005. * value (i.e. matching '' or "" - skips all data between the set of
  2006. * quotes).
  2007. *
  2008. * Return value:
  2009. *
  2010. * True if an unspecified value was parsed; ptr_return is updated to
  2011. * point to the first char following the trailing quote.
  2012. *
  2013. * False if an unspecified value was not found; ptr_return is updated
  2014. * to point to the first non-whitespace char in value_string.
  2015. *
  2016. */
  2017. static Boolean
  2018. ParseUnspecifiedValue(const char* value_string,
  2019. const char** ptr_return)
  2020. {
  2021. Boolean status;
  2022. const char* ptr;
  2023. /*
  2024. * skip leading whitespace
  2025. */
  2026. ptr = value_string + SpanWhitespace(value_string);
  2027. /*
  2028. * parse out an unspecified optional value ('' or "")
  2029. */
  2030. if(*ptr == '\'' || *ptr == '"')
  2031. {
  2032. char delim[2];
  2033. if(ptr_return != (const char**)NULL)
  2034. {
  2035. delim[0] = *ptr;
  2036. delim[1] = '\0';
  2037. /*
  2038. * skip over the matching delimiter
  2039. */
  2040. ++ptr;
  2041. ptr += strcspn(ptr, delim);
  2042. if(*ptr != '\0')
  2043. ++ptr;
  2044. }
  2045. status = True;
  2046. }
  2047. else
  2048. status = False;
  2049. /*
  2050. * update the return pointer
  2051. */
  2052. if(ptr_return != (const char**)NULL)
  2053. *ptr_return = ptr;
  2054. /*
  2055. * return
  2056. */
  2057. return status;
  2058. }
  2059. /*
  2060. * ------------------------------------------------------------------------
  2061. * Name: SpanToken
  2062. *
  2063. * Description:
  2064. *
  2065. * Returns the length of the initial segment of the passed string
  2066. * that consists entirely of non-whitespace and non-sequence
  2067. * delimiter characters.
  2068. *
  2069. *
  2070. */
  2071. static int
  2072. SpanToken(const char* string)
  2073. {
  2074. const char* ptr;
  2075. for(ptr = string;
  2076. *ptr != '\0' && !DtIsspace((char*)ptr) && *ptr != '{' && *ptr != '}';
  2077. ptr = DtNextChar((char*)ptr));
  2078. return ptr - string;
  2079. }
  2080. /*
  2081. * ------------------------------------------------------------------------
  2082. * Name: SpanWhitespace
  2083. *
  2084. * Description:
  2085. *
  2086. * Returns the length of the initial segment of the passed string
  2087. * that consists entirely of whitespace characters.
  2088. *
  2089. *
  2090. */
  2091. static int
  2092. SpanWhitespace(const char* string)
  2093. {
  2094. const char* ptr;
  2095. for(ptr = string;
  2096. *ptr != '\0' && DtIsspace((char*)ptr);
  2097. ptr = DtNextChar((char*)ptr));
  2098. return ptr - string;
  2099. }