2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: AccessSDL.c /main/13 1996/09/30 11:22:14 cde-hp $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 ** Project: Run Time Project File Access
31 ** Description: This body of code handles the access routines for the
35 ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
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.
43 ****************************************************************************
44 ************************************<+>*************************************/
54 #include <X11/Xresource.h>
57 * Canvas Engine includes
60 #include "CanvasSegP.h"
67 #include "CvStringI.h"
68 #include "FontAttrI.h"
71 #include "AccessSDLP.h"
72 #include "AccessSDLI.h"
73 #include "FormatUtilI.h"
74 #include "FormatSDLI.h"
75 #include "StringFuncsI.h"
81 /******** Private Defines ********/
82 /******** End Private Defines ********/
84 /******** Private Function Declarations ********/
85 static int ProcessEntry (
89 /******** End Private Function Declarations ********/
91 /******** Private Variable Declarations ********/
92 static const char *IsoString = "ISO-8859-1";
93 static const CESDLVolume DefaultSdlVolume =
95 NULL, /* _DtCvSegment *sdl_info; */
96 NULL, /* _DtCvSegment *toss; */
97 NULL, /* _DtCvSegment *loids; */
98 NULL, /* _DtCvSegment *index; */
99 NULL, /* _DtCvSegment *title; */
100 NULL, /* _DtCvSegment *snb; */
101 0, /* short minor_no; */
102 False, /* short title_processed; */
105 /******** Private Macro Declarations ********/
107 /******************************************************************************
109 ******************************************************************************/
110 /******************************************************************************
111 * Function: void FreeIds (
121 ******************************************************************************/
131 p_seg = _DtCvContainerListOfSeg(loids);
133 while (NULL != p_seg)
135 if (NULL != _SdlSegToSdlIdInfoPtr(p_seg))
137 if (NULL != _SdlSegToSdlIdInfoRssi(p_seg))
138 free(_SdlSegToSdlIdInfoRssi(p_seg));
140 free(_SdlSegToSdlIdInfoPtr(p_seg));
143 p_seg = p_seg->next_seg;
147 /******************************************************************************
148 * Function: void FreeTossInfo (
158 ******************************************************************************/
169 p_seg = _DtCvContainerListOfSeg(toss);
171 while (NULL != p_seg)
173 info = (SDLTossInfo *) _SdlSegTossInfo(p_seg);
176 if (NULL != _SdlTossInfoPtrSsi(info))
177 free(_SdlTossInfoPtrSsi(info));
179 /* free the colj,colw or the enter, exit data */
180 if (NULL != _SdlTossInfoPtrStr1(info))
181 free(_SdlTossInfoPtrStr1(info));
182 if (NULL != _SdlTossInfoPtrStr2(info))
183 free(_SdlTossInfoPtrStr2(info));
185 /* free the font strings */
186 if (NULL != _DtHelpFontHintsColor(_SdlTossInfoPtrFontSpecs(info)))
187 free(_DtHelpFontHintsColor(_SdlTossInfoPtrFontSpecs(info)));
188 if (NULL != _DtHelpFontHintsXlfd(_SdlTossInfoPtrFontSpecs(info)))
189 free(_DtHelpFontHintsXlfd(_SdlTossInfoPtrFontSpecs(info)));
190 if (NULL != _DtHelpFontHintsXlfdb(_SdlTossInfoPtrFontSpecs(info)))
191 free(_DtHelpFontHintsXlfdb(_SdlTossInfoPtrFontSpecs(info)));
192 if (NULL != _DtHelpFontHintsXlfdi(_SdlTossInfoPtrFontSpecs(info)))
193 free(_DtHelpFontHintsXlfdi(_SdlTossInfoPtrFontSpecs(info)));
194 if (NULL != _DtHelpFontHintsXlfdib(_SdlTossInfoPtrFontSpecs(info)))
195 free(_DtHelpFontHintsXlfdib(_SdlTossInfoPtrFontSpecs(info)));
196 if (NULL != _DtHelpFontHintsTypeNam(_SdlTossInfoPtrFontSpecs(info)))
197 free(_DtHelpFontHintsTypeNam(_SdlTossInfoPtrFontSpecs(info)));
198 if (NULL != _DtHelpFontHintsTypeNamb(_SdlTossInfoPtrFontSpecs(info)))
199 free(_DtHelpFontHintsTypeNamb(_SdlTossInfoPtrFontSpecs(info)));
200 if (NULL != _DtHelpFontHintsTypeNami(_SdlTossInfoPtrFontSpecs(info)))
201 free(_DtHelpFontHintsTypeNami(_SdlTossInfoPtrFontSpecs(info)));
202 if (NULL != _DtHelpFontHintsTypeNamib(_SdlTossInfoPtrFontSpecs(info)))
203 free(_DtHelpFontHintsTypeNamib(_SdlTossInfoPtrFontSpecs(info)));
207 p_seg = p_seg->next_seg;
211 /******************************************************************************
212 * Function: void FreeEntryInfo (
222 ******************************************************************************/
233 p_seg = _DtCvContainerListOfSeg(index);
235 while (NULL != p_seg)
237 info = _SdlSegToSdlEntryInfo(p_seg);
241 if (NULL != info->main)
243 if (NULL != info->locs)
245 if (NULL != info->syns)
247 if (NULL != info->sort)
251 if (_DtCvIsSegContainer(p_seg))
252 FreeEntryInfo(p_seg);
256 p_seg = p_seg->next_seg;
260 /******************************************************************************
261 * Function: int ProcessSubEntries (
271 ******************************************************************************/
278 while (p_seg != NULL)
281 * the only sub containers of an entry that should have an non-null
282 * internal pointer should be a sub <entry>.
284 if (_DtCvIsSegContainer(p_seg) && NULL != _SdlSegEntryInfo(p_seg)
285 && ProcessEntry(vol, _DtCvContainerListOfSeg(p_seg),
289 p_seg = p_seg->next_seg;
294 /******************************************************************************
295 * Function: int AsciiKeyword (
298 * p_list The segment list to process for strings.
299 * parent_str The string to append information onto.
301 * str_size The malloc'ed size of the parent string.
302 * Includes room for the null byte. If zero
303 * and parent_str is non-null, then memory
304 * must be malloc'ed and parent_str copied
305 * into it. Otherwise, goodStr can just
314 ******************************************************************************/
317 _DtCvSegment *p_list,
326 * if a starting string has been passed in, use it.
328 if (NULL != parent_str)
331 * get the actual byte count.
333 len = strlen(parent_str) + 1;
336 * is the starting value zero? If so, we have to copy it.
340 parent_str = strdup(parent_str);
341 if (NULL == parent_str)
349 * start with the parent_string
351 goodStr = parent_str;
353 while (p_list != NULL)
355 if (_DtCvIsSegString(p_list))
358 * get the number of characters in the next string.
360 newLen = _DtCvStrLen(_DtCvStringOfStringSeg(p_list),
361 _DtCvIsSegWideChar(p_list));
364 * if this is wide char string, multiply the count by
365 * MB_CUR_MAX to get the maximum number of bytes this
368 if (_DtCvIsSegWideChar(p_list))
369 newLen = newLen * MB_CUR_MAX;
372 * now add it to our previous size.
377 * are we starting from scratch?
382 * include a byte for the end-of-string character.
389 goodStr = (char *) malloc (len);
392 else if (*str_size < len) /* does this have to grow? */
393 goodStr = (char *) realloc (goodStr, len);
399 * remember the absolute size of the memory for the string
404 if (_DtCvIsSegWideChar(p_list))
407 * back up to the insertion point.
414 newLen = wcstombs(&goodStr[len - 1],
415 (wchar_t *) _DtCvStringOfStringSeg(p_list),
417 if ((size_t) -1 == newLen)
426 strcpy(&goodStr[len - newLen - 1],
427 (char *) _DtCvStringOfStringSeg(p_list));
431 * the only containers in an <entry> that should have a non-null
432 * internal pointer should be a sub <entry>. Therefore, if null,
433 * process since it could be a <key>, <sphrase>, etc.
435 else if (_DtCvIsSegContainer(p_list) &&
436 NULL == _SdlSegEntryInfo(p_list))
438 goodStr = AsciiKeyword(_DtCvContainerListOfSeg(p_list), goodStr,
443 len = strlen(goodStr) + 1;
446 p_list = p_list->next_seg;
452 /******************************************************************************
453 * Function: int ProcessLocations (
463 ******************************************************************************/
469 char **myList = NULL;
472 while (locs != NULL && *locs != '\0')
474 locs = _DtHelpGetNxtToken(locs, &nextLoc);
478 if (*nextLoc != '\0')
480 myList = (char **) _DtHelpCeAddPtrToArray ((void **) myList,
491 /******************************************************************************
492 * Function: int ProcessEntry (_DtHelpVolume vol)
494 * Parameters: vol Specifies the volume whose keywords need to be
495 * loaded from disk. Once loaded, they can be
496 * accessed through the fields of the volume structure.
498 * Return Value: 0 if successful, -1 if a failure occurs
500 * errno Values: CEErrorMalloc
501 * CEErrorIllegalDatabaseFile
502 * Specifies that the keyword file is
503 * invalid or corrupt.
504 * CEErrorMissingKeywordsRes
505 * Specifies that the keyword file does
506 * not contain the 'Keywords/keywords'
507 * resource or the resource is NULL
510 * Purpose: Load the keywords associated with a volume.
512 ******************************************************************************/
521 char *nextKey = NULL;
523 /* Now parse the string into the appropriate arrays. The string has the
526 <!ELEMENT entry - - ((%simple; | #PCDATA)*, entry*) >
527 <!ATTLIST entry id ID #IMPLIED
531 sort CDATA #IMPLIED >
534 #define MAIN_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->main
535 #define LOCS_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->locs
537 while (p_seg != NULL)
540 nextKey = AsciiKeyword(_DtCvContainerListOfSeg(p_seg),
541 parent_key, &strSize);
546 /* We have the next keyword. Hang onto it and add it to the list
547 once we get the array of topics. We don't add it yet because if
548 there are no topics we want to throw it away. (Silently ignoring
549 keywords which specify no topics is an undocumented feature.) */
551 /* Now get the list of topics. */
553 if (NULL != FrmtPrivInfoPtr(p_seg) && NULL != _SdlSegEntryInfo(p_seg)
554 && (ProcessLocations(MAIN_STRINGS, &topics) == -1 ||
555 ProcessLocations(LOCS_STRINGS, &topics) == -1))
563 vol->keywords = (char **) _DtHelpCeAddPtrToArray (
564 (void **) vol->keywords,
566 vol->keywordTopics = (char ***) _DtHelpCeAddPtrToArray (
567 (void **) vol->keywordTopics,
570 * If we just malloc'ed ourselves out of existence...
573 if (vol->keywords == 0 || vol->keywordTopics == 0)
575 if (vol->keywords != NULL)
578 _DtHelpCeFreeStringArray (vol->keywords);
579 _DtHelpCeFreeStringArray (topics);
580 vol->keywords = NULL;
582 if (vol->keywordTopics)
586 for (topicList = vol->keywordTopics; topicList; topicList++)
587 _DtHelpCeFreeStringArray (*topicList);
588 free (vol->keywordTopics);
589 vol->keywordTopics = NULL;
595 if (_DtCvContainerListOfSeg(p_seg) != NULL &&
596 ProcessSubEntries(vol,_DtCvContainerListOfSeg(p_seg),nextKey) == -1)
602 p_seg = p_seg->next_seg;
608 /******************************************************************************
609 * Function: int MapPath (_DtCvSegment *cur_id, int level, char ***ret_ids)
613 * Return Value: 0 if successful, -1 if failure.
615 * Memory: The memory returned in ret_ids is owned by the caller.
617 * Purpose: To come up with a path from the top of the volume to the
620 ******************************************************************************/
623 _DtCvSegment **cur_id,
624 _DtCvSegment *target_el,
630 _DtCvSegment *mySeg = *cur_id;
635 while (mySeg != NULL)
638 * Does this match the target id?
639 * And, is the element a child of the current path?
641 info = _SdlSegToSdlIdInfoPtr(mySeg);
642 myLev = _SdlIdInfoPtrRlevel(info);
643 if (target_el == mySeg && (myLev == -1 || myLev > stop_lev))
646 * matched the target id.
647 * allocate memory and return.
650 if (_SdlIdInfoPtrType(info) == SdlIdVirpage)
656 *ret_ids = (char **) malloc (sizeof(char *) * (lev_cnt + 1));
657 if ((*ret_ids) == NULL)
660 (*ret_ids)[lev_cnt] = NULL;
662 if (_SdlIdInfoPtrType(info) == SdlIdVirpage)
663 (*ret_ids)[lev_cnt - 1] = strdup(_DtCvContainerIdOfSeg(mySeg));
667 else if (myLev != -1 && myLev != hidden_no
668 && _SdlIdInfoPtrType(info) == SdlIdVirpage)
670 char *myId = _DtCvContainerIdOfSeg(mySeg);
673 * If we've hit a virpage that is a sibling or an aunt
674 * set the search pointer to this segment (since this
675 * is where we want to start searching again) and return
676 * a negative on the successful search.
678 if (myLev <= stop_lev)
685 * this virpage is a child of mine, so look at it's children
688 mySeg = mySeg->next_seg;
689 count = MapPath(&mySeg, target_el, myLev, lev_cnt + 1, hidden_no,
693 * successful response on finding the target id in the virpage's
694 * children. Duplicate the virpage's id string and return to
699 (*ret_ids)[lev_cnt] = strdup(myId);
705 else /* did not match the target id and is not a virpage
706 * or is a hidden virpage */
707 mySeg = mySeg->next_seg;
714 /******************************************************************************
715 * Semi-Private Functions
716 ******************************************************************************/
717 /*******************************************************************************
718 * Function: CESDLVolume *_DtHelpCeGetSdlVolumePtr (_DtHelpVolumeHdl vol);
720 * Parameters: vol Specifies the loaded volume.
722 * Return Value: 0 if successful, -1 if a failure occurs
726 * Purpose: When the volume is no longer needed, it should be unloaded
727 * with this call. Unloading it frees the memory (which means
728 * any handles on the volume become invalid.)
730 ******************************************************************************/
732 _DtHelpCeGetSdlVolumePtr (
733 _DtHelpVolumeHdl volume)
735 _DtHelpVolume vol = (_DtHelpVolume) volume;
738 return ((CESDLVolume *) vol->vols.sdl_vol);
742 /******************************************************************************
743 * Semi-Public Functions
744 ******************************************************************************/
745 /*******************************************************************************
746 * Function: void _DtHelpCeInitSdlVolume (_DtHelpVolume vol);
748 * Parameters: vol Specifies the loaded volume.
750 * Return Value: 0 if successful, -1 if a failure occurs
754 * Purpose: When the volume is no longer needed, it should be unloaded
755 * with this call. Unloading it frees the memory (which means
756 * any handles on the volume become invalid.)
758 ******************************************************************************/
760 _DtHelpCeInitSdlVolume (
761 _DtHelpVolumeHdl volume)
763 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
766 *sdlVol = DefaultSdlVolume;
770 /*******************************************************************************
771 * Function: void _DtHelpCeOpenSdlVolume (_DtHelpVolume vol);
773 * Parameters: vol Specifies the loaded volume.
775 * Return Value: 0 if successful, -1 if a failure occurs
779 * Purpose: When the volume is no longer needed, it should be unloaded
780 * with this call. Unloading it frees the memory (which means
781 * any handles on the volume become invalid.)
783 ******************************************************************************/
785 _DtHelpCeOpenSdlVolume (
786 _DtHelpVolumeHdl volume)
789 _DtHelpVolume vol = (_DtHelpVolume) volume;
791 sdlVol = (CESDLVolume *) calloc (1, sizeof(CESDLVolume));
794 vol->vols.sdl_vol = (SdlVolumeHandle) sdlVol;
795 _DtHelpCeInitSdlVolume(volume);
796 if (_DtHelpCeFrmtSdlVolumeInfo(vol->volFile,
797 vol, &(vol->check_time)) == 0)
799 vol->sdl_flag = True;
803 vol->vols.sdl_vol = NULL;
810 /*******************************************************************************
811 * Function: void _DtHelpCeCleanSdlVolume (_DtHelpVolume vol);
813 * Parameters: vol Specifies the loaded volume.
815 * Return Value: 0 if successful, -1 if a failure occurs
819 * Purpose: When the volume is no longer needed, it should be unloaded
820 * with this call. Unloading it frees the memory (which means
821 * any handles on the volume become invalid.)
823 ******************************************************************************/
825 _DtHelpCeCleanSdlVolume (
826 _DtHelpVolumeHdl volume)
828 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
832 _DtHelpFreeSegments(sdlVol->snb , _DtCvFALSE, sdlVol->destroy_region,
833 sdlVol->client_data);
834 _DtHelpFreeSegments(sdlVol->title, _DtCvFALSE, sdlVol->destroy_region,
835 sdlVol->client_data);
838 * free the index information
840 FreeEntryInfo(sdlVol->index);
841 _DtHelpFreeSegments(sdlVol->index, _DtCvFALSE, NULL, NULL);
844 * free the toss information.
846 FreeTossInfo(sdlVol->toss);
847 _DtHelpFreeSegments(sdlVol->toss , _DtCvFALSE, NULL, NULL);
852 FreeIds(sdlVol->loids);
853 _DtHelpFreeSegments(sdlVol->loids, _DtCvFALSE, NULL, NULL);
856 * free the document information.
858 if (NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
859 free(_SdlDocInfoPtrLanguage(sdlVol->sdl_info));
861 if (NULL != _SdlDocInfoPtrCharSet(sdlVol->sdl_info))
862 free(_SdlDocInfoPtrCharSet(sdlVol->sdl_info));
864 if (NULL != _SdlDocInfoPtrDocId(sdlVol->sdl_info))
865 free(_SdlDocInfoPtrDocId(sdlVol->sdl_info));
867 if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info))
868 free(_SdlDocInfoPtrFirstPg(sdlVol->sdl_info));
870 if (NULL != _SdlDocInfoPtrSdlDtd(sdlVol->sdl_info))
871 free(_SdlDocInfoPtrSdlDtd(sdlVol->sdl_info));
873 if (NULL != _SdlDocInfoPtrStamp(sdlVol->sdl_info))
874 free(_SdlDocInfoPtrStamp(sdlVol->sdl_info));
876 free(sdlVol->sdl_info);
880 /*******************************************************************************
881 * Function: int _DtHelpCeRereadSdlVolume (_DtHelpVolume vol);
883 * Parameters: vol Specifies the loaded volume.
885 * Return Value: 0 if successful, -1 if a failure occurs
889 * Purpose: When the volume is no longer needed, it should be unloaded
890 * with this call. Unloading it frees the memory (which means
891 * any handles on the volume become invalid.)
893 ******************************************************************************/
895 _DtHelpCeRereadSdlVolume (
896 _DtHelpVolumeHdl volume)
898 _DtHelpCeCleanSdlVolume(volume);
899 _DtHelpCeInitSdlVolume(volume);
900 if (_DtHelpCeFrmtSdlVolumeInfo(_DtHelpCeGetVolumeName(volume),
907 /*******************************************************************************
908 * Function: void _DtHelpCeCloseSdlVolume (_DtHelpVolume vol);
910 * Parameters: vol Specifies the loaded volume.
912 * Return Value: 0 if successful, -1 if a failure occurs
916 * Purpose: When the volume is no longer needed, it should be unloaded
917 * with this call. Unloading it frees the memory (which means
918 * any handles on the volume become invalid.)
920 ******************************************************************************/
922 _DtHelpCeCloseSdlVolume (
923 _DtHelpVolumeHdl volume)
925 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
929 _DtHelpCeCleanSdlVolume(volume);
934 /*****************************************************************************
935 * Function: Boolean _DtHelpCeGetSdlHomeTopicId (_DtHelpVolume vol,
937 * char *ret_name, int *ret_offset)
939 * Parameters: vol Specifies the loaded volume
940 * target_id Specifies target location ID
941 * ret_name Returns a null terminated string
942 * containing a fully qualified path to
943 * the file that contains 'target_id'.
944 * ret_offset Returns the offset into 'ret_name'
945 * to the topic that contains 'target_id'.
947 * Memory own by caller:
950 * Returns: True if successful, False if a failure occurs
952 * errno Values: EINVAL Specifies an invalid parameter was
955 * CEErrorLocIdNotFound
956 * Specifies that 'locId' was not
959 * Purpose: Find which topic contains a specified locationID.
961 *****************************************************************************/
963 _DtHelpCeGetSdlHomeTopicId (
964 _DtHelpVolumeHdl volume)
966 _DtCvSegment *idSegs;
967 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
969 if (sdlVol->sdl_info != NULL)
972 * Was the first page topic declared in the header?
974 if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info))
975 return (_SdlDocInfoPtrFirstPg(sdlVol->sdl_info));
978 * have to search the list of ids for the home topic. This is a
979 * bit of a kludge since we are looking for a specific string in
980 * the rssi. But this is for backwards compatibility since the
981 * Snapshot release of the help system were released with out
982 * the first-page attribute and relied on _hometopic.
984 * Plus, first-page is #IMPLIED, which means that the parser
985 * that generated this SDL document does not have to use this
988 if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0)
991 while (idSegs != NULL)
993 if (SdlIdVirpage == _SdlSegToSdlIdInfoType(idSegs) &&
994 _DtHelpCeStrCaseCmpLatin1(_SdlIdInfoPtrRssi(
995 _SdlSegToSdlIdInfoPtr(idSegs)),
997 return _DtCvContainerIdOfSeg(idSegs);
999 idSegs = idSegs->next_seg;
1006 /*****************************************************************************
1007 * Function: Boolean _DtHelpCeFindSdlId (_DtHelpVolume vol, char *target_id,
1008 * char *ret_name, int *ret_offset)
1010 * Parameters: vol Specifies the loaded volume
1011 * target_id Specifies target location ID
1012 * ret_name Returns a null terminated string
1013 * containing a fully qualified path to
1014 * the file that contains 'target_id'.
1015 * ret_offset Returns the offset into 'ret_name'
1016 * to the topic that contains 'target_id'.
1018 * Memory own by caller:
1021 * Returns: True if successful, False if a failure occurs
1023 * errno Values: EINVAL Specifies an invalid parameter was
1026 * CEErrorLocIdNotFound
1027 * Specifies that 'locId' was not
1030 * Purpose: Find which topic contains a specified locationID.
1032 *****************************************************************************/
1034 _DtHelpCeFindSdlId (
1035 _DtHelpVolumeHdl volume,
1041 _DtHelpVolume vol = (_DtHelpVolume) volume;
1044 pEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, fd);
1048 if (ret_name != NULL)
1049 *ret_name = strdup(vol->volFile);
1050 *ret_offset = _SdlIdInfoPtrOffset(_SdlSegToSdlIdInfoPtr(pEl));
1057 /*****************************************************************************
1058 * Function: int _DtHelpCeGetSdlKeywordList (
1062 * Returns: 0 if successful, -1 if not.
1066 * Purpose: Get the KeywordList for an SDL volume.
1068 *****************************************************************************/
1070 _DtHelpCeGetSdlKeywordList (
1071 _DtHelpVolumeHdl volume)
1073 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
1075 if (_DtHelpCeGetSdlVolIndex(volume) != 0 || NULL == sdlVol->index
1076 || NULL == _DtCvContainerListOfSeg(sdlVol->index))
1079 return(ProcessEntry(((_DtHelpVolume) volume),
1080 _DtCvContainerListOfSeg(sdlVol->index), NULL));
1083 /*****************************************************************************
1084 * Function: int _DtHelpCeGetSdlVolumeAsciiAbstract(volume);
1088 * Returns: 0 if successful, -1 if not.
1092 * Purpose: Get the KeywordList for an SDL volume.
1094 *****************************************************************************/
1096 _DtHelpCeGetSdlVolumeAsciiAbstract(
1097 _DtHelpVolumeHdl volume)
1099 return(_DtHelpCeFrmtSdlVolumeAbstractToAscii(volume));
1102 /*****************************************************************************
1103 * Function: int _DtHelpCeGetSdlIdPath(volume, target_id, ret_ids);
1107 * Returns: > 0 if successful, -1 if not.
1109 * Memory: The memory returned is owned by the caller.
1111 * Purpose: Get the list of location ids between the top and the
1114 *****************************************************************************/
1116 _DtHelpCeGetSdlIdPath(
1117 _DtHelpVolumeHdl volume,
1121 _DtCvSegment *idSegs;
1122 _DtCvSegment *targetEl;
1125 targetEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1);
1127 if (targetEl == NULL)
1132 if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0)
1135 if (_SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume)) >= SDL_DTD_1_1)
1138 return (MapPath(&idSegs, targetEl, -1, 0, hiddenNo, ret_ids));
1141 /*****************************************************************************
1142 * Function: _DtCvSegment *_DtHelpCeMapSdlIdToSegment(volume, target_id);
1146 * Returns: > 0 if successful, -1 if not.
1150 * Purpose: Get the list of location ids between the top and the
1153 *****************************************************************************/
1155 _DtHelpCeMapSdlIdToSegment(
1156 _DtHelpVolumeHdl volume,
1157 const char *target_id,
1160 int underScore = False;
1162 _DtCvSegment *idSegs;
1164 char resStr[128] = "SDL-RESERVED-";
1166 minorNo = _SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume));
1168 if (*target_id == '_')
1171 * parsers generating SDL_DTD_1_0 and earlier put the special
1172 * access points (_hometopic, _abstract, _copyright, etc.) in
1175 if (minorNo < SDL_DTD_1_1)
1180 strcat(resStr, target_id);
1185 if (_DtHelpCeGetSdlVolIds(volume, fd, &idSegs) != 0)
1188 while (idSegs != NULL)
1190 if (underScore == True)
1191 idString = _SdlIdInfoPtrRssi(_SdlSegToSdlIdInfoPtr(idSegs));
1193 idString = _DtCvContainerIdOfSeg(idSegs);
1195 if (idString != NULL &&
1196 _DtHelpCeStrCaseCmpLatin1(idString, target_id) == 0)
1199 idSegs = idSegs->next_seg;
1205 /*****************************************************************************
1206 * Function: int _DtHelpCeMapIdToSdlTopicId(volume, target_id);
1210 * Returns: > 0 if successful, -1 if not.
1214 * Purpose: Get the id of the virpage containing the target_id.
1216 *****************************************************************************/
1218 _DtHelpCeMapIdToSdlTopicId(
1219 _DtHelpVolumeHdl volume,
1220 const char *target_id,
1224 _DtCvSegment *idList;
1225 _DtCvSegment *idSeg;
1228 if (_DtHelpCeGetSdlVolIds(volume, -1, &idList) == 0)
1230 idSeg = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1);
1233 while (found == -1 && idList != NULL)
1235 idInfo = _SdlSegToSdlIdInfoPtr(idList);
1236 if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage)
1237 *ret_id = _DtCvContainerIdOfSeg(idList);
1239 if (idList == idSeg)
1242 idList = idList->next_seg;
1250 /*****************************************************************************
1251 * Function: char * _DtHelpCeGetSdlVolCharSet(volume);
1255 * Returns: the pointer to the locale string. Null otherwise.
1259 * Purpose: Get the locale of the volume.
1261 *****************************************************************************/
1263 _DtHelpCeGetSdlVolCharSet(
1264 _DtHelpVolumeHdl volume)
1266 const char *charSet = IsoString;
1267 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
1269 if (sdlVol->sdl_info != NULL &&
1270 NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
1271 charSet = _SdlDocInfoPtrCharSet(sdlVol->sdl_info);
1276 /*****************************************************************************
1277 * Function: char * _DtHelpCeGetSdlVolLanguage(volume);
1281 * Returns: the pointer to the language used in the volume.
1285 * Purpose: Get the locale of the volume.
1287 *****************************************************************************/
1289 _DtHelpCeGetSdlVolLanguage(
1290 _DtHelpVolumeHdl volume)
1292 char *language = "C";
1293 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
1295 if (sdlVol->sdl_info != NULL &&
1296 NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
1297 language = _SdlDocInfoPtrLanguage(sdlVol->sdl_info);
1302 /*****************************************************************************
1303 * Function: char * _DtHelpCeGetSdlVolumeLocale(volume);
1307 * Returns: the pointer to the locale string. Null otherwise.
1311 * Purpose: Get the locale of the volume.
1313 *****************************************************************************/
1315 _DtHelpCeGetSdlVolumeLocale(
1316 _DtHelpVolumeHdl volume)
1321 const char *charSet;
1323 lang = _DtHelpCeGetSdlVolLanguage(volume);
1324 charSet = _DtHelpCeGetSdlVolCharSet(volume);
1326 langLen = strlen(lang);
1327 locale = (char *) malloc (langLen + strlen(charSet) + 2);
1330 strcpy(locale, lang);
1331 if (langLen != 0 && *charSet != '\0')
1333 locale[langLen++] = '.';
1334 strcpy(&(locale[langLen]), charSet);
1341 /*****************************************************************************
1342 * Function: int _DtHelpCeGetSdlDocStamp(volume, ret_doc, ret_time);
1346 * Returns: 0 if successful, -2 if the volume does not contain
1347 * one or the other, -1 if any other failure.
1349 * Memory: The Caller owns the memory returned in ret_doc and ret_time.
1351 * Purpose: Get the doc id and time stamp of a volume.
1353 *****************************************************************************/
1355 _DtHelpCeGetSdlDocStamp(
1356 _DtHelpVolumeHdl volume,
1362 char *timestamp = NULL;
1363 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
1365 if (sdlVol->sdl_info != NULL)
1368 if (NULL != _SdlDocInfoPtrDocId(sdlVol->sdl_info))
1369 docId = strdup(_SdlDocInfoPtrDocId(sdlVol->sdl_info));
1373 if (NULL != _SdlDocInfoPtrStamp(sdlVol->sdl_info))
1374 timestamp = strdup(_SdlDocInfoPtrStamp(sdlVol->sdl_info));
1379 if (ret_doc != NULL)
1381 if (ret_time != NULL)
1382 *ret_time = timestamp;
1384 if (result == 0 && (docId == NULL || timestamp == NULL)) {
1385 free(docId); /* Incase only one of them is NULL */
1386 free(timestamp); /* " */
1393 /*****************************************************************************
1394 * Function: int _DtHelpCeGetSdlTopicChildren(
1398 * Returns: pointer to the element, Null otherwise.
1402 * Purpose: Find the specified element.
1404 *****************************************************************************/
1406 _DtHelpCeGetSdlTopicChildren(
1407 _DtHelpVolumeHdl volume,
1414 _DtCvSegment *idSeg;
1418 * Find the target id.
1420 idSeg = _DtHelpCeMapSdlIdToSegment(volume, target, -1);
1423 * save this level and start looking for its children at the next seg.
1428 idInfo = _SdlSegToSdlIdInfoPtr(idSeg);
1429 segLev = _SdlIdInfoPtrRlevel(idInfo) + 1;
1430 idSeg = idSeg->next_seg;
1434 * process any virpage that has the correct level
1436 while (idSeg != NULL && done == False)
1438 idInfo = _SdlSegToSdlIdInfoPtr(idSeg);
1439 if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage)
1442 * If greater, we're at the next sibling.
1444 if (segLev > _SdlIdInfoPtrRlevel(idInfo))
1446 else if (segLev == _SdlIdInfoPtrRlevel(idInfo))
1448 *ret_ids = (char **) _DtHelpCeAddPtrToArray( (void **) *ret_ids,
1449 (void *)(strdup(_DtCvContainerIdOfSeg(idSeg))));
1450 if ((*ret_ids) == NULL)
1456 idSeg = idSeg->next_seg;