1455 lines
37 KiB
C
1455 lines
37 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these librararies and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $XConsortium: AccessSDL.c /main/13 1996/09/30 11:22:14 cde-hp $ */
|
|
/************************************<+>*************************************
|
|
****************************************************************************
|
|
**
|
|
** File: AccessSDL.c
|
|
**
|
|
** Project: Run Time Project File Access
|
|
**
|
|
** Description: This body of code handles the access routines for the
|
|
** SDL files.
|
|
**
|
|
**
|
|
** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
|
|
**
|
|
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
|
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
|
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
|
** (c) Copyright 1993, 1994 Novell, Inc.
|
|
**
|
|
**
|
|
****************************************************************************
|
|
************************************<+>*************************************/
|
|
|
|
/*
|
|
* system includes
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xresource.h>
|
|
|
|
/*
|
|
* Canvas Engine includes
|
|
*/
|
|
#include "CanvasP.h"
|
|
#include "CanvasSegP.h"
|
|
|
|
/*
|
|
* private includes
|
|
*/
|
|
#include "bufioI.h"
|
|
#include "CleanUpI.h"
|
|
#include "CvStringI.h"
|
|
#include "FontAttrI.h"
|
|
#include "Access.h"
|
|
#include "AccessP.h"
|
|
#include "AccessSDLP.h"
|
|
#include "AccessSDLI.h"
|
|
#include "FormatUtilI.h"
|
|
#include "FormatSDLI.h"
|
|
#include "StringFuncsI.h"
|
|
#include "UtilSDLI.h"
|
|
|
|
#ifdef NLS16
|
|
#endif
|
|
|
|
/******** Private Defines ********/
|
|
/******** End Private Defines ********/
|
|
|
|
/******** Private Function Declarations ********/
|
|
static int ProcessEntry (
|
|
_DtHelpVolume vol,
|
|
_DtCvSegment *p_seg,
|
|
char *parent_key);
|
|
/******** End Private Function Declarations ********/
|
|
|
|
/******** Private Variable Declarations ********/
|
|
static const char *IsoString = "ISO-8859-1";
|
|
static const CESDLVolume DefaultSdlVolume =
|
|
{
|
|
NULL, /* _DtCvSegment *sdl_info; */
|
|
NULL, /* _DtCvSegment *toss; */
|
|
NULL, /* _DtCvSegment *loids; */
|
|
NULL, /* _DtCvSegment *index; */
|
|
NULL, /* _DtCvSegment *title; */
|
|
NULL, /* _DtCvSegment *snb; */
|
|
0, /* short minor_no; */
|
|
False, /* short title_processed; */
|
|
};
|
|
|
|
/******** Private Macro Declarations ********/
|
|
|
|
/******************************************************************************
|
|
* Private Functions
|
|
******************************************************************************/
|
|
/******************************************************************************
|
|
* Function: void FreeIds (
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Return Value:
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose:
|
|
*
|
|
******************************************************************************/
|
|
static void
|
|
FreeIds (
|
|
_DtCvSegment *loids)
|
|
{
|
|
_DtCvSegment *p_seg;
|
|
|
|
if (NULL == loids)
|
|
return;
|
|
|
|
p_seg = _DtCvContainerListOfSeg(loids);
|
|
|
|
while (NULL != p_seg)
|
|
{
|
|
if (NULL != _SdlSegToSdlIdInfoPtr(p_seg))
|
|
{
|
|
if (NULL != _SdlSegToSdlIdInfoRssi(p_seg))
|
|
free(_SdlSegToSdlIdInfoRssi(p_seg));
|
|
|
|
free(_SdlSegToSdlIdInfoPtr(p_seg));
|
|
}
|
|
|
|
p_seg = p_seg->next_seg;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function: void FreeTossInfo (
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Return Value:
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose:
|
|
*
|
|
******************************************************************************/
|
|
static void
|
|
FreeTossInfo (
|
|
_DtCvSegment *toss)
|
|
{
|
|
_DtCvSegment *p_seg;
|
|
SDLTossInfo *info;
|
|
|
|
if (NULL == toss)
|
|
return;
|
|
|
|
p_seg = _DtCvContainerListOfSeg(toss);
|
|
|
|
while (NULL != p_seg)
|
|
{
|
|
info = (SDLTossInfo *) _SdlSegTossInfo(p_seg);
|
|
|
|
/* free the ssi */
|
|
if (NULL != _SdlTossInfoPtrSsi(info))
|
|
free(_SdlTossInfoPtrSsi(info));
|
|
|
|
/* free the colj,colw or the enter, exit data */
|
|
if (NULL != _SdlTossInfoPtrStr1(info))
|
|
free(_SdlTossInfoPtrStr1(info));
|
|
if (NULL != _SdlTossInfoPtrStr2(info))
|
|
free(_SdlTossInfoPtrStr2(info));
|
|
|
|
/* free the font strings */
|
|
if (NULL != _DtHelpFontHintsColor(_SdlTossInfoPtrFontSpecs(info)))
|
|
free(_DtHelpFontHintsColor(_SdlTossInfoPtrFontSpecs(info)));
|
|
if (NULL != _DtHelpFontHintsXlfd(_SdlTossInfoPtrFontSpecs(info)))
|
|
free(_DtHelpFontHintsXlfd(_SdlTossInfoPtrFontSpecs(info)));
|
|
if (NULL != _DtHelpFontHintsXlfdb(_SdlTossInfoPtrFontSpecs(info)))
|
|
free(_DtHelpFontHintsXlfdb(_SdlTossInfoPtrFontSpecs(info)));
|
|
if (NULL != _DtHelpFontHintsXlfdi(_SdlTossInfoPtrFontSpecs(info)))
|
|
free(_DtHelpFontHintsXlfdi(_SdlTossInfoPtrFontSpecs(info)));
|
|
if (NULL != _DtHelpFontHintsXlfdib(_SdlTossInfoPtrFontSpecs(info)))
|
|
free(_DtHelpFontHintsXlfdib(_SdlTossInfoPtrFontSpecs(info)));
|
|
if (NULL != _DtHelpFontHintsTypeNam(_SdlTossInfoPtrFontSpecs(info)))
|
|
free(_DtHelpFontHintsTypeNam(_SdlTossInfoPtrFontSpecs(info)));
|
|
if (NULL != _DtHelpFontHintsTypeNamb(_SdlTossInfoPtrFontSpecs(info)))
|
|
free(_DtHelpFontHintsTypeNamb(_SdlTossInfoPtrFontSpecs(info)));
|
|
if (NULL != _DtHelpFontHintsTypeNami(_SdlTossInfoPtrFontSpecs(info)))
|
|
free(_DtHelpFontHintsTypeNami(_SdlTossInfoPtrFontSpecs(info)));
|
|
if (NULL != _DtHelpFontHintsTypeNamib(_SdlTossInfoPtrFontSpecs(info)))
|
|
free(_DtHelpFontHintsTypeNamib(_SdlTossInfoPtrFontSpecs(info)));
|
|
|
|
free(info);
|
|
|
|
p_seg = p_seg->next_seg;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function: void FreeEntryInfo (
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Return Value:
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose:
|
|
*
|
|
******************************************************************************/
|
|
static void
|
|
FreeEntryInfo (
|
|
_DtCvSegment *index)
|
|
{
|
|
_DtCvSegment *p_seg;
|
|
SDLEntryInfo *info;
|
|
|
|
if (NULL == index)
|
|
return;
|
|
|
|
p_seg = _DtCvContainerListOfSeg(index);
|
|
|
|
while (NULL != p_seg)
|
|
{
|
|
info = _SdlSegToSdlEntryInfo(p_seg);
|
|
|
|
if (NULL != info)
|
|
{
|
|
if (NULL != info->main)
|
|
free(info->main);
|
|
if (NULL != info->locs)
|
|
free(info->locs);
|
|
if (NULL != info->syns)
|
|
free(info->syns);
|
|
if (NULL != info->sort)
|
|
free(info->sort);
|
|
}
|
|
|
|
if (_DtCvIsSegContainer(p_seg))
|
|
FreeEntryInfo(p_seg);
|
|
|
|
free(info);
|
|
|
|
p_seg = p_seg->next_seg;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function: int ProcessSubEntries (
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Return Value:
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose:
|
|
*
|
|
******************************************************************************/
|
|
static int
|
|
ProcessSubEntries (
|
|
_DtHelpVolume vol,
|
|
_DtCvSegment *p_seg,
|
|
char *parent_key)
|
|
{
|
|
while (p_seg != NULL)
|
|
{
|
|
/*
|
|
* the only sub containers of an entry that should have an non-null
|
|
* internal pointer should be a sub <entry>.
|
|
*/
|
|
if (_DtCvIsSegContainer(p_seg) && NULL != _SdlSegEntryInfo(p_seg)
|
|
&& ProcessEntry(vol, _DtCvContainerListOfSeg(p_seg),
|
|
parent_key) == -1)
|
|
return -1;
|
|
|
|
p_seg = p_seg->next_seg;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function: int AsciiKeyword (
|
|
*
|
|
* Parameters:
|
|
* p_list The segment list to process for strings.
|
|
* parent_str The string to append information onto.
|
|
* This may be NULL.
|
|
* str_size The malloc'ed size of the parent string.
|
|
* Includes room for the null byte. If zero
|
|
* and parent_str is non-null, then memory
|
|
* must be malloc'ed and parent_str copied
|
|
* into it. Otherwise, goodStr can just
|
|
* reuse parent_str.
|
|
*
|
|
* Return Value:
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose:
|
|
*
|
|
******************************************************************************/
|
|
static char *
|
|
AsciiKeyword (
|
|
_DtCvSegment *p_list,
|
|
char *parent_str,
|
|
int *str_size)
|
|
{
|
|
int len = 0;
|
|
int newLen;
|
|
char *goodStr;
|
|
|
|
/*
|
|
* if a starting string has been passed in, use it.
|
|
*/
|
|
if (NULL != parent_str)
|
|
{
|
|
/*
|
|
* get the actual byte count.
|
|
*/
|
|
len = strlen(parent_str) + 1;
|
|
|
|
/*
|
|
* is the starting value zero? If so, we have to copy it.
|
|
*/
|
|
if (0 == *str_size)
|
|
{
|
|
parent_str = strdup(parent_str);
|
|
if (NULL == parent_str)
|
|
return NULL;
|
|
|
|
*str_size = len;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* start with the parent_string
|
|
*/
|
|
goodStr = parent_str;
|
|
|
|
while (p_list != NULL)
|
|
{
|
|
if (_DtCvIsSegString(p_list))
|
|
{
|
|
/*
|
|
* get the number of characters in the next string.
|
|
*/
|
|
newLen = _DtCvStrLen(_DtCvStringOfStringSeg(p_list),
|
|
_DtCvIsSegWideChar(p_list));
|
|
|
|
/*
|
|
* if this is wide char string, multiply the count by
|
|
* MB_CUR_MAX to get the maximum number of bytes this
|
|
* string would take.
|
|
*/
|
|
if (_DtCvIsSegWideChar(p_list))
|
|
newLen = newLen * MB_CUR_MAX;
|
|
|
|
/*
|
|
* now add it to our previous size.
|
|
*/
|
|
len += newLen;
|
|
|
|
/*
|
|
* are we starting from scratch?
|
|
*/
|
|
if (goodStr == NULL)
|
|
{
|
|
/*
|
|
* include a byte for the end-of-string character.
|
|
*/
|
|
len++;
|
|
|
|
/*
|
|
* malloc the memory
|
|
*/
|
|
goodStr = (char *) malloc (len);
|
|
|
|
}
|
|
else if (*str_size < len) /* does this have to grow? */
|
|
goodStr = (char *) realloc (goodStr, len);
|
|
|
|
if (goodStr == NULL)
|
|
return NULL;
|
|
|
|
/*
|
|
* remember the absolute size of the memory for the string
|
|
*/
|
|
if (*str_size < len)
|
|
*str_size = len;
|
|
|
|
if (_DtCvIsSegWideChar(p_list))
|
|
{
|
|
/*
|
|
* back up to the insertion point.
|
|
*/
|
|
len -= newLen;
|
|
|
|
/*
|
|
* transfer
|
|
*/
|
|
newLen = wcstombs(&goodStr[len - 1],
|
|
(wchar_t *) _DtCvStringOfStringSeg(p_list),
|
|
newLen + 1);
|
|
if ((size_t) -1 == newLen)
|
|
return NULL;
|
|
|
|
len += newLen;
|
|
}
|
|
else
|
|
strcpy(&goodStr[len - newLen - 1],
|
|
(char *) _DtCvStringOfStringSeg(p_list));
|
|
}
|
|
|
|
/*
|
|
* the only containers in an <entry> that should have a non-null
|
|
* internal pointer should be a sub <entry>. Therefore, if null,
|
|
* process since it could be a <key>, <sphrase>, etc.
|
|
*/
|
|
else if (_DtCvIsSegContainer(p_list) &&
|
|
NULL == _SdlSegEntryInfo(p_list))
|
|
{
|
|
goodStr = AsciiKeyword(_DtCvContainerListOfSeg(p_list), goodStr,
|
|
str_size);
|
|
if (goodStr == NULL)
|
|
return NULL;
|
|
|
|
len = strlen(goodStr) + 1;
|
|
}
|
|
|
|
p_list = p_list->next_seg;
|
|
}
|
|
|
|
return goodStr;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function: int ProcessLocations (
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Return Value:
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose:
|
|
*
|
|
******************************************************************************/
|
|
static int
|
|
ProcessLocations (
|
|
char *locs,
|
|
char ***list)
|
|
{
|
|
char **myList = NULL;
|
|
char *nextLoc;
|
|
|
|
while (locs != NULL && *locs != '\0')
|
|
{
|
|
locs = _DtHelpGetNxtToken(locs, &nextLoc);
|
|
if (nextLoc == NULL)
|
|
return -1;
|
|
|
|
if (*nextLoc != '\0')
|
|
{
|
|
myList = (char **) _DtHelpCeAddPtrToArray ((void **) myList,
|
|
(void *) nextLoc);
|
|
if (myList == NULL)
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
*list = myList;
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function: int ProcessEntry (_DtHelpVolume vol)
|
|
*
|
|
* Parameters: vol Specifies the volume whose keywords need to be
|
|
* loaded from disk. Once loaded, they can be
|
|
* accessed through the fields of the volume structure.
|
|
*
|
|
* Return Value: 0 if successful, -1 if a failure occurs
|
|
*
|
|
* errno Values: CEErrorMalloc
|
|
* CEErrorIllegalDatabaseFile
|
|
* Specifies that the keyword file is
|
|
* invalid or corrupt.
|
|
* CEErrorMissingKeywordsRes
|
|
* Specifies that the keyword file does
|
|
* not contain the 'Keywords/keywords'
|
|
* resource or the resource is NULL
|
|
*
|
|
*
|
|
* Purpose: Load the keywords associated with a volume.
|
|
*
|
|
******************************************************************************/
|
|
static int
|
|
ProcessEntry (
|
|
_DtHelpVolume vol,
|
|
_DtCvSegment *p_seg,
|
|
char *parent_key)
|
|
{
|
|
int strSize;
|
|
char **topics;
|
|
char *nextKey = NULL;
|
|
|
|
/* Now parse the string into the appropriate arrays. The string has the
|
|
following syntax:
|
|
|
|
<!ELEMENT entry - - ((%simple; | #PCDATA)*, entry*) >
|
|
<!ATTLIST entry id ID #IMPLIED
|
|
main IDREFS #IMPLIED
|
|
locs IDREFS #IMPLIED
|
|
syns IDREFS #IMPLIED
|
|
sort CDATA #IMPLIED >
|
|
*/
|
|
|
|
#define MAIN_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->main
|
|
#define LOCS_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->locs
|
|
|
|
while (p_seg != NULL)
|
|
{
|
|
strSize = 0;
|
|
nextKey = AsciiKeyword(_DtCvContainerListOfSeg(p_seg),
|
|
parent_key, &strSize);
|
|
|
|
if (nextKey == NULL)
|
|
return -1;
|
|
|
|
/* We have the next keyword. Hang onto it and add it to the list
|
|
once we get the array of topics. We don't add it yet because if
|
|
there are no topics we want to throw it away. (Silently ignoring
|
|
keywords which specify no topics is an undocumented feature.) */
|
|
|
|
/* Now get the list of topics. */
|
|
topics = NULL;
|
|
if (NULL != FrmtPrivInfoPtr(p_seg) && NULL != _SdlSegEntryInfo(p_seg)
|
|
&& (ProcessLocations(MAIN_STRINGS, &topics) == -1 ||
|
|
ProcessLocations(LOCS_STRINGS, &topics) == -1))
|
|
{
|
|
free(nextKey);
|
|
return -1;
|
|
}
|
|
|
|
if (topics != NULL)
|
|
{
|
|
vol->keywords = (char **) _DtHelpCeAddPtrToArray (
|
|
(void **) vol->keywords,
|
|
(void *) nextKey);
|
|
vol->keywordTopics = (char ***) _DtHelpCeAddPtrToArray (
|
|
(void **) vol->keywordTopics,
|
|
(void *) topics);
|
|
/*
|
|
* If we just malloc'ed ourselves out of existance...
|
|
* stop here.
|
|
*/
|
|
if (vol->keywords == 0 || vol->keywordTopics == 0)
|
|
{
|
|
if (vol->keywords != NULL)
|
|
{
|
|
free(nextKey);
|
|
_DtHelpCeFreeStringArray (vol->keywords);
|
|
_DtHelpCeFreeStringArray (topics);
|
|
vol->keywords = NULL;
|
|
}
|
|
if (vol->keywordTopics)
|
|
{
|
|
char ***topicList;
|
|
|
|
for (topicList = vol->keywordTopics; topicList; topicList++)
|
|
_DtHelpCeFreeStringArray (*topicList);
|
|
free (vol->keywordTopics);
|
|
vol->keywordTopics = NULL;
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (_DtCvContainerListOfSeg(p_seg) != NULL &&
|
|
ProcessSubEntries(vol,_DtCvContainerListOfSeg(p_seg),nextKey) == -1)
|
|
return -1;
|
|
|
|
if (topics == NULL)
|
|
free (nextKey);
|
|
|
|
p_seg = p_seg->next_seg;
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Function: int MapPath (_DtCvSegment *cur_id, int level, char ***ret_ids)
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Return Value: 0 if successful, -1 if failure.
|
|
*
|
|
* Memory: The memory returned in ret_ids is owned by the caller.
|
|
*
|
|
* Purpose: To come up with a path from the top of the volume to the
|
|
* target id.
|
|
*
|
|
******************************************************************************/
|
|
static int
|
|
MapPath (
|
|
_DtCvSegment **cur_id,
|
|
_DtCvSegment *target_el,
|
|
int stop_lev,
|
|
int lev_cnt,
|
|
int hidden_no,
|
|
char ***ret_ids)
|
|
{
|
|
_DtCvSegment *mySeg = *cur_id;
|
|
int count = -1;
|
|
int myLev;
|
|
SDLIdInfo *info;
|
|
|
|
while (mySeg != NULL)
|
|
{
|
|
/*
|
|
* Does this match the target id?
|
|
* And, is the element a child of the current path?
|
|
*/
|
|
info = _SdlSegToSdlIdInfoPtr(mySeg);
|
|
myLev = _SdlIdInfoPtrRlevel(info);
|
|
if (target_el == mySeg && (myLev == -1 || myLev > stop_lev))
|
|
{
|
|
/*
|
|
* matched the target id.
|
|
* allocate memory and return.
|
|
*/
|
|
count = 0;
|
|
if (_SdlIdInfoPtrType(info) == SdlIdVirpage)
|
|
{
|
|
count++;
|
|
lev_cnt++;
|
|
}
|
|
|
|
*ret_ids = (char **) malloc (sizeof(char *) * (lev_cnt + 1));
|
|
if ((*ret_ids) == NULL)
|
|
return -1;
|
|
|
|
(*ret_ids)[lev_cnt] = NULL;
|
|
|
|
if (_SdlIdInfoPtrType(info) == SdlIdVirpage)
|
|
(*ret_ids)[lev_cnt - 1] = strdup(_DtCvContainerIdOfSeg(mySeg));
|
|
|
|
return count;
|
|
}
|
|
else if (myLev != -1 && myLev != hidden_no
|
|
&& _SdlIdInfoPtrType(info) == SdlIdVirpage)
|
|
{
|
|
char *myId = _DtCvContainerIdOfSeg(mySeg);
|
|
|
|
/*
|
|
* If we've hit a virpage that is a sibling or an aunt
|
|
* set the search pointer to this segment (since this
|
|
* is where we want to start searching again) and return
|
|
* a negative on the successful search.
|
|
*/
|
|
if (myLev <= stop_lev)
|
|
{
|
|
*cur_id = mySeg;
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* this virpage is a child of mine, so look at it's children
|
|
* for the target id.
|
|
*/
|
|
mySeg = mySeg->next_seg;
|
|
count = MapPath(&mySeg, target_el, myLev, lev_cnt + 1, hidden_no,
|
|
ret_ids);
|
|
|
|
/*
|
|
* successful response on finding the target id in the virpage's
|
|
* children. Duplicate the virpage's id string and return to
|
|
* my parent.
|
|
*/
|
|
if (count != -1)
|
|
{
|
|
(*ret_ids)[lev_cnt] = strdup(myId);
|
|
|
|
count++;
|
|
return count;
|
|
}
|
|
}
|
|
else /* did not match the target id and is not a virpage
|
|
* or is a hidden virpage */
|
|
mySeg = mySeg->next_seg;
|
|
}
|
|
|
|
*cur_id = mySeg;
|
|
return -1;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Semi-Private Functions
|
|
******************************************************************************/
|
|
/*******************************************************************************
|
|
* Function: CESDLVolume *_DtHelpCeGetSdlVolumePtr (_DtHelpVolumeHdl vol);
|
|
*
|
|
* Parameters: vol Specifies the loaded volume.
|
|
*
|
|
* Return Value: 0 if successful, -1 if a failure occurs
|
|
*
|
|
* errno Values: None
|
|
*
|
|
* Purpose: When the volume is no longer needed, it should be unloaded
|
|
* with this call. Unloading it frees the memory (which means
|
|
* any handles on the volume become invalid.)
|
|
*
|
|
******************************************************************************/
|
|
CESDLVolume *
|
|
_DtHelpCeGetSdlVolumePtr (
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
_DtHelpVolume vol = (_DtHelpVolume) volume;
|
|
|
|
if (vol != NULL)
|
|
return ((CESDLVolume *) vol->vols.sdl_vol);
|
|
return NULL;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Semi-Public Functions
|
|
******************************************************************************/
|
|
/*******************************************************************************
|
|
* Function: void _DtHelpCeInitSdlVolume (_DtHelpVolume vol);
|
|
*
|
|
* Parameters: vol Specifies the loaded volume.
|
|
*
|
|
* Return Value: 0 if successful, -1 if a failure occurs
|
|
*
|
|
* errno Values: None
|
|
*
|
|
* Purpose: When the volume is no longer needed, it should be unloaded
|
|
* with this call. Unloading it frees the memory (which means
|
|
* any handles on the volume become invalid.)
|
|
*
|
|
******************************************************************************/
|
|
void
|
|
_DtHelpCeInitSdlVolume (
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
|
|
|
|
if (sdlVol != NULL)
|
|
*sdlVol = DefaultSdlVolume;
|
|
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function: void _DtHelpCeOpenSdlVolume (_DtHelpVolume vol);
|
|
*
|
|
* Parameters: vol Specifies the loaded volume.
|
|
*
|
|
* Return Value: 0 if successful, -1 if a failure occurs
|
|
*
|
|
* errno Values: None
|
|
*
|
|
* Purpose: When the volume is no longer needed, it should be unloaded
|
|
* with this call. Unloading it frees the memory (which means
|
|
* any handles on the volume become invalid.)
|
|
*
|
|
******************************************************************************/
|
|
int
|
|
_DtHelpCeOpenSdlVolume (
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
CESDLVolume *sdlVol;
|
|
_DtHelpVolume vol = (_DtHelpVolume) volume;
|
|
|
|
sdlVol = (CESDLVolume *) calloc (1, sizeof(CESDLVolume));
|
|
if (sdlVol != NULL)
|
|
{
|
|
vol->vols.sdl_vol = (SdlVolumeHandle) sdlVol;
|
|
_DtHelpCeInitSdlVolume(volume);
|
|
if (_DtHelpCeFrmtSdlVolumeInfo(vol->volFile,
|
|
vol, &(vol->check_time)) == 0)
|
|
{
|
|
vol->sdl_flag = True;
|
|
return 0;
|
|
}
|
|
|
|
vol->vols.sdl_vol = NULL;
|
|
free(sdlVol);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function: void _DtHelpCeCleanSdlVolume (_DtHelpVolume vol);
|
|
*
|
|
* Parameters: vol Specifies the loaded volume.
|
|
*
|
|
* Return Value: 0 if successful, -1 if a failure occurs
|
|
*
|
|
* errno Values: None
|
|
*
|
|
* Purpose: When the volume is no longer needed, it should be unloaded
|
|
* with this call. Unloading it frees the memory (which means
|
|
* any handles on the volume become invalid.)
|
|
*
|
|
******************************************************************************/
|
|
void
|
|
_DtHelpCeCleanSdlVolume (
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
|
|
|
|
if (sdlVol != NULL)
|
|
{
|
|
_DtHelpFreeSegments(sdlVol->snb , _DtCvFALSE, sdlVol->destroy_region,
|
|
sdlVol->client_data);
|
|
_DtHelpFreeSegments(sdlVol->title, _DtCvFALSE, sdlVol->destroy_region,
|
|
sdlVol->client_data);
|
|
|
|
/*
|
|
* free the index information
|
|
*/
|
|
FreeEntryInfo(sdlVol->index);
|
|
_DtHelpFreeSegments(sdlVol->index, _DtCvFALSE, NULL, NULL);
|
|
|
|
/*
|
|
* free the toss information.
|
|
*/
|
|
FreeTossInfo(sdlVol->toss);
|
|
_DtHelpFreeSegments(sdlVol->toss , _DtCvFALSE, NULL, NULL);
|
|
|
|
/*
|
|
* free the ids
|
|
*/
|
|
FreeIds(sdlVol->loids);
|
|
_DtHelpFreeSegments(sdlVol->loids, _DtCvFALSE, NULL, NULL);
|
|
|
|
/*
|
|
* free the document information.
|
|
*/
|
|
if (NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
|
|
free(_SdlDocInfoPtrLanguage(sdlVol->sdl_info));
|
|
|
|
if (NULL != _SdlDocInfoPtrCharSet(sdlVol->sdl_info))
|
|
free(_SdlDocInfoPtrCharSet(sdlVol->sdl_info));
|
|
|
|
if (NULL != _SdlDocInfoPtrDocId(sdlVol->sdl_info))
|
|
free(_SdlDocInfoPtrDocId(sdlVol->sdl_info));
|
|
|
|
if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info))
|
|
free(_SdlDocInfoPtrFirstPg(sdlVol->sdl_info));
|
|
|
|
if (NULL != _SdlDocInfoPtrSdlDtd(sdlVol->sdl_info))
|
|
free(_SdlDocInfoPtrSdlDtd(sdlVol->sdl_info));
|
|
|
|
if (NULL != _SdlDocInfoPtrStamp(sdlVol->sdl_info))
|
|
free(_SdlDocInfoPtrStamp(sdlVol->sdl_info));
|
|
|
|
free(sdlVol->sdl_info);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function: int _DtHelpCeRereadSdlVolume (_DtHelpVolume vol);
|
|
*
|
|
* Parameters: vol Specifies the loaded volume.
|
|
*
|
|
* Return Value: 0 if successful, -1 if a failure occurs
|
|
*
|
|
* errno Values: None
|
|
*
|
|
* Purpose: When the volume is no longer needed, it should be unloaded
|
|
* with this call. Unloading it frees the memory (which means
|
|
* any handles on the volume become invalid.)
|
|
*
|
|
******************************************************************************/
|
|
int
|
|
_DtHelpCeRereadSdlVolume (
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
_DtHelpCeCleanSdlVolume(volume);
|
|
_DtHelpCeInitSdlVolume(volume);
|
|
if (_DtHelpCeFrmtSdlVolumeInfo(_DtHelpCeGetVolumeName(volume),
|
|
volume, NULL) == 0)
|
|
return 0;
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function: void _DtHelpCeCloseSdlVolume (_DtHelpVolume vol);
|
|
*
|
|
* Parameters: vol Specifies the loaded volume.
|
|
*
|
|
* Return Value: 0 if successful, -1 if a failure occurs
|
|
*
|
|
* errno Values: None
|
|
*
|
|
* Purpose: When the volume is no longer needed, it should be unloaded
|
|
* with this call. Unloading it frees the memory (which means
|
|
* any handles on the volume become invalid.)
|
|
*
|
|
******************************************************************************/
|
|
void
|
|
_DtHelpCeCloseSdlVolume (
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
|
|
|
|
if (sdlVol != NULL)
|
|
{
|
|
_DtHelpCeCleanSdlVolume(volume);
|
|
free(sdlVol);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: Boolean _DtHelpCeGetSdlHomeTopicId (_DtHelpVolume vol,
|
|
* char *target_id,
|
|
* char *ret_name, int *ret_offset)
|
|
*
|
|
* Parameters: vol Specifies the loaded volume
|
|
* target_id Specifies target location ID
|
|
* ret_name Returns a null terminated string
|
|
* containing a fully qualified path to
|
|
* the file that contains 'target_id'.
|
|
* ret_offset Returns the offset into 'ret_name'
|
|
* to the topic that contains 'target_id'.
|
|
*
|
|
* Memory own by caller:
|
|
* ret_name
|
|
*
|
|
* Returns: True if successful, False if a failure occurs
|
|
*
|
|
* errno Values: EINVAL Specifies an invalid parameter was
|
|
* used.
|
|
* CEErrorMalloc
|
|
* CEErrorLocIdNotFound
|
|
* Specifies that 'locId' was not
|
|
* found.
|
|
*
|
|
* Purpose: Find which topic contains a specified locationID.
|
|
*
|
|
*****************************************************************************/
|
|
char *
|
|
_DtHelpCeGetSdlHomeTopicId (
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
_DtCvSegment *idSegs;
|
|
CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
|
|
|
|
if (sdlVol->sdl_info != NULL)
|
|
{
|
|
/*
|
|
* Was the first page topic declared in the header?
|
|
*/
|
|
if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info))
|
|
return (_SdlDocInfoPtrFirstPg(sdlVol->sdl_info));
|
|
|
|
/*
|
|
* have to search the list of ids for the home topic. This is a
|
|
* bit of a kludge since we are looking for a specific string in
|
|
* the rssi. But this is for backwards compatibility since the
|
|
* Snapshot release of the help system were released with out
|
|
* the first-page attribute and relied on _hometopic.
|
|
*
|
|
* Plus, first-page is #IMPLIED, which means that the parser
|
|
* that generated this SDL document does not have to use this
|
|
* attribute.
|
|
*/
|
|
if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0)
|
|
return NULL;
|
|
|
|
while (idSegs != NULL)
|
|
{
|
|
if (SdlIdVirpage == _SdlSegToSdlIdInfoType(idSegs) &&
|
|
_DtHelpCeStrCaseCmpLatin1(_SdlIdInfoPtrRssi(
|
|
_SdlSegToSdlIdInfoPtr(idSegs)),
|
|
"_hometopic") == 0)
|
|
return _DtCvContainerIdOfSeg(idSegs);
|
|
|
|
idSegs = idSegs->next_seg;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: Boolean _DtHelpCeFindSdlId (_DtHelpVolume vol, char *target_id,
|
|
* char *ret_name, int *ret_offset)
|
|
*
|
|
* Parameters: vol Specifies the loaded volume
|
|
* target_id Specifies target location ID
|
|
* ret_name Returns a null terminated string
|
|
* containing a fully qualified path to
|
|
* the file that contains 'target_id'.
|
|
* ret_offset Returns the offset into 'ret_name'
|
|
* to the topic that contains 'target_id'.
|
|
*
|
|
* Memory own by caller:
|
|
* ret_name
|
|
*
|
|
* Returns: True if successful, False if a failure occurs
|
|
*
|
|
* errno Values: EINVAL Specifies an invalid parameter was
|
|
* used.
|
|
* CEErrorMalloc
|
|
* CEErrorLocIdNotFound
|
|
* Specifies that 'locId' was not
|
|
* found.
|
|
*
|
|
* Purpose: Find which topic contains a specified locationID.
|
|
*
|
|
*****************************************************************************/
|
|
int
|
|
_DtHelpCeFindSdlId (
|
|
_DtHelpVolumeHdl volume,
|
|
char *target_id,
|
|
int fd,
|
|
char **ret_name,
|
|
int *ret_offset )
|
|
{
|
|
_DtHelpVolume vol = (_DtHelpVolume) volume;
|
|
_DtCvSegment *pEl;
|
|
|
|
pEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, fd);
|
|
|
|
if (pEl != NULL)
|
|
{
|
|
if (ret_name != NULL)
|
|
*ret_name = strdup(vol->volFile);
|
|
*ret_offset = _SdlIdInfoPtrOffset(_SdlSegToSdlIdInfoPtr(pEl));
|
|
return True;
|
|
}
|
|
|
|
return False;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: int _DtHelpCeGetSdlKeywordList (
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns: 0 if successful, -1 if not.
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose: Get the KeywordList for an SDL volume.
|
|
*
|
|
*****************************************************************************/
|
|
int
|
|
_DtHelpCeGetSdlKeywordList (
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
|
|
|
|
if (_DtHelpCeGetSdlVolIndex(volume) != 0 || NULL == sdlVol->index
|
|
|| NULL == _DtCvContainerListOfSeg(sdlVol->index))
|
|
return -1;
|
|
|
|
return(ProcessEntry(((_DtHelpVolume) volume),
|
|
_DtCvContainerListOfSeg(sdlVol->index), NULL));
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: int _DtHelpCeGetSdlVolumeAsciiAbstract(volume);
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns: 0 if successful, -1 if not.
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose: Get the KeywordList for an SDL volume.
|
|
*
|
|
*****************************************************************************/
|
|
char *
|
|
_DtHelpCeGetSdlVolumeAsciiAbstract(
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
return(_DtHelpCeFrmtSdlVolumeAbstractToAscii(volume));
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: int _DtHelpCeGetSdlIdPath(volume, target_id, ret_ids);
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns: > 0 if successful, -1 if not.
|
|
*
|
|
* Memory: The memory returned is owned by the caller.
|
|
*
|
|
* Purpose: Get the list of location ids between the top and the
|
|
* target_id.
|
|
*
|
|
*****************************************************************************/
|
|
int
|
|
_DtHelpCeGetSdlIdPath(
|
|
_DtHelpVolumeHdl volume,
|
|
char *target_id,
|
|
char ***ret_ids)
|
|
{
|
|
_DtCvSegment *idSegs;
|
|
_DtCvSegment *targetEl;
|
|
int hiddenNo = -1;
|
|
|
|
targetEl = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1);
|
|
|
|
if (targetEl == NULL)
|
|
return -1;
|
|
|
|
*ret_ids = NULL;
|
|
|
|
if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0)
|
|
return 0;
|
|
|
|
if (_SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume)) >= SDL_DTD_1_1)
|
|
hiddenNo = 0;
|
|
|
|
return (MapPath(&idSegs, targetEl, -1, 0, hiddenNo, ret_ids));
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: _DtCvSegment *_DtHelpCeMapSdlIdToSegment(volume, target_id);
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns: > 0 if successful, -1 if not.
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose: Get the list of location ids between the top and the
|
|
* target_id.
|
|
*
|
|
*****************************************************************************/
|
|
_DtCvSegment *
|
|
_DtHelpCeMapSdlIdToSegment(
|
|
_DtHelpVolumeHdl volume,
|
|
const char *target_id,
|
|
int fd)
|
|
{
|
|
int underScore = False;
|
|
short minorNo;
|
|
_DtCvSegment *idSegs;
|
|
char *idString;
|
|
char resStr[128] = "SDL-RESERVED-";
|
|
|
|
minorNo = _SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume));
|
|
|
|
if (*target_id == '_')
|
|
{
|
|
/*
|
|
* parsers generating SDL_DTD_1_0 and earlier put the special
|
|
* access points (_hometopic, _abstract, _copyright, etc.) in
|
|
* the SSI.
|
|
*/
|
|
if (minorNo < SDL_DTD_1_1)
|
|
underScore = True;
|
|
else
|
|
{
|
|
target_id++;
|
|
strcat(resStr, target_id);
|
|
target_id = resStr;
|
|
}
|
|
}
|
|
|
|
if (_DtHelpCeGetSdlVolIds(volume, fd, &idSegs) != 0)
|
|
return NULL;
|
|
|
|
while (idSegs != NULL)
|
|
{
|
|
if (underScore == True)
|
|
idString = _SdlIdInfoPtrRssi(_SdlSegToSdlIdInfoPtr(idSegs));
|
|
else
|
|
idString = _DtCvContainerIdOfSeg(idSegs);
|
|
|
|
if (idString != NULL &&
|
|
_DtHelpCeStrCaseCmpLatin1(idString, target_id) == 0)
|
|
return idSegs;
|
|
|
|
idSegs = idSegs->next_seg;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: int _DtHelpCeMapIdToSdlTopicId(volume, target_id);
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns: > 0 if successful, -1 if not.
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose: Get the id of the virpage containing the target_id.
|
|
*
|
|
*****************************************************************************/
|
|
int
|
|
_DtHelpCeMapIdToSdlTopicId(
|
|
_DtHelpVolumeHdl volume,
|
|
const char *target_id,
|
|
char **ret_id)
|
|
{
|
|
int found = -1;
|
|
_DtCvSegment *idList;
|
|
_DtCvSegment *idSeg;
|
|
SDLIdInfo *idInfo;
|
|
|
|
if (_DtHelpCeGetSdlVolIds(volume, -1, &idList) == 0)
|
|
{
|
|
idSeg = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1);
|
|
if (idSeg != NULL)
|
|
{
|
|
while (found == -1 && idList != NULL)
|
|
{
|
|
idInfo = _SdlSegToSdlIdInfoPtr(idList);
|
|
if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage)
|
|
*ret_id = _DtCvContainerIdOfSeg(idList);
|
|
|
|
if (idList == idSeg)
|
|
found = 0;
|
|
else
|
|
idList = idList->next_seg;
|
|
}
|
|
}
|
|
}
|
|
|
|
return found;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: char * _DtHelpCeGetSdlVolCharSet(volume);
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns: the pointer to the locale string. Null otherwise.
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose: Get the locale of the volume.
|
|
*
|
|
*****************************************************************************/
|
|
const char *
|
|
_DtHelpCeGetSdlVolCharSet(
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
const char *charSet = IsoString;
|
|
CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
|
|
|
|
if (sdlVol->sdl_info != NULL &&
|
|
NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
|
|
charSet = _SdlDocInfoPtrCharSet(sdlVol->sdl_info);
|
|
|
|
return charSet;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: char * _DtHelpCeGetSdlVolLanguage(volume);
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns: the pointer to the language used in the volume.
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose: Get the locale of the volume.
|
|
*
|
|
*****************************************************************************/
|
|
char *
|
|
_DtHelpCeGetSdlVolLanguage(
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
char *language = "C";
|
|
CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
|
|
|
|
if (sdlVol->sdl_info != NULL &&
|
|
NULL != _SdlDocInfoPtrLanguage(sdlVol->sdl_info))
|
|
language = _SdlDocInfoPtrLanguage(sdlVol->sdl_info);
|
|
|
|
return language;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: char * _DtHelpCeGetSdlVolumeLocale(volume);
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns: the pointer to the locale string. Null otherwise.
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose: Get the locale of the volume.
|
|
*
|
|
*****************************************************************************/
|
|
char *
|
|
_DtHelpCeGetSdlVolumeLocale(
|
|
_DtHelpVolumeHdl volume)
|
|
{
|
|
int langLen;
|
|
char *locale;
|
|
char *lang;
|
|
const char *charSet;
|
|
|
|
lang = _DtHelpCeGetSdlVolLanguage(volume);
|
|
charSet = _DtHelpCeGetSdlVolCharSet(volume);
|
|
|
|
langLen = strlen(lang);
|
|
locale = (char *) malloc (langLen + strlen(charSet) + 2);
|
|
if (locale != NULL)
|
|
{
|
|
strcpy(locale, lang);
|
|
if (langLen != 0 && *charSet != '\0')
|
|
{
|
|
locale[langLen++] = '.';
|
|
strcpy(&(locale[langLen]), charSet);
|
|
}
|
|
}
|
|
|
|
return locale;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: int _DtHelpCeGetSdlDocStamp(volume, ret_doc, ret_time);
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns: 0 if successful, -2 if the volume does not contain
|
|
* one or the other, -1 if any other failure.
|
|
*
|
|
* Memory: The Caller owns the memory returned in ret_doc and ret_time.
|
|
*
|
|
* Purpose: Get the doc id and time stamp of a volume.
|
|
*
|
|
*****************************************************************************/
|
|
int
|
|
_DtHelpCeGetSdlDocStamp(
|
|
_DtHelpVolumeHdl volume,
|
|
char **ret_doc,
|
|
char **ret_time)
|
|
{
|
|
int result = -1;
|
|
char *docId = NULL;
|
|
char *timestamp = NULL;
|
|
CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
|
|
|
|
if (sdlVol->sdl_info != NULL)
|
|
{
|
|
result = 0;
|
|
if (NULL != _SdlDocInfoPtrDocId(sdlVol->sdl_info))
|
|
docId = strdup(_SdlDocInfoPtrDocId(sdlVol->sdl_info));
|
|
else
|
|
result = -2;
|
|
|
|
if (NULL != _SdlDocInfoPtrStamp(sdlVol->sdl_info))
|
|
timestamp = strdup(_SdlDocInfoPtrStamp(sdlVol->sdl_info));
|
|
else
|
|
result = -2;
|
|
}
|
|
|
|
if (ret_doc != NULL)
|
|
*ret_doc = docId;
|
|
if (ret_time != NULL)
|
|
*ret_time = timestamp;
|
|
|
|
if (result == 0 && (docId == NULL || timestamp == NULL))
|
|
return -1;
|
|
|
|
return result;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: int _DtHelpCeGetSdlTopicChildren(
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns: pointer to the element, Null otherwise.
|
|
*
|
|
* errno Values:
|
|
*
|
|
* Purpose: Find the specified element.
|
|
*
|
|
*****************************************************************************/
|
|
int
|
|
_DtHelpCeGetSdlTopicChildren(
|
|
_DtHelpVolumeHdl volume,
|
|
char *target,
|
|
char ***ret_ids)
|
|
{
|
|
int done = False;
|
|
int count = 0;
|
|
int segLev;
|
|
_DtCvSegment *idSeg;
|
|
SDLIdInfo *idInfo;
|
|
|
|
/*
|
|
* Find the target id.
|
|
*/
|
|
idSeg = _DtHelpCeMapSdlIdToSegment(volume, target, -1);
|
|
|
|
/*
|
|
* save this level and start looking for its children at the next seg.
|
|
*/
|
|
*ret_ids = NULL;
|
|
if (idSeg != NULL)
|
|
{
|
|
idInfo = _SdlSegToSdlIdInfoPtr(idSeg);
|
|
segLev = _SdlIdInfoPtrRlevel(idInfo) + 1;
|
|
idSeg = idSeg->next_seg;
|
|
}
|
|
|
|
/*
|
|
* process any virpage that has the correct level
|
|
*/
|
|
while (idSeg != NULL && done == False)
|
|
{
|
|
idInfo = _SdlSegToSdlIdInfoPtr(idSeg);
|
|
if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage)
|
|
{
|
|
/*
|
|
* If greater, we're at the next sibling.
|
|
*/
|
|
if (segLev > _SdlIdInfoPtrRlevel(idInfo))
|
|
done = True;
|
|
else if (segLev == _SdlIdInfoPtrRlevel(idInfo))
|
|
{
|
|
*ret_ids = (char **) _DtHelpCeAddPtrToArray( (void **) *ret_ids,
|
|
(void *)(strdup(_DtCvContainerIdOfSeg(idSeg))));
|
|
if ((*ret_ids) == NULL)
|
|
return -1;
|
|
|
|
count++;
|
|
}
|
|
}
|
|
idSeg = idSeg->next_seg;
|
|
}
|
|
|
|
return count;
|
|
}
|