AccessSDL.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454
  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 librararies 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. /* $XConsortium: AccessSDL.c /main/13 1996/09/30 11:22:14 cde-hp $ */
  24. /************************************<+>*************************************
  25. ****************************************************************************
  26. **
  27. ** File: AccessSDL.c
  28. **
  29. ** Project: Run Time Project File Access
  30. **
  31. ** Description: This body of code handles the access routines for the
  32. ** SDL files.
  33. **
  34. **
  35. ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
  36. **
  37. ** (c) Copyright 1993, 1994 Hewlett-Packard Company
  38. ** (c) Copyright 1993, 1994 International Business Machines Corp.
  39. ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
  40. ** (c) Copyright 1993, 1994 Novell, Inc.
  41. **
  42. **
  43. ****************************************************************************
  44. ************************************<+>*************************************/
  45. /*
  46. * system includes
  47. */
  48. #include <stdlib.h>
  49. #include <stdio.h>
  50. #include <string.h>
  51. #include <X11/Xlib.h>
  52. #include <X11/Xresource.h>
  53. /*
  54. * Canvas Engine includes
  55. */
  56. #include "CanvasP.h"
  57. #include "CanvasSegP.h"
  58. /*
  59. * private includes
  60. */
  61. #include "bufioI.h"
  62. #include "CleanUpI.h"
  63. #include "CvStringI.h"
  64. #include "FontAttrI.h"
  65. #include "Access.h"
  66. #include "AccessP.h"
  67. #include "AccessSDLP.h"
  68. #include "AccessSDLI.h"
  69. #include "FormatUtilI.h"
  70. #include "FormatSDLI.h"
  71. #include "StringFuncsI.h"
  72. #include "UtilSDLI.h"
  73. #ifdef NLS16
  74. #endif
  75. /******** Private Defines ********/
  76. /******** End Private Defines ********/
  77. /******** Private Function Declarations ********/
  78. static int ProcessEntry (
  79. _DtHelpVolume vol,
  80. _DtCvSegment *p_seg,
  81. char *parent_key);
  82. /******** End Private Function Declarations ********/
  83. /******** Private Variable Declarations ********/
  84. static const char *IsoString = "ISO-8859-1";
  85. static const CESDLVolume DefaultSdlVolume =
  86. {
  87. NULL, /* _DtCvSegment *sdl_info; */
  88. NULL, /* _DtCvSegment *toss; */
  89. NULL, /* _DtCvSegment *loids; */
  90. NULL, /* _DtCvSegment *index; */
  91. NULL, /* _DtCvSegment *title; */
  92. NULL, /* _DtCvSegment *snb; */
  93. 0, /* short minor_no; */
  94. False, /* short title_processed; */
  95. };
  96. /******** Private Macro Declarations ********/
  97. /******************************************************************************
  98. * Private Functions
  99. ******************************************************************************/
  100. /******************************************************************************
  101. * Function: void FreeIds (
  102. *
  103. * Parameters:
  104. *
  105. * Return Value:
  106. *
  107. * errno Values:
  108. *
  109. * Purpose:
  110. *
  111. ******************************************************************************/
  112. static void
  113. FreeIds (
  114. _DtCvSegment *loids)
  115. {
  116. _DtCvSegment *p_seg;
  117. if (NULL == loids)
  118. return;
  119. p_seg = _DtCvContainerListOfSeg(loids);
  120. while (NULL != p_seg)
  121. {
  122. if (NULL != _SdlSegToSdlIdInfoPtr(p_seg))
  123. {
  124. if (NULL != _SdlSegToSdlIdInfoRssi(p_seg))
  125. free(_SdlSegToSdlIdInfoRssi(p_seg));
  126. free(_SdlSegToSdlIdInfoPtr(p_seg));
  127. }
  128. p_seg = p_seg->next_seg;
  129. }
  130. }
  131. /******************************************************************************
  132. * Function: void FreeTossInfo (
  133. *
  134. * Parameters:
  135. *
  136. * Return Value:
  137. *
  138. * errno Values:
  139. *
  140. * Purpose:
  141. *
  142. ******************************************************************************/
  143. static void
  144. FreeTossInfo (
  145. _DtCvSegment *toss)
  146. {
  147. _DtCvSegment *p_seg;
  148. SDLTossInfo *info;
  149. if (NULL == toss)
  150. return;
  151. p_seg = _DtCvContainerListOfSeg(toss);
  152. while (NULL != p_seg)
  153. {
  154. info = (SDLTossInfo *) _SdlSegTossInfo(p_seg);
  155. /* free the ssi */
  156. if (NULL != _SdlTossInfoPtrSsi(info))
  157. free(_SdlTossInfoPtrSsi(info));
  158. /* free the colj,colw or the enter, exit data */
  159. if (NULL != _SdlTossInfoPtrStr1(info))
  160. free(_SdlTossInfoPtrStr1(info));
  161. if (NULL != _SdlTossInfoPtrStr2(info))
  162. free(_SdlTossInfoPtrStr2(info));
  163. /* free the font strings */
  164. if (NULL != _DtHelpFontHintsColor(_SdlTossInfoPtrFontSpecs(info)))
  165. free(_DtHelpFontHintsColor(_SdlTossInfoPtrFontSpecs(info)));
  166. if (NULL != _DtHelpFontHintsXlfd(_SdlTossInfoPtrFontSpecs(info)))
  167. free(_DtHelpFontHintsXlfd(_SdlTossInfoPtrFontSpecs(info)));
  168. if (NULL != _DtHelpFontHintsXlfdb(_SdlTossInfoPtrFontSpecs(info)))
  169. free(_DtHelpFontHintsXlfdb(_SdlTossInfoPtrFontSpecs(info)));
  170. if (NULL != _DtHelpFontHintsXlfdi(_SdlTossInfoPtrFontSpecs(info)))
  171. free(_DtHelpFontHintsXlfdi(_SdlTossInfoPtrFontSpecs(info)));
  172. if (NULL != _DtHelpFontHintsXlfdib(_SdlTossInfoPtrFontSpecs(info)))
  173. free(_DtHelpFontHintsXlfdib(_SdlTossInfoPtrFontSpecs(info)));
  174. if (NULL != _DtHelpFontHintsTypeNam(_SdlTossInfoPtrFontSpecs(info)))
  175. free(_DtHelpFontHintsTypeNam(_SdlTossInfoPtrFontSpecs(info)));
  176. if (NULL != _DtHelpFontHintsTypeNamb(_SdlTossInfoPtrFontSpecs(info)))
  177. free(_DtHelpFontHintsTypeNamb(_SdlTossInfoPtrFontSpecs(info)));
  178. if (NULL != _DtHelpFontHintsTypeNami(_SdlTossInfoPtrFontSpecs(info)))
  179. free(_DtHelpFontHintsTypeNami(_SdlTossInfoPtrFontSpecs(info)));
  180. if (NULL != _DtHelpFontHintsTypeNamib(_SdlTossInfoPtrFontSpecs(info)))
  181. free(_DtHelpFontHintsTypeNamib(_SdlTossInfoPtrFontSpecs(info)));
  182. free(info);
  183. p_seg = p_seg->next_seg;
  184. }
  185. }
  186. /******************************************************************************
  187. * Function: void FreeEntryInfo (
  188. *
  189. * Parameters:
  190. *
  191. * Return Value:
  192. *
  193. * errno Values:
  194. *
  195. * Purpose:
  196. *
  197. ******************************************************************************/
  198. static void
  199. FreeEntryInfo (
  200. _DtCvSegment *index)
  201. {
  202. _DtCvSegment *p_seg;
  203. SDLEntryInfo *info;
  204. if (NULL == index)
  205. return;
  206. p_seg = _DtCvContainerListOfSeg(index);
  207. while (NULL != p_seg)
  208. {
  209. info = _SdlSegToSdlEntryInfo(p_seg);
  210. if (NULL != info)
  211. {
  212. if (NULL != info->main)
  213. free(info->main);
  214. if (NULL != info->locs)
  215. free(info->locs);
  216. if (NULL != info->syns)
  217. free(info->syns);
  218. if (NULL != info->sort)
  219. free(info->sort);
  220. }
  221. if (_DtCvIsSegContainer(p_seg))
  222. FreeEntryInfo(p_seg);
  223. free(info);
  224. p_seg = p_seg->next_seg;
  225. }
  226. }
  227. /******************************************************************************
  228. * Function: int ProcessSubEntries (
  229. *
  230. * Parameters:
  231. *
  232. * Return Value:
  233. *
  234. * errno Values:
  235. *
  236. * Purpose:
  237. *
  238. ******************************************************************************/
  239. static int
  240. ProcessSubEntries (
  241. _DtHelpVolume vol,
  242. _DtCvSegment *p_seg,
  243. char *parent_key)
  244. {
  245. while (p_seg != NULL)
  246. {
  247. /*
  248. * the only sub containers of an entry that should have an non-null
  249. * internal pointer should be a sub <entry>.
  250. */
  251. if (_DtCvIsSegContainer(p_seg) && NULL != _SdlSegEntryInfo(p_seg)
  252. && ProcessEntry(vol, _DtCvContainerListOfSeg(p_seg),
  253. parent_key) == -1)
  254. return -1;
  255. p_seg = p_seg->next_seg;
  256. }
  257. return 0;
  258. }
  259. /******************************************************************************
  260. * Function: int AsciiKeyword (
  261. *
  262. * Parameters:
  263. * p_list The segment list to process for strings.
  264. * parent_str The string to append information onto.
  265. * This may be NULL.
  266. * str_size The malloc'ed size of the parent string.
  267. * Includes room for the null byte. If zero
  268. * and parent_str is non-null, then memory
  269. * must be malloc'ed and parent_str copied
  270. * into it. Otherwise, goodStr can just
  271. * reuse parent_str.
  272. *
  273. * Return Value:
  274. *
  275. * errno Values:
  276. *
  277. * Purpose:
  278. *
  279. ******************************************************************************/
  280. static char *
  281. AsciiKeyword (
  282. _DtCvSegment *p_list,
  283. char *parent_str,
  284. int *str_size)
  285. {
  286. int len = 0;
  287. int newLen;
  288. char *goodStr;
  289. /*
  290. * if a starting string has been passed in, use it.
  291. */
  292. if (NULL != parent_str)
  293. {
  294. /*
  295. * get the actual byte count.
  296. */
  297. len = strlen(parent_str) + 1;
  298. /*
  299. * is the starting value zero? If so, we have to copy it.
  300. */
  301. if (0 == *str_size)
  302. {
  303. parent_str = strdup(parent_str);
  304. if (NULL == parent_str)
  305. return NULL;
  306. *str_size = len;
  307. }
  308. }
  309. /*
  310. * start with the parent_string
  311. */
  312. goodStr = parent_str;
  313. while (p_list != NULL)
  314. {
  315. if (_DtCvIsSegString(p_list))
  316. {
  317. /*
  318. * get the number of characters in the next string.
  319. */
  320. newLen = _DtCvStrLen(_DtCvStringOfStringSeg(p_list),
  321. _DtCvIsSegWideChar(p_list));
  322. /*
  323. * if this is wide char string, multiply the count by
  324. * MB_CUR_MAX to get the maximum number of bytes this
  325. * string would take.
  326. */
  327. if (_DtCvIsSegWideChar(p_list))
  328. newLen = newLen * MB_CUR_MAX;
  329. /*
  330. * now add it to our previous size.
  331. */
  332. len += newLen;
  333. /*
  334. * are we starting from scratch?
  335. */
  336. if (goodStr == NULL)
  337. {
  338. /*
  339. * include a byte for the end-of-string character.
  340. */
  341. len++;
  342. /*
  343. * malloc the memory
  344. */
  345. goodStr = (char *) malloc (len);
  346. }
  347. else if (*str_size < len) /* does this have to grow? */
  348. goodStr = (char *) realloc (goodStr, len);
  349. if (goodStr == NULL)
  350. return NULL;
  351. /*
  352. * remember the absolute size of the memory for the string
  353. */
  354. if (*str_size < len)
  355. *str_size = len;
  356. if (_DtCvIsSegWideChar(p_list))
  357. {
  358. /*
  359. * back up to the insertion point.
  360. */
  361. len -= newLen;
  362. /*
  363. * transfer
  364. */
  365. newLen = wcstombs(&goodStr[len - 1],
  366. (wchar_t *) _DtCvStringOfStringSeg(p_list),
  367. newLen + 1);
  368. if ((size_t) -1 == newLen)
  369. return NULL;
  370. len += newLen;
  371. }
  372. else
  373. strcpy(&goodStr[len - newLen - 1],
  374. (char *) _DtCvStringOfStringSeg(p_list));
  375. }
  376. /*
  377. * the only containers in an <entry> that should have a non-null
  378. * internal pointer should be a sub <entry>. Therefore, if null,
  379. * process since it could be a <key>, <sphrase>, etc.
  380. */
  381. else if (_DtCvIsSegContainer(p_list) &&
  382. NULL == _SdlSegEntryInfo(p_list))
  383. {
  384. goodStr = AsciiKeyword(_DtCvContainerListOfSeg(p_list), goodStr,
  385. str_size);
  386. if (goodStr == NULL)
  387. return NULL;
  388. len = strlen(goodStr) + 1;
  389. }
  390. p_list = p_list->next_seg;
  391. }
  392. return goodStr;
  393. }
  394. /******************************************************************************
  395. * Function: int ProcessLocations (
  396. *
  397. * Parameters:
  398. *
  399. * Return Value:
  400. *
  401. * errno Values:
  402. *
  403. * Purpose:
  404. *
  405. ******************************************************************************/
  406. static int
  407. ProcessLocations (
  408. char *locs,
  409. char ***list)
  410. {
  411. char **myList = NULL;
  412. char *nextLoc;
  413. while (locs != NULL && *locs != '\0')
  414. {
  415. locs = _DtHelpGetNxtToken(locs, &nextLoc);
  416. if (nextLoc == NULL)
  417. return -1;
  418. if (*nextLoc != '\0')
  419. {
  420. myList = (char **) _DtHelpCeAddPtrToArray ((void **) myList,
  421. (void *) nextLoc);
  422. if (myList == NULL)
  423. return -1;
  424. }
  425. }
  426. *list = myList;
  427. return 0;
  428. }
  429. /******************************************************************************
  430. * Function: int ProcessEntry (_DtHelpVolume vol)
  431. *
  432. * Parameters: vol Specifies the volume whose keywords need to be
  433. * loaded from disk. Once loaded, they can be
  434. * accessed through the fields of the volume structure.
  435. *
  436. * Return Value: 0 if successful, -1 if a failure occurs
  437. *
  438. * errno Values: CEErrorMalloc
  439. * CEErrorIllegalDatabaseFile
  440. * Specifies that the keyword file is
  441. * invalid or corrupt.
  442. * CEErrorMissingKeywordsRes
  443. * Specifies that the keyword file does
  444. * not contain the 'Keywords/keywords'
  445. * resource or the resource is NULL
  446. *
  447. *
  448. * Purpose: Load the keywords associated with a volume.
  449. *
  450. ******************************************************************************/
  451. static int
  452. ProcessEntry (
  453. _DtHelpVolume vol,
  454. _DtCvSegment *p_seg,
  455. char *parent_key)
  456. {
  457. int strSize;
  458. char **topics;
  459. char *nextKey = NULL;
  460. /* Now parse the string into the appropriate arrays. The string has the
  461. following syntax:
  462. <!ELEMENT entry - - ((%simple; | #PCDATA)*, entry*) >
  463. <!ATTLIST entry id ID #IMPLIED
  464. main IDREFS #IMPLIED
  465. locs IDREFS #IMPLIED
  466. syns IDREFS #IMPLIED
  467. sort CDATA #IMPLIED >
  468. */
  469. #define MAIN_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->main
  470. #define LOCS_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->locs
  471. while (p_seg != NULL)
  472. {
  473. strSize = 0;
  474. nextKey = AsciiKeyword(_DtCvContainerListOfSeg(p_seg),
  475. parent_key, &strSize);
  476. if (nextKey == NULL)
  477. return -1;
  478. /* We have the next keyword. Hang onto it and add it to the list
  479. once we get the array of topics. We don't add it yet because if
  480. there are no topics we want to throw it away. (Silently ignoring
  481. keywords which specify no topics is an undocumented feature.) */
  482. /* Now get the list of topics. */
  483. topics = NULL;
  484. if (NULL != FrmtPrivInfoPtr(p_seg) && NULL != _SdlSegEntryInfo(p_seg)
  485. && (ProcessLocations(MAIN_STRINGS, &topics) == -1 ||
  486. ProcessLocations(LOCS_STRINGS, &topics) == -1))
  487. {
  488. free(nextKey);
  489. return -1;
  490. }
  491. if (topics != NULL)
  492. {
  493. vol->keywords = (char **) _DtHelpCeAddPtrToArray (
  494. (void **) vol->keywords,
  495. (void *) nextKey);
  496. vol->keywordTopics = (char ***) _DtHelpCeAddPtrToArray (
  497. (void **) vol->keywordTopics,
  498. (void *) topics);
  499. /*
  500. * If we just malloc'ed ourselves out of existance...
  501. * stop here.
  502. */
  503. if (vol->keywords == 0 || vol->keywordTopics == 0)
  504. {
  505. if (vol->keywords != NULL)
  506. {
  507. free(nextKey);
  508. _DtHelpCeFreeStringArray (vol->keywords);
  509. _DtHelpCeFreeStringArray (topics);
  510. vol->keywords = NULL;
  511. }
  512. if (vol->keywordTopics)
  513. {
  514. char ***topicList;
  515. for (topicList = vol->keywordTopics; topicList; topicList++)
  516. _DtHelpCeFreeStringArray (*topicList);
  517. free (vol->keywordTopics);
  518. vol->keywordTopics = NULL;
  519. }
  520. return -1;
  521. }
  522. }
  523. if (_DtCvContainerListOfSeg(p_seg) != NULL &&
  524. ProcessSubEntries(vol,_DtCvContainerListOfSeg(p_seg),nextKey) == -1)
  525. return -1;
  526. if (topics == NULL)
  527. free (nextKey);
  528. p_seg = p_seg->next_seg;
  529. }
  530. return (0);
  531. }
  532. /******************************************************************************
  533. * Function: int MapPath (_DtCvSegment *cur_id, int level, char ***ret_ids)
  534. *
  535. * Parameters:
  536. *
  537. * Return Value: 0 if successful, -1 if failure.
  538. *
  539. * Memory: The memory returned in ret_ids is owned by the caller.
  540. *
  541. * Purpose: To come up with a path from the top of the volume to the
  542. * target id.
  543. *
  544. ******************************************************************************/
  545. static int
  546. MapPath (
  547. _DtCvSegment **cur_id,
  548. _DtCvSegment *target_el,
  549. int stop_lev,
  550. int lev_cnt,
  551. int hidden_no,
  552. char ***ret_ids)
  553. {
  554. _DtCvSegment *mySeg = *cur_id;
  555. int count = -1;
  556. int myLev;
  557. SDLIdInfo *info;
  558. while (mySeg != NULL)
  559. {
  560. /*
  561. * Does this match the target id?
  562. * And, is the element a child of the current path?
  563. */
  564. info = _SdlSegToSdlIdInfoPtr(mySeg);
  565. myLev = _SdlIdInfoPtrRlevel(info);
  566. if (target_el == mySeg && (myLev == -1 || myLev > stop_lev))
  567. {
  568. /*
  569. * matched the target id.
  570. * allocate memory and return.
  571. */
  572. count = 0;
  573. if (_SdlIdInfoPtrType(info) == SdlIdVirpage)
  574. {
  575. count++;
  576. lev_cnt++;
  577. }
  578. *ret_ids = (char **) malloc (sizeof(char *) * (lev_cnt + 1));
  579. if ((*ret_ids) == NULL)
  580. return -1;
  581. (*ret_ids)[lev_cnt] = NULL;
  582. if (_SdlIdInfoPtrType(info) == SdlIdVirpage)
  583. (*ret_ids)[lev_cnt - 1] = strdup(_DtCvContainerIdOfSeg(mySeg));
  584. return count;
  585. }
  586. else if (myLev != -1 && myLev != hidden_no
  587. && _SdlIdInfoPtrType(info) == SdlIdVirpage)
  588. {
  589. char *myId = _DtCvContainerIdOfSeg(mySeg);
  590. /*
  591. * If we've hit a virpage that is a sibling or an aunt
  592. * set the search pointer to this segment (since this
  593. * is where we want to start searching again) and return
  594. * a negative on the successful search.
  595. */
  596. if (myLev <= stop_lev)
  597. {
  598. *cur_id = mySeg;
  599. return -1;
  600. }
  601. /*
  602. * this virpage is a child of mine, so look at it's children
  603. * for the target id.
  604. */
  605. mySeg = mySeg->next_seg;
  606. count = MapPath(&mySeg, target_el, myLev, lev_cnt + 1, hidden_no,
  607. ret_ids);
  608. /*
  609. * successful response on finding the target id in the virpage's
  610. * children. Duplicate the virpage's id string and return to
  611. * my parent.
  612. */
  613. if (count != -1)
  614. {
  615. (*ret_ids)[lev_cnt] = strdup(myId);
  616. count++;
  617. return count;
  618. }
  619. }
  620. else /* did not match the target id and is not a virpage
  621. * or is a hidden virpage */
  622. mySeg = mySeg->next_seg;
  623. }
  624. *cur_id = mySeg;
  625. return -1;
  626. }
  627. /******************************************************************************
  628. * Semi-Private Functions
  629. ******************************************************************************/
  630. /*******************************************************************************
  631. * Function: CESDLVolume *_DtHelpCeGetSdlVolumePtr (_DtHelpVolumeHdl vol);
  632. *
  633. * Parameters: vol Specifies the loaded volume.
  634. *
  635. * Return Value: 0 if successful, -1 if a failure occurs
  636. *
  637. * errno Values: None
  638. *
  639. * Purpose: When the volume is no longer needed, it should be unloaded
  640. * with this call. Unloading it frees the memory (which means
  641. * any handles on the volume become invalid.)
  642. *
  643. ******************************************************************************/
  644. CESDLVolume *
  645. _DtHelpCeGetSdlVolumePtr (
  646. _DtHelpVolumeHdl volume)
  647. {
  648. _DtHelpVolume vol = (_DtHelpVolume) volume;
  649. if (vol != NULL)
  650. return ((CESDLVolume *) vol->vols.sdl_vol);
  651. return NULL;
  652. }
  653. /******************************************************************************
  654. * Semi-Public Functions
  655. ******************************************************************************/
  656. /*******************************************************************************
  657. * Function: void _DtHelpCeInitSdlVolume (_DtHelpVolume vol);
  658. *
  659. * Parameters: vol Specifies the loaded volume.
  660. *
  661. * Return Value: 0 if successful, -1 if a failure occurs
  662. *
  663. * errno Values: None
  664. *
  665. * Purpose: When the volume is no longer needed, it should be unloaded
  666. * with this call. Unloading it frees the memory (which means
  667. * any handles on the volume become invalid.)
  668. *
  669. ******************************************************************************/
  670. void
  671. _DtHelpCeInitSdlVolume (
  672. _DtHelpVolumeHdl volume)
  673. {
  674. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  675. if (sdlVol != NULL)
  676. *sdlVol = DefaultSdlVolume;
  677. }
  678. /*******************************************************************************
  679. * Function: void _DtHelpCeOpenSdlVolume (_DtHelpVolume vol);
  680. *
  681. * Parameters: vol Specifies the loaded volume.
  682. *
  683. * Return Value: 0 if successful, -1 if a failure occurs
  684. *
  685. * errno Values: None
  686. *
  687. * Purpose: When the volume is no longer needed, it should be unloaded
  688. * with this call. Unloading it frees the memory (which means
  689. * any handles on the volume become invalid.)
  690. *
  691. ******************************************************************************/
  692. int
  693. _DtHelpCeOpenSdlVolume (
  694. _DtHelpVolumeHdl volume)
  695. {
  696. CESDLVolume *sdlVol;
  697. _DtHelpVolume vol = (_DtHelpVolume) volume;
  698. sdlVol = (CESDLVolume *) calloc (1, sizeof(CESDLVolume));
  699. if (sdlVol != NULL)
  700. {
  701. vol->vols.sdl_vol = (SdlVolumeHandle) sdlVol;
  702. _DtHelpCeInitSdlVolume(volume);
  703. if (_DtHelpCeFrmtSdlVolumeInfo(vol->volFile,
  704. vol, &(vol->check_time)) == 0)
  705. {
  706. vol->sdl_flag = True;
  707. return 0;
  708. }
  709. vol->vols.sdl_vol = NULL;
  710. free(sdlVol);
  711. }
  712. return -1;
  713. }
  714. /*******************************************************************************
  715. * Function: void _DtHelpCeCleanSdlVolume (_DtHelpVolume vol);
  716. *
  717. * Parameters: vol Specifies the loaded volume.
  718. *
  719. * Return Value: 0 if successful, -1 if a failure occurs
  720. *
  721. * errno Values: None
  722. *
  723. * Purpose: When the volume is no longer needed, it should be unloaded
  724. * with this call. Unloading it frees the memory (which means
  725. * any handles on the volume become invalid.)
  726. *
  727. ******************************************************************************/
  728. void
  729. _DtHelpCeCleanSdlVolume (
  730. _DtHelpVolumeHdl volume)
  731. {
  732. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  733. if (sdlVol != NULL)
  734. {
  735. _DtHelpFreeSegments(sdlVol->snb , _DtCvFALSE, sdlVol->destroy_region,
  736. sdlVol->client_data);
  737. _DtHelpFreeSegments(sdlVol->title, _DtCvFALSE, sdlVol->destroy_region,
  738. sdlVol->client_data);
  739. /*
  740. * free the index information
  741. */
  742. FreeEntryInfo(sdlVol->index);
  743. _DtHelpFreeSegments(sdlVol->index, _DtCvFALSE, NULL, NULL);
  744. /*
  745. * free the toss information.
  746. */
  747. FreeTossInfo(sdlVol->toss);
  748. _DtHelpFreeSegments(sdlVol->toss , _DtCvFALSE, NULL, NULL);
  749. /*
  750. * free the ids
  751. */
  752. FreeIds(sdlVol->loids);
  753. _DtHelpFreeSegments(sdlVol->loids, _DtCvFALSE, NULL, NULL);
  754. /*
  755. * free the document information.
  756. */
  757. if (NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
  758. free(_SdlDocInfoPtrLanguage(sdlVol->sdl_info));
  759. if (NULL != _SdlDocInfoPtrCharSet(sdlVol->sdl_info))
  760. free(_SdlDocInfoPtrCharSet(sdlVol->sdl_info));
  761. if (NULL != _SdlDocInfoPtrDocId(sdlVol->sdl_info))
  762. free(_SdlDocInfoPtrDocId(sdlVol->sdl_info));
  763. if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info))
  764. free(_SdlDocInfoPtrFirstPg(sdlVol->sdl_info));
  765. if (NULL != _SdlDocInfoPtrSdlDtd(sdlVol->sdl_info))
  766. free(_SdlDocInfoPtrSdlDtd(sdlVol->sdl_info));
  767. if (NULL != _SdlDocInfoPtrStamp(sdlVol->sdl_info))
  768. free(_SdlDocInfoPtrStamp(sdlVol->sdl_info));
  769. free(sdlVol->sdl_info);
  770. }
  771. }
  772. /*******************************************************************************
  773. * Function: int _DtHelpCeRereadSdlVolume (_DtHelpVolume vol);
  774. *
  775. * Parameters: vol Specifies the loaded volume.
  776. *
  777. * Return Value: 0 if successful, -1 if a failure occurs
  778. *
  779. * errno Values: None
  780. *
  781. * Purpose: When the volume is no longer needed, it should be unloaded
  782. * with this call. Unloading it frees the memory (which means
  783. * any handles on the volume become invalid.)
  784. *
  785. ******************************************************************************/
  786. int
  787. _DtHelpCeRereadSdlVolume (
  788. _DtHelpVolumeHdl volume)
  789. {
  790. _DtHelpCeCleanSdlVolume(volume);
  791. _DtHelpCeInitSdlVolume(volume);
  792. if (_DtHelpCeFrmtSdlVolumeInfo(_DtHelpCeGetVolumeName(volume),
  793. volume, NULL) == 0)
  794. return 0;
  795. return -1;
  796. }
  797. /*******************************************************************************
  798. * Function: void _DtHelpCeCloseSdlVolume (_DtHelpVolume vol);
  799. *
  800. * Parameters: vol Specifies the loaded volume.
  801. *
  802. * Return Value: 0 if successful, -1 if a failure occurs
  803. *
  804. * errno Values: None
  805. *
  806. * Purpose: When the volume is no longer needed, it should be unloaded
  807. * with this call. Unloading it frees the memory (which means
  808. * any handles on the volume become invalid.)
  809. *
  810. ******************************************************************************/
  811. void
  812. _DtHelpCeCloseSdlVolume (
  813. _DtHelpVolumeHdl volume)
  814. {
  815. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  816. if (sdlVol != NULL)
  817. {
  818. _DtHelpCeCleanSdlVolume(volume);
  819. free(sdlVol);
  820. }
  821. }
  822. /*****************************************************************************
  823. * Function: Boolean _DtHelpCeGetSdlHomeTopicId (_DtHelpVolume vol,
  824. * char *target_id,
  825. * char *ret_name, int *ret_offset)
  826. *
  827. * Parameters: vol Specifies the loaded volume
  828. * target_id Specifies target location ID
  829. * ret_name Returns a null terminated string
  830. * containing a fully qualified path to
  831. * the file that contains 'target_id'.
  832. * ret_offset Returns the offset into 'ret_name'
  833. * to the topic that contains 'target_id'.
  834. *
  835. * Memory own by caller:
  836. * ret_name
  837. *
  838. * Returns: True if successful, False if a failure occurs
  839. *
  840. * errno Values: EINVAL Specifies an invalid parameter was
  841. * used.
  842. * CEErrorMalloc
  843. * CEErrorLocIdNotFound
  844. * Specifies that 'locId' was not
  845. * found.
  846. *
  847. * Purpose: Find which topic contains a specified locationID.
  848. *
  849. *****************************************************************************/
  850. char *
  851. _DtHelpCeGetSdlHomeTopicId (
  852. _DtHelpVolumeHdl volume)
  853. {
  854. _DtCvSegment *idSegs;
  855. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  856. if (sdlVol->sdl_info != NULL)
  857. {
  858. /*
  859. * Was the first page topic declared in the header?
  860. */
  861. if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info))
  862. return (_SdlDocInfoPtrFirstPg(sdlVol->sdl_info));
  863. /*
  864. * have to search the list of ids for the home topic. This is a
  865. * bit of a kludge since we are looking for a specific string in
  866. * the rssi. But this is for backwards compatibility since the
  867. * Snapshot release of the help system were released with out
  868. * the first-page attribute and relied on _hometopic.
  869. *
  870. * Plus, first-page is #IMPLIED, which means that the parser
  871. * that generated this SDL document does not have to use this
  872. * attribute.
  873. */
  874. if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0)
  875. return NULL;
  876. while (idSegs != NULL)
  877. {
  878. if (SdlIdVirpage == _SdlSegToSdlIdInfoType(idSegs) &&
  879. _DtHelpCeStrCaseCmpLatin1(_SdlIdInfoPtrRssi(
  880. _SdlSegToSdlIdInfoPtr(idSegs)),
  881. "_hometopic") == 0)
  882. return _DtCvContainerIdOfSeg(idSegs);
  883. idSegs = idSegs->next_seg;
  884. }
  885. }
  886. return NULL;
  887. }
  888. /*****************************************************************************
  889. * Function: Boolean _DtHelpCeFindSdlId (_DtHelpVolume vol, char *target_id,
  890. * char *ret_name, int *ret_offset)
  891. *
  892. * Parameters: vol Specifies the loaded volume
  893. * target_id Specifies target location ID
  894. * ret_name Returns a null terminated string
  895. * containing a fully qualified path to
  896. * the file that contains 'target_id'.
  897. * ret_offset Returns the offset into 'ret_name'
  898. * to the topic that contains 'target_id'.
  899. *
  900. * Memory own by caller:
  901. * ret_name
  902. *
  903. * Returns: True if successful, False if a failure occurs
  904. *
  905. * errno Values: EINVAL Specifies an invalid parameter was
  906. * used.
  907. * CEErrorMalloc
  908. * CEErrorLocIdNotFound
  909. * Specifies that 'locId' was not
  910. * found.
  911. *
  912. * Purpose: Find which topic contains a specified locationID.
  913. *
  914. *****************************************************************************/
  915. int
  916. _DtHelpCeFindSdlId (
  917. _DtHelpVolumeHdl volume,
  918. char *target_id,
  919. int fd,
  920. char **ret_name,
  921. int *ret_offset )
  922. {
  923. _DtHelpVolume vol = (_DtHelpVolume) volume;
  924. _DtCvSegment *pEl;
  925. pEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, fd);
  926. if (pEl != NULL)
  927. {
  928. if (ret_name != NULL)
  929. *ret_name = strdup(vol->volFile);
  930. *ret_offset = _SdlIdInfoPtrOffset(_SdlSegToSdlIdInfoPtr(pEl));
  931. return True;
  932. }
  933. return False;
  934. }
  935. /*****************************************************************************
  936. * Function: int _DtHelpCeGetSdlKeywordList (
  937. *
  938. * Parameters:
  939. *
  940. * Returns: 0 if successful, -1 if not.
  941. *
  942. * errno Values:
  943. *
  944. * Purpose: Get the KeywordList for an SDL volume.
  945. *
  946. *****************************************************************************/
  947. int
  948. _DtHelpCeGetSdlKeywordList (
  949. _DtHelpVolumeHdl volume)
  950. {
  951. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  952. if (_DtHelpCeGetSdlVolIndex(volume) != 0 || NULL == sdlVol->index
  953. || NULL == _DtCvContainerListOfSeg(sdlVol->index))
  954. return -1;
  955. return(ProcessEntry(((_DtHelpVolume) volume),
  956. _DtCvContainerListOfSeg(sdlVol->index), NULL));
  957. }
  958. /*****************************************************************************
  959. * Function: int _DtHelpCeGetSdlVolumeAsciiAbstract(volume);
  960. *
  961. * Parameters:
  962. *
  963. * Returns: 0 if successful, -1 if not.
  964. *
  965. * errno Values:
  966. *
  967. * Purpose: Get the KeywordList for an SDL volume.
  968. *
  969. *****************************************************************************/
  970. char *
  971. _DtHelpCeGetSdlVolumeAsciiAbstract(
  972. _DtHelpVolumeHdl volume)
  973. {
  974. return(_DtHelpCeFrmtSdlVolumeAbstractToAscii(volume));
  975. }
  976. /*****************************************************************************
  977. * Function: int _DtHelpCeGetSdlIdPath(volume, target_id, ret_ids);
  978. *
  979. * Parameters:
  980. *
  981. * Returns: > 0 if successful, -1 if not.
  982. *
  983. * Memory: The memory returned is owned by the caller.
  984. *
  985. * Purpose: Get the list of location ids between the top and the
  986. * target_id.
  987. *
  988. *****************************************************************************/
  989. int
  990. _DtHelpCeGetSdlIdPath(
  991. _DtHelpVolumeHdl volume,
  992. char *target_id,
  993. char ***ret_ids)
  994. {
  995. _DtCvSegment *idSegs;
  996. _DtCvSegment *targetEl;
  997. int hiddenNo = -1;
  998. targetEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1);
  999. if (targetEl == NULL)
  1000. return -1;
  1001. *ret_ids = NULL;
  1002. if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0)
  1003. return 0;
  1004. if (_SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume)) >= SDL_DTD_1_1)
  1005. hiddenNo = 0;
  1006. return (MapPath(&idSegs, targetEl, -1, 0, hiddenNo, ret_ids));
  1007. }
  1008. /*****************************************************************************
  1009. * Function: _DtCvSegment *_DtHelpCeMapSdlIdToSegment(volume, target_id);
  1010. *
  1011. * Parameters:
  1012. *
  1013. * Returns: > 0 if successful, -1 if not.
  1014. *
  1015. * errno Values:
  1016. *
  1017. * Purpose: Get the list of location ids between the top and the
  1018. * target_id.
  1019. *
  1020. *****************************************************************************/
  1021. _DtCvSegment *
  1022. _DtHelpCeMapSdlIdToSegment(
  1023. _DtHelpVolumeHdl volume,
  1024. const char *target_id,
  1025. int fd)
  1026. {
  1027. int underScore = False;
  1028. short minorNo;
  1029. _DtCvSegment *idSegs;
  1030. char *idString;
  1031. char resStr[128] = "SDL-RESERVED-";
  1032. minorNo = _SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume));
  1033. if (*target_id == '_')
  1034. {
  1035. /*
  1036. * parsers generating SDL_DTD_1_0 and earlier put the special
  1037. * access points (_hometopic, _abstract, _copyright, etc.) in
  1038. * the SSI.
  1039. */
  1040. if (minorNo < SDL_DTD_1_1)
  1041. underScore = True;
  1042. else
  1043. {
  1044. target_id++;
  1045. strcat(resStr, target_id);
  1046. target_id = resStr;
  1047. }
  1048. }
  1049. if (_DtHelpCeGetSdlVolIds(volume, fd, &idSegs) != 0)
  1050. return NULL;
  1051. while (idSegs != NULL)
  1052. {
  1053. if (underScore == True)
  1054. idString = _SdlIdInfoPtrRssi(_SdlSegToSdlIdInfoPtr(idSegs));
  1055. else
  1056. idString = _DtCvContainerIdOfSeg(idSegs);
  1057. if (idString != NULL &&
  1058. _DtHelpCeStrCaseCmpLatin1(idString, target_id) == 0)
  1059. return idSegs;
  1060. idSegs = idSegs->next_seg;
  1061. }
  1062. return NULL;
  1063. }
  1064. /*****************************************************************************
  1065. * Function: int _DtHelpCeMapIdToSdlTopicId(volume, target_id);
  1066. *
  1067. * Parameters:
  1068. *
  1069. * Returns: > 0 if successful, -1 if not.
  1070. *
  1071. * errno Values:
  1072. *
  1073. * Purpose: Get the id of the virpage containing the target_id.
  1074. *
  1075. *****************************************************************************/
  1076. int
  1077. _DtHelpCeMapIdToSdlTopicId(
  1078. _DtHelpVolumeHdl volume,
  1079. const char *target_id,
  1080. char **ret_id)
  1081. {
  1082. int found = -1;
  1083. _DtCvSegment *idList;
  1084. _DtCvSegment *idSeg;
  1085. SDLIdInfo *idInfo;
  1086. if (_DtHelpCeGetSdlVolIds(volume, -1, &idList) == 0)
  1087. {
  1088. idSeg = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1);
  1089. if (idSeg != NULL)
  1090. {
  1091. while (found == -1 && idList != NULL)
  1092. {
  1093. idInfo = _SdlSegToSdlIdInfoPtr(idList);
  1094. if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage)
  1095. *ret_id = _DtCvContainerIdOfSeg(idList);
  1096. if (idList == idSeg)
  1097. found = 0;
  1098. else
  1099. idList = idList->next_seg;
  1100. }
  1101. }
  1102. }
  1103. return found;
  1104. }
  1105. /*****************************************************************************
  1106. * Function: char * _DtHelpCeGetSdlVolCharSet(volume);
  1107. *
  1108. * Parameters:
  1109. *
  1110. * Returns: the pointer to the locale string. Null otherwise.
  1111. *
  1112. * errno Values:
  1113. *
  1114. * Purpose: Get the locale of the volume.
  1115. *
  1116. *****************************************************************************/
  1117. const char *
  1118. _DtHelpCeGetSdlVolCharSet(
  1119. _DtHelpVolumeHdl volume)
  1120. {
  1121. const char *charSet = IsoString;
  1122. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  1123. if (sdlVol->sdl_info != NULL &&
  1124. NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
  1125. charSet = _SdlDocInfoPtrCharSet(sdlVol->sdl_info);
  1126. return charSet;
  1127. }
  1128. /*****************************************************************************
  1129. * Function: char * _DtHelpCeGetSdlVolLanguage(volume);
  1130. *
  1131. * Parameters:
  1132. *
  1133. * Returns: the pointer to the language used in the volume.
  1134. *
  1135. * errno Values:
  1136. *
  1137. * Purpose: Get the locale of the volume.
  1138. *
  1139. *****************************************************************************/
  1140. char *
  1141. _DtHelpCeGetSdlVolLanguage(
  1142. _DtHelpVolumeHdl volume)
  1143. {
  1144. char *language = "C";
  1145. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  1146. if (sdlVol->sdl_info != NULL &&
  1147. NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
  1148. language = _SdlDocInfoPtrLanguage(sdlVol->sdl_info);
  1149. return language;
  1150. }
  1151. /*****************************************************************************
  1152. * Function: char * _DtHelpCeGetSdlVolumeLocale(volume);
  1153. *
  1154. * Parameters:
  1155. *
  1156. * Returns: the pointer to the locale string. Null otherwise.
  1157. *
  1158. * errno Values:
  1159. *
  1160. * Purpose: Get the locale of the volume.
  1161. *
  1162. *****************************************************************************/
  1163. char *
  1164. _DtHelpCeGetSdlVolumeLocale(
  1165. _DtHelpVolumeHdl volume)
  1166. {
  1167. int langLen;
  1168. char *locale;
  1169. char *lang;
  1170. const char *charSet;
  1171. lang = _DtHelpCeGetSdlVolLanguage(volume);
  1172. charSet = _DtHelpCeGetSdlVolCharSet(volume);
  1173. langLen = strlen(lang);
  1174. locale = (char *) malloc (langLen + strlen(charSet) + 2);
  1175. if (locale != NULL)
  1176. {
  1177. strcpy(locale, lang);
  1178. if (langLen != 0 && *charSet != '\0')
  1179. {
  1180. locale[langLen++] = '.';
  1181. strcpy(&(locale[langLen]), charSet);
  1182. }
  1183. }
  1184. return locale;
  1185. }
  1186. /*****************************************************************************
  1187. * Function: int _DtHelpCeGetSdlDocStamp(volume, ret_doc, ret_time);
  1188. *
  1189. * Parameters:
  1190. *
  1191. * Returns: 0 if successful, -2 if the volume does not contain
  1192. * one or the other, -1 if any other failure.
  1193. *
  1194. * Memory: The Caller owns the memory returned in ret_doc and ret_time.
  1195. *
  1196. * Purpose: Get the doc id and time stamp of a volume.
  1197. *
  1198. *****************************************************************************/
  1199. int
  1200. _DtHelpCeGetSdlDocStamp(
  1201. _DtHelpVolumeHdl volume,
  1202. char **ret_doc,
  1203. char **ret_time)
  1204. {
  1205. int result = -1;
  1206. char *docId = NULL;
  1207. char *timestamp = NULL;
  1208. CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
  1209. if (sdlVol->sdl_info != NULL)
  1210. {
  1211. result = 0;
  1212. if (NULL != _SdlDocInfoPtrDocId(sdlVol->sdl_info))
  1213. docId = strdup(_SdlDocInfoPtrDocId(sdlVol->sdl_info));
  1214. else
  1215. result = -2;
  1216. if (NULL != _SdlDocInfoPtrStamp(sdlVol->sdl_info))
  1217. timestamp = strdup(_SdlDocInfoPtrStamp(sdlVol->sdl_info));
  1218. else
  1219. result = -2;
  1220. }
  1221. if (ret_doc != NULL)
  1222. *ret_doc = docId;
  1223. if (ret_time != NULL)
  1224. *ret_time = timestamp;
  1225. if (result == 0 && (docId == NULL || timestamp == NULL))
  1226. return -1;
  1227. return result;
  1228. }
  1229. /*****************************************************************************
  1230. * Function: int _DtHelpCeGetSdlTopicChildren(
  1231. *
  1232. * Parameters:
  1233. *
  1234. * Returns: pointer to the element, Null otherwise.
  1235. *
  1236. * errno Values:
  1237. *
  1238. * Purpose: Find the specified element.
  1239. *
  1240. *****************************************************************************/
  1241. int
  1242. _DtHelpCeGetSdlTopicChildren(
  1243. _DtHelpVolumeHdl volume,
  1244. char *target,
  1245. char ***ret_ids)
  1246. {
  1247. int done = False;
  1248. int count = 0;
  1249. int segLev;
  1250. _DtCvSegment *idSeg;
  1251. SDLIdInfo *idInfo;
  1252. /*
  1253. * Find the target id.
  1254. */
  1255. idSeg = _DtHelpCeMapSdlIdToSegment(volume, target, -1);
  1256. /*
  1257. * save this level and start looking for its children at the next seg.
  1258. */
  1259. *ret_ids = NULL;
  1260. if (idSeg != NULL)
  1261. {
  1262. idInfo = _SdlSegToSdlIdInfoPtr(idSeg);
  1263. segLev = _SdlIdInfoPtrRlevel(idInfo) + 1;
  1264. idSeg = idSeg->next_seg;
  1265. }
  1266. /*
  1267. * process any virpage that has the correct level
  1268. */
  1269. while (idSeg != NULL && done == False)
  1270. {
  1271. idInfo = _SdlSegToSdlIdInfoPtr(idSeg);
  1272. if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage)
  1273. {
  1274. /*
  1275. * If greater, we're at the next sibling.
  1276. */
  1277. if (segLev > _SdlIdInfoPtrRlevel(idInfo))
  1278. done = True;
  1279. else if (segLev == _SdlIdInfoPtrRlevel(idInfo))
  1280. {
  1281. *ret_ids = (char **) _DtHelpCeAddPtrToArray( (void **) *ret_ids,
  1282. (void *)(strdup(_DtCvContainerIdOfSeg(idSeg))));
  1283. if ((*ret_ids) == NULL)
  1284. return -1;
  1285. count++;
  1286. }
  1287. }
  1288. idSeg = idSeg->next_seg;
  1289. }
  1290. return count;
  1291. }