2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $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)
423 strcpy(&goodStr[len - newLen - 1],
424 (char *) _DtCvStringOfStringSeg(p_list));
428 * the only containers in an <entry> that should have a non-null
429 * internal pointer should be a sub <entry>. Therefore, if null,
430 * process since it could be a <key>, <sphrase>, etc.
432 else if (_DtCvIsSegContainer(p_list) &&
433 NULL == _SdlSegEntryInfo(p_list))
435 goodStr = AsciiKeyword(_DtCvContainerListOfSeg(p_list), goodStr,
440 len = strlen(goodStr) + 1;
443 p_list = p_list->next_seg;
449 /******************************************************************************
450 * Function: int ProcessLocations (
460 ******************************************************************************/
466 char **myList = NULL;
469 while (locs != NULL && *locs != '\0')
471 locs = _DtHelpGetNxtToken(locs, &nextLoc);
475 if (*nextLoc != '\0')
477 myList = (char **) _DtHelpCeAddPtrToArray ((void **) myList,
488 /******************************************************************************
489 * Function: int ProcessEntry (_DtHelpVolume vol)
491 * Parameters: vol Specifies the volume whose keywords need to be
492 * loaded from disk. Once loaded, they can be
493 * accessed through the fields of the volume structure.
495 * Return Value: 0 if successful, -1 if a failure occurs
497 * errno Values: CEErrorMalloc
498 * CEErrorIllegalDatabaseFile
499 * Specifies that the keyword file is
500 * invalid or corrupt.
501 * CEErrorMissingKeywordsRes
502 * Specifies that the keyword file does
503 * not contain the 'Keywords/keywords'
504 * resource or the resource is NULL
507 * Purpose: Load the keywords associated with a volume.
509 ******************************************************************************/
518 char *nextKey = NULL;
520 /* Now parse the string into the appropriate arrays. The string has the
523 <!ELEMENT entry - - ((%simple; | #PCDATA)*, entry*) >
524 <!ATTLIST entry id ID #IMPLIED
528 sort CDATA #IMPLIED >
531 #define MAIN_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->main
532 #define LOCS_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->locs
534 while (p_seg != NULL)
537 nextKey = AsciiKeyword(_DtCvContainerListOfSeg(p_seg),
538 parent_key, &strSize);
543 /* We have the next keyword. Hang onto it and add it to the list
544 once we get the array of topics. We don't add it yet because if
545 there are no topics we want to throw it away. (Silently ignoring
546 keywords which specify no topics is an undocumented feature.) */
548 /* Now get the list of topics. */
550 if (NULL != FrmtPrivInfoPtr(p_seg) && NULL != _SdlSegEntryInfo(p_seg)
551 && (ProcessLocations(MAIN_STRINGS, &topics) == -1 ||
552 ProcessLocations(LOCS_STRINGS, &topics) == -1))
560 vol->keywords = (char **) _DtHelpCeAddPtrToArray (
561 (void **) vol->keywords,
563 vol->keywordTopics = (char ***) _DtHelpCeAddPtrToArray (
564 (void **) vol->keywordTopics,
567 * If we just malloc'ed ourselves out of existance...
570 if (vol->keywords == 0 || vol->keywordTopics == 0)
572 if (vol->keywords != NULL)
575 _DtHelpCeFreeStringArray (vol->keywords);
576 _DtHelpCeFreeStringArray (topics);
577 vol->keywords = NULL;
579 if (vol->keywordTopics)
583 for (topicList = vol->keywordTopics; topicList; topicList++)
584 _DtHelpCeFreeStringArray (*topicList);
585 free (vol->keywordTopics);
586 vol->keywordTopics = NULL;
592 if (_DtCvContainerListOfSeg(p_seg) != NULL &&
593 ProcessSubEntries(vol,_DtCvContainerListOfSeg(p_seg),nextKey) == -1)
599 p_seg = p_seg->next_seg;
605 /******************************************************************************
606 * Function: int MapPath (_DtCvSegment *cur_id, int level, char ***ret_ids)
610 * Return Value: 0 if successful, -1 if failure.
612 * Memory: The memory returned in ret_ids is owned by the caller.
614 * Purpose: To come up with a path from the top of the volume to the
617 ******************************************************************************/
620 _DtCvSegment **cur_id,
621 _DtCvSegment *target_el,
627 _DtCvSegment *mySeg = *cur_id;
632 while (mySeg != NULL)
635 * Does this match the target id?
636 * And, is the element a child of the current path?
638 info = _SdlSegToSdlIdInfoPtr(mySeg);
639 myLev = _SdlIdInfoPtrRlevel(info);
640 if (target_el == mySeg && (myLev == -1 || myLev > stop_lev))
643 * matched the target id.
644 * allocate memory and return.
647 if (_SdlIdInfoPtrType(info) == SdlIdVirpage)
653 *ret_ids = (char **) malloc (sizeof(char *) * (lev_cnt + 1));
654 if ((*ret_ids) == NULL)
657 (*ret_ids)[lev_cnt] = NULL;
659 if (_SdlIdInfoPtrType(info) == SdlIdVirpage)
660 (*ret_ids)[lev_cnt - 1] = strdup(_DtCvContainerIdOfSeg(mySeg));
664 else if (myLev != -1 && myLev != hidden_no
665 && _SdlIdInfoPtrType(info) == SdlIdVirpage)
667 char *myId = _DtCvContainerIdOfSeg(mySeg);
670 * If we've hit a virpage that is a sibling or an aunt
671 * set the search pointer to this segment (since this
672 * is where we want to start searching again) and return
673 * a negative on the successful search.
675 if (myLev <= stop_lev)
682 * this virpage is a child of mine, so look at it's children
685 mySeg = mySeg->next_seg;
686 count = MapPath(&mySeg, target_el, myLev, lev_cnt + 1, hidden_no,
690 * successful response on finding the target id in the virpage's
691 * children. Duplicate the virpage's id string and return to
696 (*ret_ids)[lev_cnt] = strdup(myId);
702 else /* did not match the target id and is not a virpage
703 * or is a hidden virpage */
704 mySeg = mySeg->next_seg;
711 /******************************************************************************
712 * Semi-Private Functions
713 ******************************************************************************/
714 /*******************************************************************************
715 * Function: CESDLVolume *_DtHelpCeGetSdlVolumePtr (_DtHelpVolumeHdl vol);
717 * Parameters: vol Specifies the loaded volume.
719 * Return Value: 0 if successful, -1 if a failure occurs
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.)
727 ******************************************************************************/
729 _DtHelpCeGetSdlVolumePtr (
730 _DtHelpVolumeHdl volume)
732 _DtHelpVolume vol = (_DtHelpVolume) volume;
735 return ((CESDLVolume *) vol->vols.sdl_vol);
739 /******************************************************************************
740 * Semi-Public Functions
741 ******************************************************************************/
742 /*******************************************************************************
743 * Function: void _DtHelpCeInitSdlVolume (_DtHelpVolume vol);
745 * Parameters: vol Specifies the loaded volume.
747 * Return Value: 0 if successful, -1 if a failure occurs
751 * Purpose: When the volume is no longer needed, it should be unloaded
752 * with this call. Unloading it frees the memory (which means
753 * any handles on the volume become invalid.)
755 ******************************************************************************/
757 _DtHelpCeInitSdlVolume (
758 _DtHelpVolumeHdl volume)
760 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
763 *sdlVol = DefaultSdlVolume;
767 /*******************************************************************************
768 * Function: void _DtHelpCeOpenSdlVolume (_DtHelpVolume vol);
770 * Parameters: vol Specifies the loaded volume.
772 * Return Value: 0 if successful, -1 if a failure occurs
776 * Purpose: When the volume is no longer needed, it should be unloaded
777 * with this call. Unloading it frees the memory (which means
778 * any handles on the volume become invalid.)
780 ******************************************************************************/
782 _DtHelpCeOpenSdlVolume (
783 _DtHelpVolumeHdl volume)
786 _DtHelpVolume vol = (_DtHelpVolume) volume;
788 sdlVol = (CESDLVolume *) calloc (1, sizeof(CESDLVolume));
791 vol->vols.sdl_vol = (SdlVolumeHandle) sdlVol;
792 _DtHelpCeInitSdlVolume(volume);
793 if (_DtHelpCeFrmtSdlVolumeInfo(vol->volFile,
794 vol, &(vol->check_time)) == 0)
796 vol->sdl_flag = True;
800 vol->vols.sdl_vol = NULL;
807 /*******************************************************************************
808 * Function: void _DtHelpCeCleanSdlVolume (_DtHelpVolume vol);
810 * Parameters: vol Specifies the loaded volume.
812 * Return Value: 0 if successful, -1 if a failure occurs
816 * Purpose: When the volume is no longer needed, it should be unloaded
817 * with this call. Unloading it frees the memory (which means
818 * any handles on the volume become invalid.)
820 ******************************************************************************/
822 _DtHelpCeCleanSdlVolume (
823 _DtHelpVolumeHdl volume)
825 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
829 _DtHelpFreeSegments(sdlVol->snb , _DtCvFALSE, sdlVol->destroy_region,
830 sdlVol->client_data);
831 _DtHelpFreeSegments(sdlVol->title, _DtCvFALSE, sdlVol->destroy_region,
832 sdlVol->client_data);
835 * free the index information
837 FreeEntryInfo(sdlVol->index);
838 _DtHelpFreeSegments(sdlVol->index, _DtCvFALSE, NULL, NULL);
841 * free the toss information.
843 FreeTossInfo(sdlVol->toss);
844 _DtHelpFreeSegments(sdlVol->toss , _DtCvFALSE, NULL, NULL);
849 FreeIds(sdlVol->loids);
850 _DtHelpFreeSegments(sdlVol->loids, _DtCvFALSE, NULL, NULL);
853 * free the document information.
855 if (NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
856 free(_SdlDocInfoPtrLanguage(sdlVol->sdl_info));
858 if (NULL != _SdlDocInfoPtrCharSet(sdlVol->sdl_info))
859 free(_SdlDocInfoPtrCharSet(sdlVol->sdl_info));
861 if (NULL != _SdlDocInfoPtrDocId(sdlVol->sdl_info))
862 free(_SdlDocInfoPtrDocId(sdlVol->sdl_info));
864 if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info))
865 free(_SdlDocInfoPtrFirstPg(sdlVol->sdl_info));
867 if (NULL != _SdlDocInfoPtrSdlDtd(sdlVol->sdl_info))
868 free(_SdlDocInfoPtrSdlDtd(sdlVol->sdl_info));
870 if (NULL != _SdlDocInfoPtrStamp(sdlVol->sdl_info))
871 free(_SdlDocInfoPtrStamp(sdlVol->sdl_info));
873 free(sdlVol->sdl_info);
877 /*******************************************************************************
878 * Function: int _DtHelpCeRereadSdlVolume (_DtHelpVolume vol);
880 * Parameters: vol Specifies the loaded volume.
882 * Return Value: 0 if successful, -1 if a failure occurs
886 * Purpose: When the volume is no longer needed, it should be unloaded
887 * with this call. Unloading it frees the memory (which means
888 * any handles on the volume become invalid.)
890 ******************************************************************************/
892 _DtHelpCeRereadSdlVolume (
893 _DtHelpVolumeHdl volume)
895 _DtHelpCeCleanSdlVolume(volume);
896 _DtHelpCeInitSdlVolume(volume);
897 if (_DtHelpCeFrmtSdlVolumeInfo(_DtHelpCeGetVolumeName(volume),
904 /*******************************************************************************
905 * Function: void _DtHelpCeCloseSdlVolume (_DtHelpVolume vol);
907 * Parameters: vol Specifies the loaded volume.
909 * Return Value: 0 if successful, -1 if a failure occurs
913 * Purpose: When the volume is no longer needed, it should be unloaded
914 * with this call. Unloading it frees the memory (which means
915 * any handles on the volume become invalid.)
917 ******************************************************************************/
919 _DtHelpCeCloseSdlVolume (
920 _DtHelpVolumeHdl volume)
922 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
926 _DtHelpCeCleanSdlVolume(volume);
931 /*****************************************************************************
932 * Function: Boolean _DtHelpCeGetSdlHomeTopicId (_DtHelpVolume vol,
934 * char *ret_name, int *ret_offset)
936 * Parameters: vol Specifies the loaded volume
937 * target_id Specifies target location ID
938 * ret_name Returns a null terminated string
939 * containing a fully qualified path to
940 * the file that contains 'target_id'.
941 * ret_offset Returns the offset into 'ret_name'
942 * to the topic that contains 'target_id'.
944 * Memory own by caller:
947 * Returns: True if successful, False if a failure occurs
949 * errno Values: EINVAL Specifies an invalid parameter was
952 * CEErrorLocIdNotFound
953 * Specifies that 'locId' was not
956 * Purpose: Find which topic contains a specified locationID.
958 *****************************************************************************/
960 _DtHelpCeGetSdlHomeTopicId (
961 _DtHelpVolumeHdl volume)
963 _DtCvSegment *idSegs;
964 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
966 if (sdlVol->sdl_info != NULL)
969 * Was the first page topic declared in the header?
971 if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info))
972 return (_SdlDocInfoPtrFirstPg(sdlVol->sdl_info));
975 * have to search the list of ids for the home topic. This is a
976 * bit of a kludge since we are looking for a specific string in
977 * the rssi. But this is for backwards compatibility since the
978 * Snapshot release of the help system were released with out
979 * the first-page attribute and relied on _hometopic.
981 * Plus, first-page is #IMPLIED, which means that the parser
982 * that generated this SDL document does not have to use this
985 if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0)
988 while (idSegs != NULL)
990 if (SdlIdVirpage == _SdlSegToSdlIdInfoType(idSegs) &&
991 _DtHelpCeStrCaseCmpLatin1(_SdlIdInfoPtrRssi(
992 _SdlSegToSdlIdInfoPtr(idSegs)),
994 return _DtCvContainerIdOfSeg(idSegs);
996 idSegs = idSegs->next_seg;
1003 /*****************************************************************************
1004 * Function: Boolean _DtHelpCeFindSdlId (_DtHelpVolume vol, char *target_id,
1005 * char *ret_name, int *ret_offset)
1007 * Parameters: vol Specifies the loaded volume
1008 * target_id Specifies target location ID
1009 * ret_name Returns a null terminated string
1010 * containing a fully qualified path to
1011 * the file that contains 'target_id'.
1012 * ret_offset Returns the offset into 'ret_name'
1013 * to the topic that contains 'target_id'.
1015 * Memory own by caller:
1018 * Returns: True if successful, False if a failure occurs
1020 * errno Values: EINVAL Specifies an invalid parameter was
1023 * CEErrorLocIdNotFound
1024 * Specifies that 'locId' was not
1027 * Purpose: Find which topic contains a specified locationID.
1029 *****************************************************************************/
1031 _DtHelpCeFindSdlId (
1032 _DtHelpVolumeHdl volume,
1038 _DtHelpVolume vol = (_DtHelpVolume) volume;
1041 pEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, fd);
1045 if (ret_name != NULL)
1046 *ret_name = strdup(vol->volFile);
1047 *ret_offset = _SdlIdInfoPtrOffset(_SdlSegToSdlIdInfoPtr(pEl));
1054 /*****************************************************************************
1055 * Function: int _DtHelpCeGetSdlKeywordList (
1059 * Returns: 0 if successful, -1 if not.
1063 * Purpose: Get the KeywordList for an SDL volume.
1065 *****************************************************************************/
1067 _DtHelpCeGetSdlKeywordList (
1068 _DtHelpVolumeHdl volume)
1070 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
1072 if (_DtHelpCeGetSdlVolIndex(volume) != 0 || NULL == sdlVol->index
1073 || NULL == _DtCvContainerListOfSeg(sdlVol->index))
1076 return(ProcessEntry(((_DtHelpVolume) volume),
1077 _DtCvContainerListOfSeg(sdlVol->index), NULL));
1080 /*****************************************************************************
1081 * Function: int _DtHelpCeGetSdlVolumeAsciiAbstract(volume);
1085 * Returns: 0 if successful, -1 if not.
1089 * Purpose: Get the KeywordList for an SDL volume.
1091 *****************************************************************************/
1093 _DtHelpCeGetSdlVolumeAsciiAbstract(
1094 _DtHelpVolumeHdl volume)
1096 return(_DtHelpCeFrmtSdlVolumeAbstractToAscii(volume));
1099 /*****************************************************************************
1100 * Function: int _DtHelpCeGetSdlIdPath(volume, target_id, ret_ids);
1104 * Returns: > 0 if successful, -1 if not.
1106 * Memory: The memory returned is owned by the caller.
1108 * Purpose: Get the list of location ids between the top and the
1111 *****************************************************************************/
1113 _DtHelpCeGetSdlIdPath(
1114 _DtHelpVolumeHdl volume,
1118 _DtCvSegment *idSegs;
1119 _DtCvSegment *targetEl;
1122 targetEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1);
1124 if (targetEl == NULL)
1129 if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0)
1132 if (_SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume)) >= SDL_DTD_1_1)
1135 return (MapPath(&idSegs, targetEl, -1, 0, hiddenNo, ret_ids));
1138 /*****************************************************************************
1139 * Function: _DtCvSegment *_DtHelpCeMapSdlIdToSegment(volume, target_id);
1143 * Returns: > 0 if successful, -1 if not.
1147 * Purpose: Get the list of location ids between the top and the
1150 *****************************************************************************/
1152 _DtHelpCeMapSdlIdToSegment(
1153 _DtHelpVolumeHdl volume,
1154 const char *target_id,
1157 int underScore = False;
1159 _DtCvSegment *idSegs;
1161 char resStr[128] = "SDL-RESERVED-";
1163 minorNo = _SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume));
1165 if (*target_id == '_')
1168 * parsers generating SDL_DTD_1_0 and earlier put the special
1169 * access points (_hometopic, _abstract, _copyright, etc.) in
1172 if (minorNo < SDL_DTD_1_1)
1177 strcat(resStr, target_id);
1182 if (_DtHelpCeGetSdlVolIds(volume, fd, &idSegs) != 0)
1185 while (idSegs != NULL)
1187 if (underScore == True)
1188 idString = _SdlIdInfoPtrRssi(_SdlSegToSdlIdInfoPtr(idSegs));
1190 idString = _DtCvContainerIdOfSeg(idSegs);
1192 if (idString != NULL &&
1193 _DtHelpCeStrCaseCmpLatin1(idString, target_id) == 0)
1196 idSegs = idSegs->next_seg;
1202 /*****************************************************************************
1203 * Function: int _DtHelpCeMapIdToSdlTopicId(volume, target_id);
1207 * Returns: > 0 if successful, -1 if not.
1211 * Purpose: Get the id of the virpage containing the target_id.
1213 *****************************************************************************/
1215 _DtHelpCeMapIdToSdlTopicId(
1216 _DtHelpVolumeHdl volume,
1217 const char *target_id,
1221 _DtCvSegment *idList;
1222 _DtCvSegment *idSeg;
1225 if (_DtHelpCeGetSdlVolIds(volume, -1, &idList) == 0)
1227 idSeg = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1);
1230 while (found == -1 && idList != NULL)
1232 idInfo = _SdlSegToSdlIdInfoPtr(idList);
1233 if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage)
1234 *ret_id = _DtCvContainerIdOfSeg(idList);
1236 if (idList == idSeg)
1239 idList = idList->next_seg;
1247 /*****************************************************************************
1248 * Function: char * _DtHelpCeGetSdlVolCharSet(volume);
1252 * Returns: the pointer to the locale string. Null otherwise.
1256 * Purpose: Get the locale of the volume.
1258 *****************************************************************************/
1260 _DtHelpCeGetSdlVolCharSet(
1261 _DtHelpVolumeHdl volume)
1263 const char *charSet = IsoString;
1264 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
1266 if (sdlVol->sdl_info != NULL &&
1267 NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
1268 charSet = _SdlDocInfoPtrCharSet(sdlVol->sdl_info);
1273 /*****************************************************************************
1274 * Function: char * _DtHelpCeGetSdlVolLanguage(volume);
1278 * Returns: the pointer to the language used in the volume.
1282 * Purpose: Get the locale of the volume.
1284 *****************************************************************************/
1286 _DtHelpCeGetSdlVolLanguage(
1287 _DtHelpVolumeHdl volume)
1289 char *language = "C";
1290 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
1292 if (sdlVol->sdl_info != NULL &&
1293 NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
1294 language = _SdlDocInfoPtrLanguage(sdlVol->sdl_info);
1299 /*****************************************************************************
1300 * Function: char * _DtHelpCeGetSdlVolumeLocale(volume);
1304 * Returns: the pointer to the locale string. Null otherwise.
1308 * Purpose: Get the locale of the volume.
1310 *****************************************************************************/
1312 _DtHelpCeGetSdlVolumeLocale(
1313 _DtHelpVolumeHdl volume)
1318 const char *charSet;
1320 lang = _DtHelpCeGetSdlVolLanguage(volume);
1321 charSet = _DtHelpCeGetSdlVolCharSet(volume);
1323 langLen = strlen(lang);
1324 locale = (char *) malloc (langLen + strlen(charSet) + 2);
1327 strcpy(locale, lang);
1328 if (langLen != 0 && *charSet != '\0')
1330 locale[langLen++] = '.';
1331 strcpy(&(locale[langLen]), charSet);
1338 /*****************************************************************************
1339 * Function: int _DtHelpCeGetSdlDocStamp(volume, ret_doc, ret_time);
1343 * Returns: 0 if successful, -2 if the volume does not contain
1344 * one or the other, -1 if any other failure.
1346 * Memory: The Caller owns the memory returned in ret_doc and ret_time.
1348 * Purpose: Get the doc id and time stamp of a volume.
1350 *****************************************************************************/
1352 _DtHelpCeGetSdlDocStamp(
1353 _DtHelpVolumeHdl volume,
1359 char *timestamp = NULL;
1360 CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
1362 if (sdlVol->sdl_info != NULL)
1365 if (NULL != _SdlDocInfoPtrDocId(sdlVol->sdl_info))
1366 docId = strdup(_SdlDocInfoPtrDocId(sdlVol->sdl_info));
1370 if (NULL != _SdlDocInfoPtrStamp(sdlVol->sdl_info))
1371 timestamp = strdup(_SdlDocInfoPtrStamp(sdlVol->sdl_info));
1376 if (ret_doc != NULL)
1378 if (ret_time != NULL)
1379 *ret_time = timestamp;
1381 if (result == 0 && (docId == NULL || timestamp == NULL))
1387 /*****************************************************************************
1388 * Function: int _DtHelpCeGetSdlTopicChildren(
1392 * Returns: pointer to the element, Null otherwise.
1396 * Purpose: Find the specified element.
1398 *****************************************************************************/
1400 _DtHelpCeGetSdlTopicChildren(
1401 _DtHelpVolumeHdl volume,
1408 _DtCvSegment *idSeg;
1412 * Find the target id.
1414 idSeg = _DtHelpCeMapSdlIdToSegment(volume, target, -1);
1417 * save this level and start looking for its children at the next seg.
1422 idInfo = _SdlSegToSdlIdInfoPtr(idSeg);
1423 segLev = _SdlIdInfoPtrRlevel(idInfo) + 1;
1424 idSeg = idSeg->next_seg;
1428 * process any virpage that has the correct level
1430 while (idSeg != NULL && done == False)
1432 idInfo = _SdlSegToSdlIdInfoPtr(idSeg);
1433 if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage)
1436 * If greater, we're at the next sibling.
1438 if (segLev > _SdlIdInfoPtrRlevel(idInfo))
1440 else if (segLev == _SdlIdInfoPtrRlevel(idInfo))
1442 *ret_ids = (char **) _DtHelpCeAddPtrToArray( (void **) *ret_ids,
1443 (void *)(strdup(_DtCvContainerIdOfSeg(idSeg))));
1444 if ((*ret_ids) == NULL)
1450 idSeg = idSeg->next_seg;