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 /* $TOG: FormatTerm.c /main/14 1997/08/07 10:52:34 samborn $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 ** Project: CDE Help System
31 ** Description: This code uses the core engine functionality of the
32 ** the help system to get topics into a form understood
33 ** by ASCII based applications.
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.
42 ****************************************************************************
43 ************************************<+>*************************************/
54 #include <sys/param.h>
63 * Canvas Engine includes
66 #include "CanvasSegP.h"
73 #include "HelpTermP.h"
77 #include "AsciiSpcI.h"
82 #include "HelpErrorP.h"
83 #include "FileUtilsI.h"
84 #include "FontAttrI.h"
85 #include "StringFuncsI.h"
87 #include "FormatUtilI.h"
88 #include "FormatSDLI.h"
89 #include "FormatCCDFI.h"
96 /******** Private Function Declarations ********/
97 static void TermMetrics(
98 _DtCvPointer client_data,
99 _DtCvElemType elem_type,
100 _DtCvPointer ret_metrics);
101 static _DtCvUnit TermStrWidth(
102 _DtCvPointer client_data,
103 _DtCvElemType elem_type,
105 static void TermStrDraw(
106 _DtCvPointer client_data,
112 _DtCvPointer font_ptr,
115 _DtCvUnit box_height,
117 _DtCvFlags old_flags,
118 _DtCvFlags new_flags );
120 static _DtCvStatus TermFindGraphic(
121 _DtCvPointer client_data,
127 _DtCvUnit *ret_width,
128 _DtCvUnit *ret_height,
129 _DtCvPointer *ret_graphic);
131 static void TermGetFont(
132 _DtCvPointer client_data,
135 _DtHelpFontHints font_attr,
136 _DtCvPointer *ret_font );
137 static void TermFontMetrics(
138 _DtCvPointer client_data,
139 _DtCvPointer font_ptr,
140 _DtCvUnit *ret_ascent,
141 _DtCvUnit *ret_descent,
142 _DtCvUnit *char_width,
143 _DtCvUnit *ret_super,
145 static _DtCvStatus TermResolveSpc(
146 _DtCvPointer client_data,
149 _DtHelpFontHints font_attr,
151 _DtCvPointer *ret_handle,
152 _DtCvUnit *ret_width,
153 _DtCvUnit *ret_height,
154 _DtCvUnit *ret_ascent);
155 static void TermRenderElem(
156 _DtCvPointer client_data,
157 _DtCvElemType elem_type,
161 _DtCvFlags old_flags,
162 _DtCvFlags new_flags,
163 _DtCvElemType trav_type,
164 _DtCvPointer trav_data,
167 /******** End Public Function Declarations ********/
169 /******************************************************************************
171 * Private variables and defines.
173 *****************************************************************************/
180 static _DtHelpVolumeHdl MyVolume = NULL;
181 static int HyperErr = 0;
182 static wchar_t WcSpace = 0;
185 * These values change as the information is processed.
191 _DtCvUnit max_columns;
194 wchar_t *cant_begin_chars;
195 wchar_t *cant_end_chars;
199 static TerminalInfo DfltTermInfo = {NULL, NULL, 0, 1, 100000, 1, NULL, NULL};
200 static _DtCvVirtualInfo TermVirtInfo =
202 TermMetrics, /* void (*_DtCvGetMetrics)(); */
203 TermRenderElem, /* void (*_DtCvRenderElem)(); */
204 TermStrWidth, /* _DtCvUnit (*_DtCvGetElemWidth)(); */
205 TermFontMetrics, /* void (*_DtCvGetFontMetrics)(); */
206 NULL, /* _DtCvStatus (*_DtCvBuildSelection)(); */
207 NULL, /* _DtCvStatus (*_DtCvFilterExecCmd)(); */
210 static TerminalInfo MyInfo = {NULL, NULL, 0, 1, 100000, 1, NULL, NULL};
211 static _DtCvHandle MyCanvas = NULL;
214 int missingGraphics = 0; /* Counter used by cdewalk */
217 /******************************************************************************
221 ******************************************************************************/
222 /******************************************************************************
224 ******************************************************************************/
226 /*****************************************************************************
227 * Function: _DtCvStatus TermFindGraphic ();
235 *****************************************************************************/
238 _DtCvPointer client_data,
244 _DtCvUnit *ret_width,
245 _DtCvUnit *ret_height,
246 _DtCvPointer *ret_graphic )
249 char *fileName = file_xid;
251 if (fileName != NULL && *fileName != '/')
253 fileName = (char *) malloc (strlen(vol_xid) + strlen (file_xid) + 2);
254 if (fileName == NULL)
257 strcpy(fileName, vol_xid);
259 if (_DtHelpCeStrrchr(fileName, "/", MB_CUR_MAX, &ptr) != -1)
262 strcat(fileName, "/");
263 strcat(fileName, file_xid);
266 if (access(fileName, R_OK) != 0)
269 fprintf (stdout, "\tGRAPHICS LINK ***UNRESOLVED***\n");
270 fprintf (stdout, "\tUnable to find graphic file: %s\n\n", fileName);
273 if (fileName != file_xid)
284 /*****************************************************************************
285 * Function: void TermStrDraw ();
293 *****************************************************************************/
296 _DtCvPointer client_data,
302 _DtCvPointer font_ptr,
305 _DtCvUnit box_height,
307 _DtCvFlags old_flags,
308 _DtCvFlags new_flags )
310 TerminalInfo *pTerm = (TerminalInfo *) client_data;
311 wchar_t *wcStr = pTerm->lines[y];
314 length = x + byte_len;
317 pTerm->lines[y] = (wchar_t *) malloc (sizeof(wchar_t) * (length + 1));
318 if (pTerm->lines[y] != NULL)
322 wcStr = pTerm->lines[y];
323 _DtHelpProcessLock();
324 for (i = 0; i < x; i++)
326 _DtHelpProcessUnlock();
328 * this will leave a hole that will be plugged by the next
332 pTerm->wc_num[y] = length;
337 if (length > pTerm->wc_num[y])
339 pTerm->lines[y] = (wchar_t *) realloc (wcStr,
340 (sizeof(wchar_t) * (length + 1)));
341 if (pTerm->lines[y] != NULL)
344 wcStr = pTerm->lines[y];
345 _DtHelpProcessLock();
346 for (i = pTerm->wc_num[y]; i < x; i++)
348 _DtHelpProcessUnlock();
350 pTerm->wc_num[y] = length;
356 mbstowcs(&wcStr[x], string, byte_len);
359 wchar_t *wcp = (wchar_t *) string;
369 /*****************************************************************************
370 * Function: void TermRenderElem ();
378 *****************************************************************************/
381 _DtCvPointer client_data,
382 _DtCvElemType elem_type,
386 _DtCvFlags old_flags,
387 _DtCvFlags new_flags,
388 _DtCvElemType trav_type,
389 _DtCvPointer trav_data,
392 _DtCvStringInfo *strInfo;
393 _DtCvRenderInfo *posInfo = (_DtCvRenderInfo *) data;
395 if (_DtCvSTRING_TYPE == elem_type)
397 strInfo = (_DtCvStringInfo *) posInfo->info;
398 TermStrDraw (client_data, x, y, strInfo->string, strInfo->byte_len,
399 strInfo->wc , strInfo->font_ptr,
400 posInfo->box_x , posInfo->box_y ,
401 posInfo->box_height, link_type,
402 old_flags , new_flags);
404 else if (_DtCvREGION_TYPE == elem_type)
406 const char *spcStr = (const char*) posInfo->info;
407 int len = spcStr ? strlen(spcStr) : 0;
409 TermStrDraw (client_data, x, y, spcStr, len, 0, 0,
410 posInfo->box_x , posInfo->box_y,
411 posInfo->box_height, link_type,
412 old_flags , new_flags);
416 /*****************************************************************************
417 * Function: void TermMetrics ();
425 *****************************************************************************/
426 static _DtCvSpaceMetrics defLinkMetrics = { 0, 0, 0, 0 };
430 _DtCvPointer client_data,
431 _DtCvElemType elem_type,
432 _DtCvPointer ret_metrics)
434 TerminalInfo *pTerm = (TerminalInfo *) client_data;
435 _DtCvSpaceMetrics *retSpace = (_DtCvSpaceMetrics *) ret_metrics;
437 if (_DtCvCANVAS_TYPE == elem_type)
439 _DtCvMetrics *retCanvas = (_DtCvMetrics *) ret_metrics;
441 retCanvas->width = pTerm->max_columns;
442 retCanvas->height = 50;
443 retCanvas->top_margin = 0;
444 retCanvas->side_margin = 0;
445 retCanvas->line_height = 1;
446 retCanvas->horiz_pad_hint = 1;
449 else if (_DtCvLOCALE_TYPE == elem_type)
451 _DtCvLocale *retLocale = (_DtCvLocale *) ret_metrics;
453 retLocale->line_wrap_mode = _DtCvModeWrapNone;
454 retLocale->cant_begin_chars = pTerm->cant_begin_chars;
455 retLocale->cant_end_chars = pTerm->cant_end_chars;
457 else if (_DtCvLINK_TYPE == elem_type || _DtCvTRAVERSAL_TYPE == elem_type)
458 *retSpace = defLinkMetrics;
461 /*****************************************************************************
462 * Function: void TermGetFont ();
470 *****************************************************************************/
473 _DtCvPointer client_data,
476 _DtHelpFontHints font_attr,
477 _DtCvPointer *ret_font )
479 *ret_font = (_DtCvPointer) 0;
482 /*****************************************************************************
483 * Function: _DtCvStatus TermResolveSpc ();
491 *****************************************************************************/
494 _DtCvPointer client_data,
497 _DtHelpFontHints font_attr,
499 _DtCvPointer *ret_handle,
500 _DtCvUnit *ret_width,
501 _DtCvUnit *ret_height,
502 _DtCvUnit *ret_ascent)
507 * initialize the returned information to nothing.
514 spcStr = _DtHelpCeResolveSpcToAscii (spc_symbol);
518 *ret_handle = ((_DtCvPointer)(spcStr));
520 *ret_width = strlen(spcStr);
527 /*****************************************************************************
528 * Function: void TermFontMetrics ();
536 *****************************************************************************/
539 _DtCvPointer client_data,
540 _DtCvPointer font_ptr,
541 _DtCvUnit *ret_ascent,
542 _DtCvUnit *ret_descent,
543 _DtCvUnit *char_width,
544 _DtCvUnit *ret_super,
561 /*****************************************************************************
562 * Function: _DtCvUnit TermStrWidth ();
570 *****************************************************************************/
573 _DtCvPointer client_data,
574 _DtCvElemType elem_type,
577 _DtCvStringInfo *strInfo = (_DtCvStringInfo *) data;
579 if (elem_type != _DtCvSTRING_TYPE)
582 return ((_DtCvUnit)(strInfo->byte_len));
585 /******************************************************************************
586 * End Canvas functions
587 * Begin other private functions
588 ******************************************************************************/
590 /******************************************************************************
591 * Function: DtHelpHyperLines *AddHyperToArray (DtHelpHyperLines *array_ptr,
592 * int value, char *link_spec, char *title)
595 * array_ptr Specifies a NULL terminated list of
596 * DtHelpHyperLines or NULL.
597 * value Specifies the link type.
598 * link_spec Specifies the link specification.
599 * title Specifies the title of the link.
601 * Returns: A ptr to the new DtHelpHyperLines if successful,
607 * Purpose: Add a hypertext link to an array of DtHelpHyperLines.
609 *****************************************************************************/
610 static DtHelpHyperLines *
612 DtHelpHyperLines *array_ptr,
618 DtHelpHyperLines *next;
624 for (next = array_ptr; next->specification != NULL; next++)
627 if (((num + 1) % GROW_SIZE) == 0)
628 array_ptr = (DtHelpHyperLines *) realloc ((void *) array_ptr,
629 (sizeof (DtHelpHyperLines) * (num + 1 + GROW_SIZE)));
632 array_ptr = (DtHelpHyperLines *) malloc (
633 sizeof (DtHelpHyperLines) * GROW_SIZE);
635 if (array_ptr == NULL)
636 errno = DtErrorMalloc;
639 next = array_ptr + num;
641 next->hyper_type = value;
642 next->win_hint = win_hint;
643 next->specification = strdup(link_spec);
647 next->specification = NULL;
654 /******************************************************************************
655 * Function: void DeallocateHyperArray (DtHelpHyperLines *array_ptr)
658 * array_ptr Specifies a NULL terminated array of
665 * Purpose: De-allocate an array of DtHelpHyperLines structures.
667 *****************************************************************************/
669 DeallocateHyperArray(
670 DtHelpHyperLines *array_ptr )
672 DtHelpHyperLines *next = array_ptr;
676 while (next->title && next->specification)
679 free (next->specification);
686 /******************************************************************************
687 * Function: int AddHyperToList(
691 * Returns: 0 if successful.
692 * -1 if unrecoverable errors.
693 * -2 if could not resolve the hypertext link.
697 * DtErrorFormattingLabel
698 * A label has illegal syntax.
700 * Invalid (negative) hypertype.
701 * DtErrorFormattingLink
704 * Invalid 'hyper_specification' in the
706 * DtErrorFormattingId
707 * Invalid <ID> syntax.
709 * Purpose: Process the result of a hypertext link, filling out
710 * a hypertext structure element with the information.
712 *****************************************************************************/
715 _DtHelpVolumeHdl volume,
718 DtHelpHyperLines **ret_list)
720 _DtCanvasStruct *myCanvas = (_DtCanvasStruct *)canvas;
721 _DtCvLinkInfo hyperInfo;
722 _DtHelpVolumeHdl newVol = NULL;
723 _DtHelpVolumeHdl useVol = volume;
724 char *volName = NULL;
726 char *allocName = NULL;
731 if (_DtLinkDbGetLinkInfo(myCanvas->link_data, i,
732 myCanvas->virt_functions.exec_cmd_filter,
733 myCanvas->client_data, &hyperInfo) == 0)
736 if (hyperInfo.description == NULL)
738 id = hyperInfo.specification;
739 switch (hyperInfo.hyper_type)
741 case _DtCvLinkType_CrossLink:
747 _DtHelpCeStrchr (spec," ",MB_CUR_MAX,&id);
753 /* find the volume (volName is malloc'd) */
754 allocName = _DtHelpFileLocate(DtHelpVOLUME_TYPE, volName,
755 _DtHelpFileSuffixList,False,R_OK);
756 if (allocName == NULL)
759 if (_DtHelpOpenVolume(allocName, &newVol)==0)
770 case _DtCvLinkType_SameVolume:
773 result = _DtHelpGetTopicTitle(useVol, id, &title);
775 HyperErr = DtErrorLocIdNotFound;
779 _DtHelpCloseVolume(newVol);
782 if (allocName != NULL)
787 case _DtCvLinkType_Execute:
788 title = (char *) malloc(strlen(id) + 11);
789 sprintf(title, "Execute \"%s\"", id);
792 case _DtCvLinkType_ManPage:
793 title = (char *) malloc(strlen(id) + 13);
794 sprintf(title, "Man Page \"%s\"", id);
797 case _DtCvLinkType_AppDefine:
798 title = (char *) malloc(strlen(id) + 26);
799 sprintf(title, "Application Link Type \"%s\"", id);
802 case _DtCvLinkType_TextFile:
803 title = (char *) malloc(strlen(id) + 12);
804 sprintf(title, "Text File \"%s\"", id);
807 title = strdup ("Unkown link type");
814 title = strdup (hyperInfo.description);
819 *ret_list = AddHyperToArray (*ret_list, -(hyperInfo.hyper_type + 1),
821 hyperInfo.specification,
822 strdup("Invalid Link"));
823 else if (result >= 0)
824 *ret_list = AddHyperToArray (*ret_list, hyperInfo.hyper_type,
826 hyperInfo.specification,
830 * report unable to resolve the hypertext link
835 if (result == -1 || *ret_list == NULL)
840 } /* End AddHyperToList */
842 /******************************************************************************
843 * Function: TerminalInfo * GetTermInfo(canvasHandle)
846 * canvasHandle Canvas whose client_data is a TerminalInfo *
848 * Returns: 0 for success, -1 for failure.
850 ******************************************************************************/
851 static TerminalInfo *
853 _DtCvHandle canvasHandle)
855 _DtCanvasStruct * canvas = (_DtCanvasStruct *) canvasHandle;
857 return (TerminalInfo *) canvas->client_data;
860 /******************************************************************************
864 ******************************************************************************/
865 /******************************************************************************
866 * Function: int _DtHelpTermCreateCanvas (int maxColumns,_DtCvHandle * ret_canvas)
869 * maxColumns Specifies the column width of the window
870 * for which to format the information.
871 * ret_canvas handle to the canvas that was created
873 * Returns: 0 for success, -1 for failure.
876 * EINVAL 'ret_canvas' was NULL or 'maxColumns'
878 * ENOMEM unable to allocate necessary memory
881 * Purpose: _DtHelpTermCreateCanvas creates a canvas that use
882 * text-only content processing routines
884 *****************************************************************************/
886 _DtHelpTermCreateCanvas (
888 _DtCvHandle * ret_canvas)
890 TerminalInfo * termInfo;
893 * check the parameters
895 if (maxColumns < 1 || ret_canvas == NULL)
901 termInfo = (TerminalInfo *) malloc(sizeof(TerminalInfo));
902 if (termInfo == NULL)
908 /* init info and create a canvas */
909 *termInfo = DfltTermInfo;
910 termInfo->max_columns = maxColumns;
912 _DtHelpLoadMultiInfo(&(termInfo->cant_begin_chars),
913 &(termInfo->cant_begin_chars),
914 &(termInfo->nl_to_space));
916 *ret_canvas = _DtCanvasCreate (TermVirtInfo, (_DtCvPointer) termInfo);
918 if (*ret_canvas == NULL)
925 /******************************************************************************
926 * Function: int _DtHelpTermGetTopicData(canvasHandle,volHandle,
927 * locationId,helpList,hyperList)
930 * canvasHandle Canvas used to retrieve the info; MUST
931 * be a Terminal canvas Since it isn't easy
932 * to verify this, we don't try. So if the
933 * Canvas ISN'T a Terminal Canvas, we'll
935 * volHandle Help volume to use
936 * locationId Specifies the locationId of the desired topic.
937 * helpList Returns a NULL terminated array of
939 * hyperList Returns a NULL terminated array of
940 * DtHelpHyperLines containing the hyperlinks
941 * found in the topic.
943 * Returns: 0 for success, -1 for failure.
946 * EINVAL 'helpVolume', 'locationId', 'helpList',
947 * or 'hyperList' were NULL. 'maxColumns'
949 * open(2) errno set via an open call on
950 * the file for 'locationId'.
952 * DtErrorExceedMaxSize
953 * When following symbolic links, the
954 * new path will exceed the system
955 * maximum file path length.
957 * When following symbolic links, the
958 * new path would change to a parent
959 * directory beyond the beginning
961 * DtErrorIllegalDatabaseFile
962 * Specifies that 'helpVolume' is
963 * an illegal database file.
964 * DtErrorMissingFilenameRes
965 * Specifies that the 'Filename/filename'
966 * resource for the topic does not exist.
967 * DtErrorMissingFileposRes
968 * Specifies that the 'Filepos/filepos'
969 * resource for the topic does not exist.
970 * DtErrorLocIdNotFound
971 * Specifies that 'locationId' was not found.
972 * DtErrorFormattingLabel
973 * A label has illegal syntax.
975 * Invalid (negative) hypertype.
976 * DtErrorFormattingLink
979 * Invalid 'hyper_specification' in the
981 * DtErrorFormattingId
982 * Invalid <ID> syntax.
983 * DtErrorFormattingTitle
984 * Invalid <TITLE> syntax.
986 * Purpose: _DtHelpTermGetTopicData retrieves Help Files content with
987 * in a form understood by a terminal
989 *****************************************************************************/
991 _DtHelpTermGetTopicData(
992 _DtCvHandle canvasHandle,
993 _DtHelpVolumeHdl volHandle,
996 DtHelpHyperLines ** hyperList)
1003 char* fileName = NULL;
1004 _DtHelpCeLockInfo lockInfo;
1005 _DtCvTopicPtr topic = NULL;
1006 TerminalInfo * termInfo;
1007 _FrmtUiInfo myUiInfo;
1009 termInfo = GetTermInfo(canvasHandle);
1011 _DtHelpProcessLock();
1013 mbtowc (&WcSpace, " ", 1);
1014 _DtHelpProcessUnlock();
1017 * find the filename and the Id string.
1019 if (_DtHelpCeLockVolume(volHandle, &lockInfo) != 0)
1024 if (_DtHelpCeFindId(volHandle,locationId,lockInfo.fd,&fileName,&offset)==0)
1026 _DtHelpCeUnlockVolume(lockInfo);
1031 * create the ui structure for the parsing.
1034 myUiInfo.load_graphic = TermFindGraphic;
1036 myUiInfo.load_graphic = NULL;
1038 myUiInfo.resolve_spc = TermResolveSpc;
1039 myUiInfo.load_font = TermGetFont;
1040 myUiInfo.destroy_region = NULL;
1041 myUiInfo.exec_filter = NULL;
1042 myUiInfo.client_data = (_DtCvPointer) termInfo;
1043 myUiInfo.line_width = 0;
1044 myUiInfo.line_height = 1;
1045 myUiInfo.leading = 0;
1046 myUiInfo.avg_char = 1;
1047 myUiInfo.nl_to_space = termInfo->nl_to_space;
1052 result = _DtHelpCeGetVolumeFlag(volHandle);
1054 _DtHelpProcessLock();
1056 result = _DtHelpCeParseSdlTopic(volHandle,
1059 offset, NULL, True, &topic);
1060 else if (result == 0)
1061 result = _DtHelpCeFrmtCcdfTopic(volHandle, fileName,
1062 offset, NULL, &myUiInfo,
1064 _DtHelpProcessUnlock();
1066 /* if successfully formatted topic */
1072 _DtCanvasStruct *myCStruct = (_DtCanvasStruct *)canvasHandle;
1074 /* build the help text list, if requested */
1075 if (NULL != helpList)
1077 _DtCanvasSetTopic(canvasHandle, topic, _DtCvIGNORE_BOUNDARY,
1078 &maxWidth, &maxRows, NULL);
1081 * The 'maxRows' variable is really misnamed; it's really the
1082 * 'maxY', and is 0-based. Thus, the 'lines' and 'wc_num'
1083 * arrays need to be 'maxRows+1', in order to hold all the
1084 * entries. Likewise, 'strList' must be 'maxRows+2', because
1085 * it also needs to be NULL terminated.
1087 termInfo->lines = (wchar_t **)malloc(sizeof(wchar_t *) *(maxRows+1));
1088 termInfo->wc_num = (size_t *)malloc(sizeof(size_t) * (maxRows+1));
1089 strList = (char **) malloc(sizeof(char *) * (maxRows+2));
1090 if (termInfo->lines == NULL || termInfo->wc_num == NULL ||
1094 if (termInfo->lines != NULL)
1095 free(termInfo->lines);
1096 if (termInfo->wc_num != NULL)
1097 free(termInfo->wc_num);
1098 if (strList != NULL)
1100 _DtHelpCeUnlockVolume(lockInfo);
1104 for (i = 0; i <= maxRows; i++)
1106 termInfo->lines[i] = NULL;
1107 termInfo->wc_num[i] = 0;
1110 _DtCanvasRender(canvasHandle, 0, 0, maxWidth, maxRows,
1111 _DtCvRENDER_PARTIAL, _DtCvFALSE, NULL, NULL);
1113 *helpList = strList;
1114 wcList = termInfo->lines;
1115 for (i = 0; i <= maxRows; i++, wcList++, strList++)
1117 if (*wcList == NULL)
1119 *strList = (char *) malloc (1);
1124 len = (termInfo->wc_num[i] + 1) * MB_CUR_MAX;
1125 *strList = (char *) malloc (sizeof (char) * len);
1126 if (*strList != NULL)
1127 wcstombs(*strList, *wcList, len);
1134 * free the allocated memory
1136 for (i = 0, wcList = termInfo->lines; i <= maxRows; i++, wcList++)
1137 if (*wcList != NULL)
1139 free(termInfo->lines);
1140 free(termInfo->wc_num);
1142 } /* if requested help text */
1145 * build the hyperlinks list, if requested
1147 if ( NULL != hyperList )
1150 for (i = 0; result != -1 && i < myCStruct->link_data->max; i++)
1151 result = AddHyperToList(volHandle, canvasHandle, i, hyperList);
1153 } /* if successfully formatted topic */
1155 _DtCanvasClean(canvasHandle);
1156 _DtHelpDestroyTopicData(topic, NULL, NULL);
1159 _DtHelpCeUnlockVolume(lockInfo);
1162 } /* End _DtHelpTermGetTopicData */
1164 /******************************************************************************
1165 * Function: int _DtHelpGetTopicDataHandles(ret_canvasHandle,ret_volHandle)
1168 * ret_canvasHandle Canvas used to retrieve the info
1169 * ret_volHandle Help volume in use
1172 * 0: canvas handle & volHandle are not NULL
1173 * -1: canvas handle & volHandle are NULL
1174 ******************************************************************************/
1176 _DtHelpGetTopicDataHandles(
1177 _DtCvHandle * ret_canvasHandle,
1178 _DtHelpVolumeHdl * ret_volHandle)
1180 _DtHelpProcessLock();
1181 *ret_canvasHandle = MyCanvas;
1182 *ret_volHandle = MyVolume;
1183 if (MyCanvas != NULL && MyVolume != NULL)
1185 _DtHelpProcessUnlock();
1190 _DtHelpProcessUnlock();
1196 /******************************************************************************
1197 * Function: int _DtHelpGetTopicData (char *helpVolume, char *locationId,
1198 * int maxColumns, char ***helpList, DtHelpHyperLines **hyperList)
1201 * helpVolume Specifies a file path to the volume.
1202 * locationId Specifies the locationId of the desired topic.
1203 * maxColumns Specifies the column width of the window
1204 * for which to format the information.
1205 * helpList Returns a NULL terminated array of
1207 * hyperList Returns a NULL terminated array of
1208 * DtHelpHyperLines containing the hyperlinks
1209 * found in the topic.
1211 * Returns: 0 for success, -1 for failure.
1214 * EINVAL 'helpVolume', 'locationId', 'helpList',
1215 * or 'hyperList' were NULL. 'maxColumns'
1216 * was less than one.
1217 * getcwd(2) errno set via a getcwd call.
1218 * readlink(2) errno set via a readlink call.
1219 * open(2) errno set via an open call on
1220 * the file for 'locationId'.
1222 * DtErrorExceedMaxSize
1223 * When following symbolic links, the
1224 * new path will exceed the system
1225 * maximum file path length.
1226 * DtErrorIllegalPath
1227 * When following symbolic links, the
1228 * new path would change to a parent
1229 * directory beyond the beginning
1231 * DtErrorIllegalDatabaseFile
1232 * Specifies that 'helpVolume' is
1233 * an illegal database file.
1234 * DtErrorMissingFilenameRes
1235 * Specifies that the 'Filename/filename'
1236 * resource for the topic does not exist.
1237 * DtErrorMissingFileposRes
1238 * Specifies that the 'Filepos/filepos'
1239 * resource for the topic does not exist.
1240 * DtErrorLocIdNotFound
1241 * Specifies that 'locationId' was not found.
1242 * DtErrorFormattingLabel
1243 * A label has illegal syntax.
1245 * Invalid (negative) hypertype.
1246 * DtErrorFormattingLink
1249 * Invalid 'hyper_specification' in the
1251 * DtErrorFormattingId
1252 * Invalid <ID> syntax.
1253 * DtErrorFormattingTitle
1254 * Invalid <TITLE> syntax.
1256 * Purpose: _DtHelpGetTopicData formats Help Files with
1257 * formatting information
1258 * into a form understood by a terminal
1260 *****************************************************************************/
1262 _DtHelpGetTopicData (
1266 char * * * helpList,
1267 DtHelpHyperLines * * hyperList )
1270 _DtHelpVolumeHdl volume = NULL;
1273 /* find the volume (path is malloc'd) */
1274 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, helpVolume,
1275 _DtHelpFileSuffixList,False,R_OK);
1276 if (path == NULL) { errno = EINVAL; return -1; } /* RETURN */
1278 /* open new canvas or reuse old one with new size */
1279 _DtHelpProcessLock();
1280 if (MyCanvas == NULL)
1282 _DtHelpTermCreateCanvas(maxColumns,&MyCanvas);
1283 if (MyCanvas == NULL)
1286 _DtHelpProcessUnlock();
1287 return -1; /* RETURN: errno=from CreateCanvas */
1292 MyInfo.max_columns = maxColumns;
1293 _DtCanvasResize (MyCanvas, _DtCvFALSE, NULL, NULL);
1296 if (_DtHelpOpenVolume (helpVolume, &volume) == -1)
1299 _DtHelpProcessUnlock();
1300 return -1; /* RETURN: errno=from OpenVolume */
1303 /* release any previously opened volume */
1305 _DtHelpCloseVolume (MyVolume);
1307 /* assign the new volume */
1310 /* get the terminal info */
1311 result = _DtHelpTermGetTopicData(MyCanvas,MyVolume,locationId,helpList,hyperList);
1313 _DtHelpProcessUnlock();
1318 /*****************************************************************************
1319 * Function: int _DtHelpProcessLinkData (char * ref_volume,DtHelpHyperLines *hyperLine,
1320 * char **ret_helpVolume, char **ret_locationId)
1323 * hyperLine Specifies the hypertext line that
1324 * the caller wishes to be resolved.
1325 * helpVolume Returns the help volume specified by
1327 * locationId Returns the location Id specified by
1330 * Returns: 0 if successful, -1 if errors.
1333 * EINVAL 'hyperLines', 'helpVolume', or 'locationId'
1337 * The hyper type is not _DtJUMP_REUSE,
1338 * _DtJUMP_NEW, or _DtDEFINITION.
1340 * Invalid hyper specification.
1341 * DtErrorIllegalPath
1342 * The volume used by the link spec (either
1343 * embedded or the ref_volume) could not be
1346 * Purpose: _DtHelpProcessLinkData resolves a hypertext specification
1347 * into a pathname to a help volume and a location Id within
1350 *****************************************************************************/
1352 _DtHelpProcessLinkData (
1354 DtHelpHyperLines * hyperLine,
1355 char * * ret_helpVolume,
1356 char * * ret_locationId )
1358 char * linkSpec = NULL;
1359 char * volumeName = NULL;
1360 char * idToken = NULL;
1363 if (ref_volume == NULL || hyperLine == NULL ||
1364 ret_helpVolume == NULL || ret_locationId == NULL)
1370 /* only process SameVolume or CrossVolume links */
1371 switch (hyperLine->hyper_type)
1373 case _DtCvLinkType_SameVolume:
1374 case _DtCvLinkType_CrossLink:
1378 errno = DtErrorHyperType;
1379 return -1; /* RETURN */
1382 /* Initialize the pointers. */
1383 *ret_helpVolume = NULL;
1384 *ret_locationId = NULL;
1386 /* get working copy of spec */
1387 linkSpec = strdup (hyperLine->specification);
1388 if (linkSpec == NULL)
1390 errno = DtErrorMalloc;
1394 /* parse the link spec. Syntax is: "[volume] locationId" */
1395 if (linkSpec == NULL || *linkSpec == EOS)
1397 errno = DtErrorHyperSpec; /* no spec */
1399 else /* at least one token exists */
1401 volumeName = linkSpec; /* posit that first token is the volume */
1403 /* look for another possible token */
1405 _DtHelpCeStrchr (linkSpec," ",MB_CUR_MAX,&idToken);
1408 if (idToken) /* second token */
1410 /* separate the tokens and advance idToken to first valid char */
1411 *idToken = EOS; idToken++;
1413 /* find the fully qualified volume (volName is malloc'd) */
1414 volumeName = _DtHelpFileLocate(DtHelpVOLUME_TYPE, volumeName,
1415 _DtHelpFileSuffixList,False,R_OK);
1416 if (volumeName == NULL)
1417 errno = DtErrorIllegalPath;
1419 else /* no second token */
1421 idToken = volumeName;
1422 /* find the fully qualified volume (volName is malloc'd) */
1423 volumeName = _DtHelpFileLocate(DtHelpVOLUME_TYPE, ref_volume,
1424 _DtHelpFileSuffixList,False,R_OK);
1425 if (volumeName == NULL)
1426 errno = DtErrorIllegalPath;
1429 if (idToken && volumeName)
1431 *ret_helpVolume = volumeName; /* already allocd by _DtHelpFileLocate */
1432 *ret_locationId = strdup (idToken);
1433 if (*ret_locationId == NULL)
1434 errno = DtErrorMalloc;
1436 } /* if at least one token exists */
1440 return ( (*ret_helpVolume && *ret_locationId) ? 0 : -1 );
1442 } /* End _DtHelpProcessLinkData */
1444 /*****************************************************************************
1445 * Function: void _DtHelpFreeTopicData (char **helpList,
1446 * DtHelpHyperLines *hyperList)
1449 * helpList Specifies a pointer to a NULL terminated
1451 * hyperList Specifies a pointer to a NULL terminated
1452 * list of DtHelpHyperLines.
1456 * Purpose: _DtHelpFreeTopicData frees the data associated with a topic.
1458 *****************************************************************************/
1460 _DtHelpFreeTopicData (
1462 DtHelpHyperLines *hyperList)
1464 if (helpList != NULL)
1465 _DtHelpCeFreeStringArray (helpList);
1467 if (hyperList != NULL)
1468 DeallocateHyperArray (hyperList);
1470 } /* End _DtHelpFreeTopicData */
1472 /******************************************************************************
1473 * Function: int _DtHelpGetTopicChildren (char *helpVolume, char *topic_id,
1474 * char ***ret_children)
1477 * helpVolume Specifies a file path to the volume.
1478 * topic_id Specifies the id of the desired topic.
1479 * ret_children Returns a NULL terminated array of
1480 * strings. The memory for these strings
1481 * *IS OWNED* by the caller and must be freed
1484 * Returns: > 0 for success, -1 for failure.
1488 * Purpose: _DtHelpGetTopicChildren returns the topic ids of the children
1489 * for a given topic id.
1491 *****************************************************************************/
1493 _DtHelpGetTopicChildren (
1496 char ***ret_children)
1499 _DtHelpVolumeHdl volume = NULL;
1502 /* Initialize the pointer */
1503 *ret_children = NULL;
1505 /* find the volume (path is malloc'd) */
1506 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, helpVolume,
1507 _DtHelpFileSuffixList,False,R_OK);
1508 if (path == NULL) { errno = EINVAL; return -1; } /* RETURN */
1510 /* open new canvas or reuse old one with new size */
1511 _DtHelpProcessLock();
1512 if (MyCanvas == NULL)
1514 _DtHelpTermCreateCanvas(72,&MyCanvas); /* 72: arbitary value for max columns */
1515 if (MyCanvas == NULL)
1518 _DtHelpProcessUnlock();
1519 return -1; /* RETURN: errno=??? */
1523 if (_DtHelpOpenVolume (helpVolume, &volume) == -1)
1526 _DtHelpProcessUnlock();
1527 return -1; /* RETURN: errno=??? */
1530 /* release any previously opened volume */
1532 _DtHelpCloseVolume (MyVolume);
1534 /* assign the new volume */
1537 /* Get the children */
1538 result = _DtHelpCeGetTopicChildren(MyVolume, topic_id, ret_children);
1540 _DtHelpProcessUnlock();