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 /* $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);
360 wchar_t *wcp = (wchar_t *) string;
370 /*****************************************************************************
371 * Function: void TermRenderElem ();
379 *****************************************************************************/
382 _DtCvPointer client_data,
383 _DtCvElemType elem_type,
387 _DtCvFlags old_flags,
388 _DtCvFlags new_flags,
389 _DtCvElemType trav_type,
390 _DtCvPointer trav_data,
393 _DtCvStringInfo *strInfo;
394 _DtCvRenderInfo *posInfo = (_DtCvRenderInfo *) data;
396 if (_DtCvSTRING_TYPE == elem_type)
398 strInfo = (_DtCvStringInfo *) posInfo->info;
399 TermStrDraw (client_data, x, y, strInfo->string, strInfo->byte_len,
400 strInfo->wc , strInfo->font_ptr,
401 posInfo->box_x , posInfo->box_y ,
402 posInfo->box_height, link_type,
403 old_flags , new_flags);
405 else if (_DtCvREGION_TYPE == elem_type)
407 const char *spcStr = (const char*) posInfo->info;
408 int len = spcStr ? strlen(spcStr) : 0;
410 TermStrDraw (client_data, x, y, spcStr, len, 0, 0,
411 posInfo->box_x , posInfo->box_y,
412 posInfo->box_height, link_type,
413 old_flags , new_flags);
417 /*****************************************************************************
418 * Function: void TermMetrics ();
426 *****************************************************************************/
427 static _DtCvSpaceMetrics defLinkMetrics = { 0, 0, 0, 0 };
431 _DtCvPointer client_data,
432 _DtCvElemType elem_type,
433 _DtCvPointer ret_metrics)
435 TerminalInfo *pTerm = (TerminalInfo *) client_data;
436 _DtCvSpaceMetrics *retSpace = (_DtCvSpaceMetrics *) ret_metrics;
438 if (_DtCvCANVAS_TYPE == elem_type)
440 _DtCvMetrics *retCanvas = (_DtCvMetrics *) ret_metrics;
442 retCanvas->width = pTerm->max_columns;
443 retCanvas->height = 50;
444 retCanvas->top_margin = 0;
445 retCanvas->side_margin = 0;
446 retCanvas->line_height = 1;
447 retCanvas->horiz_pad_hint = 1;
450 else if (_DtCvLOCALE_TYPE == elem_type)
452 _DtCvLocale *retLocale = (_DtCvLocale *) ret_metrics;
454 retLocale->line_wrap_mode = _DtCvModeWrapNone;
455 retLocale->cant_begin_chars = pTerm->cant_begin_chars;
456 retLocale->cant_end_chars = pTerm->cant_end_chars;
458 else if (_DtCvLINK_TYPE == elem_type || _DtCvTRAVERSAL_TYPE == elem_type)
459 *retSpace = defLinkMetrics;
462 /*****************************************************************************
463 * Function: void TermGetFont ();
471 *****************************************************************************/
474 _DtCvPointer client_data,
477 _DtHelpFontHints font_attr,
478 _DtCvPointer *ret_font )
480 *ret_font = (_DtCvPointer) 0;
483 /*****************************************************************************
484 * Function: _DtCvStatus TermResolveSpc ();
492 *****************************************************************************/
495 _DtCvPointer client_data,
498 _DtHelpFontHints font_attr,
500 _DtCvPointer *ret_handle,
501 _DtCvUnit *ret_width,
502 _DtCvUnit *ret_height,
503 _DtCvUnit *ret_ascent)
508 * initialize the returned information to nothing.
515 spcStr = _DtHelpCeResolveSpcToAscii (spc_symbol);
519 *ret_handle = ((_DtCvPointer)(spcStr));
521 *ret_width = strlen(spcStr);
528 /*****************************************************************************
529 * Function: void TermFontMetrics ();
537 *****************************************************************************/
540 _DtCvPointer client_data,
541 _DtCvPointer font_ptr,
542 _DtCvUnit *ret_ascent,
543 _DtCvUnit *ret_descent,
544 _DtCvUnit *char_width,
545 _DtCvUnit *ret_super,
562 /*****************************************************************************
563 * Function: _DtCvUnit TermStrWidth ();
571 *****************************************************************************/
574 _DtCvPointer client_data,
575 _DtCvElemType elem_type,
578 _DtCvStringInfo *strInfo = (_DtCvStringInfo *) data;
580 if (elem_type != _DtCvSTRING_TYPE)
583 return ((_DtCvUnit)(strInfo->byte_len));
586 /******************************************************************************
587 * End Canvas functions
588 * Begin other private functions
589 ******************************************************************************/
591 /******************************************************************************
592 * Function: DtHelpHyperLines *AddHyperToArray (DtHelpHyperLines *array_ptr,
593 * int value, char *link_spec, char *title)
596 * array_ptr Specifies a NULL terminated list of
597 * DtHelpHyperLines or NULL.
598 * value Specifies the link type.
599 * link_spec Specifies the link specification.
600 * title Specifies the title of the link.
602 * Returns: A ptr to the new DtHelpHyperLines if successful,
608 * Purpose: Add a hypertext link to an array of DtHelpHyperLines.
610 *****************************************************************************/
611 static DtHelpHyperLines *
613 DtHelpHyperLines *array_ptr,
619 DtHelpHyperLines *next;
625 for (next = array_ptr; next->specification != NULL; next++)
628 if (((num + 1) % GROW_SIZE) == 0)
629 array_ptr = (DtHelpHyperLines *) realloc ((void *) array_ptr,
630 (sizeof (DtHelpHyperLines) * (num + 1 + GROW_SIZE)));
633 array_ptr = (DtHelpHyperLines *) malloc (
634 sizeof (DtHelpHyperLines) * GROW_SIZE);
636 if (array_ptr == NULL)
637 errno = DtErrorMalloc;
640 next = array_ptr + num;
642 next->hyper_type = value;
643 next->win_hint = win_hint;
644 next->specification = strdup(link_spec);
648 next->specification = NULL;
655 /******************************************************************************
656 * Function: void DeallocateHyperArray (DtHelpHyperLines *array_ptr)
659 * array_ptr Specifies a NULL terminated array of
666 * Purpose: De-allocate an array of DtHelpHyperLines structures.
668 *****************************************************************************/
670 DeallocateHyperArray(
671 DtHelpHyperLines *array_ptr )
673 register DtHelpHyperLines *next = array_ptr;
677 while (next->title && next->specification)
680 free (next->specification);
687 /******************************************************************************
688 * Function: int AddHyperToList(
692 * Returns: 0 if successful.
693 * -1 if unrecoverable errors.
694 * -2 if could not resolve the hypertext link.
698 * DtErrorFormattingLabel
699 * A label has illegal syntax.
701 * Invalid (negative) hypertype.
702 * DtErrorFormattingLink
705 * Invalid 'hyper_specification' in the
707 * DtErrorFormattingId
708 * Invalid <ID> syntax.
710 * Purpose: Process the result of a hypertext link, filling out
711 * a hypertext structure element with the information.
713 *****************************************************************************/
716 _DtHelpVolumeHdl volume,
719 DtHelpHyperLines **ret_list)
721 _DtCanvasStruct *myCanvas = (_DtCanvasStruct *)canvas;
722 _DtCvLinkInfo hyperInfo;
723 _DtHelpVolumeHdl newVol = NULL;
724 _DtHelpVolumeHdl useVol = volume;
725 char *volName = NULL;
727 char *allocName = NULL;
732 if (_DtLinkDbGetLinkInfo(myCanvas->link_data, i,
733 myCanvas->virt_functions.exec_cmd_filter,
734 myCanvas->client_data, &hyperInfo) == 0)
737 if (hyperInfo.description == NULL)
739 id = hyperInfo.specification;
740 switch (hyperInfo.hyper_type)
742 case _DtCvLinkType_CrossLink:
748 _DtHelpCeStrchr (spec," ",MB_CUR_MAX,&id);
754 /* find the volume (volName is malloc'd) */
755 allocName = _DtHelpFileLocate(DtHelpVOLUME_TYPE, volName,
756 _DtHelpFileSuffixList,False,R_OK);
757 if (allocName == NULL)
760 if (_DtHelpOpenVolume(allocName, &newVol)==0)
771 case _DtCvLinkType_SameVolume:
774 result = _DtHelpGetTopicTitle(useVol, id, &title);
776 HyperErr = DtErrorLocIdNotFound;
780 _DtHelpCloseVolume(newVol);
783 if (allocName != NULL)
788 case _DtCvLinkType_Execute:
789 title = (char *) malloc(strlen(id) + 11);
790 sprintf(title, "Execute \"%s\"", id);
793 case _DtCvLinkType_ManPage:
794 title = (char *) malloc(strlen(id) + 13);
795 sprintf(title, "Man Page \"%s\"", id);
798 case _DtCvLinkType_AppDefine:
799 title = (char *) malloc(strlen(id) + 26);
800 sprintf(title, "Application Link Type \"%s\"", id);
803 case _DtCvLinkType_TextFile:
804 title = (char *) malloc(strlen(id) + 12);
805 sprintf(title, "Text File \"%s\"", id);
808 title = strdup ("Unkown link type");
815 title = strdup (hyperInfo.description);
820 *ret_list = AddHyperToArray (*ret_list, -(hyperInfo.hyper_type + 1),
822 hyperInfo.specification,
823 strdup("Invalid Link"));
824 else if (result >= 0)
825 *ret_list = AddHyperToArray (*ret_list, hyperInfo.hyper_type,
827 hyperInfo.specification,
831 * report unable to resolve the hypertext link
836 if (result == -1 || *ret_list == NULL)
841 } /* End AddHyperToList */
843 /******************************************************************************
844 * Function: TerminalInfo * GetTermInfo(canvasHandle)
847 * canvasHandle Canvas whose client_data is a TerminalInfo *
849 * Returns: 0 for success, -1 for failure.
851 ******************************************************************************/
852 static TerminalInfo *
854 _DtCvHandle canvasHandle)
856 _DtCanvasStruct * canvas = (_DtCanvasStruct *) canvasHandle;
858 return (TerminalInfo *) canvas->client_data;
861 /******************************************************************************
865 ******************************************************************************/
866 /******************************************************************************
867 * Function: int _DtHelpTermCreateCanvas (int maxColumns,_DtCvHandle * ret_canvas)
870 * maxColumns Specifies the column width of the window
871 * for which to format the information.
872 * ret_canvas handle to the canvas that was created
874 * Returns: 0 for success, -1 for failure.
877 * EINVAL 'ret_canvas' was NULL or 'maxColumns'
879 * ENOMEM unable to allocate necessary memory
882 * Purpose: _DtHelpTermCreateCanvas creates a canvas that use
883 * text-only content processing routines
885 *****************************************************************************/
887 _DtHelpTermCreateCanvas (
889 _DtCvHandle * ret_canvas)
891 TerminalInfo * termInfo;
894 * check the parameters
896 if (maxColumns < 1 || ret_canvas == NULL)
902 termInfo = (TerminalInfo *) malloc(sizeof(TerminalInfo));
903 if (termInfo == NULL)
909 /* init info and create a canvas */
910 *termInfo = DfltTermInfo;
911 termInfo->max_columns = maxColumns;
913 _DtHelpLoadMultiInfo(&(termInfo->cant_begin_chars),
914 &(termInfo->cant_begin_chars),
915 &(termInfo->nl_to_space));
917 *ret_canvas = _DtCanvasCreate (TermVirtInfo, (_DtCvPointer) termInfo);
919 if (*ret_canvas == NULL)
926 /******************************************************************************
927 * Function: int _DtHelpTermGetTopicData(canvasHandle,volHandle,
928 * locationId,helpList,hyperList)
931 * canvasHandle Canvas used to retrieve the info; MUST
932 * be a Terminal canvas Since it isn't easy
933 * to verify this, we don't try. So if the
934 * Canvas ISN'T a Terminal Canvas, we'll
936 * volHandle Help volume to use
937 * locationId Specifies the locationId of the desired topic.
938 * helpList Returns a NULL terminated array of
940 * hyperList Returns a NULL terminated array of
941 * DtHelpHyperLines containing the hyperlinks
942 * found in the topic.
944 * Returns: 0 for success, -1 for failure.
947 * EINVAL 'helpVolume', 'locationId', 'helpList',
948 * or 'hyperList' were NULL. 'maxColumns'
950 * open(2) errno set via an open call on
951 * the file for 'locationId'.
953 * DtErrorExceedMaxSize
954 * When following symbolic links, the
955 * new path will exceed the system
956 * maximum file path length.
958 * When following symbolic links, the
959 * new path would change to a parent
960 * directory beyond the beginning
962 * DtErrorIllegalDatabaseFile
963 * Specifies that 'helpVolume' is
964 * an illegal database file.
965 * DtErrorMissingFilenameRes
966 * Specifies that the 'Filename/filename'
967 * resource for the topic does not exist.
968 * DtErrorMissingFileposRes
969 * Specifies that the 'Filepos/filepos'
970 * resource for the topic does not exist.
971 * DtErrorLocIdNotFound
972 * Specifies that 'locationId' was not found.
973 * DtErrorFormattingLabel
974 * A label has illegal syntax.
976 * Invalid (negative) hypertype.
977 * DtErrorFormattingLink
980 * Invalid 'hyper_specification' in the
982 * DtErrorFormattingId
983 * Invalid <ID> syntax.
984 * DtErrorFormattingTitle
985 * Invalid <TITLE> syntax.
987 * Purpose: _DtHelpTermGetTopicData retrieves Help Files content with
988 * in a form understood by a terminal
990 *****************************************************************************/
992 _DtHelpTermGetTopicData(
993 _DtCvHandle canvasHandle,
994 _DtHelpVolumeHdl volHandle,
997 DtHelpHyperLines ** hyperList)
1004 char* fileName = NULL;
1005 _DtHelpCeLockInfo lockInfo;
1006 _DtCvTopicPtr topic;
1007 TerminalInfo * termInfo;
1008 _FrmtUiInfo myUiInfo;
1010 termInfo = GetTermInfo(canvasHandle);
1012 _DtHelpProcessLock();
1014 mbtowc (&WcSpace, " ", 1);
1015 _DtHelpProcessUnlock();
1018 * find the filename and the Id string.
1020 if (_DtHelpCeLockVolume(volHandle, &lockInfo) != 0)
1025 if (_DtHelpCeFindId(volHandle,locationId,lockInfo.fd,&fileName,&offset)==0)
1027 _DtHelpCeUnlockVolume(lockInfo);
1032 * create the ui structure for the parsing.
1035 myUiInfo.load_graphic = TermFindGraphic;
1037 myUiInfo.load_graphic = NULL;
1039 myUiInfo.resolve_spc = TermResolveSpc;
1040 myUiInfo.load_font = TermGetFont;
1041 myUiInfo.destroy_region = NULL;
1042 myUiInfo.exec_filter = NULL;
1043 myUiInfo.client_data = (_DtCvPointer) termInfo;
1044 myUiInfo.line_width = 0;
1045 myUiInfo.line_height = 1;
1046 myUiInfo.leading = 0;
1047 myUiInfo.avg_char = 1;
1048 myUiInfo.nl_to_space = termInfo->nl_to_space;
1053 result = _DtHelpCeGetVolumeFlag(volHandle);
1055 _DtHelpProcessLock();
1057 result = _DtHelpCeParseSdlTopic(volHandle,
1060 offset, NULL, True, &topic);
1061 else if (result == 0)
1062 result = _DtHelpCeFrmtCcdfTopic(volHandle, fileName,
1063 offset, NULL, &myUiInfo,
1065 _DtHelpProcessUnlock();
1067 /* if successfully formatted topic */
1073 _DtCanvasStruct *myCStruct = (_DtCanvasStruct *)canvasHandle;
1075 /* build the help text list, if requested */
1076 if (NULL != helpList)
1078 _DtCanvasSetTopic(canvasHandle, topic, _DtCvIGNORE_BOUNDARY,
1079 &maxWidth, &maxRows, NULL);
1082 * The 'maxRows' variable is really misnamed; it's really the
1083 * 'maxY', and is 0-based. Thus, the 'lines' and 'wc_num'
1084 * arrays need to be 'maxRows+1', in order to hold all the
1085 * entries. Likewise, 'strList' must be 'maxRows+2', because
1086 * it also needs to be NULL terminated.
1088 termInfo->lines = (wchar_t **)malloc(sizeof(wchar_t *) *(maxRows+1));
1089 termInfo->wc_num = (size_t *)malloc(sizeof(size_t) * (maxRows+1));
1090 strList = (char **) malloc(sizeof(char *) * (maxRows+2));
1091 if (termInfo->lines == NULL || termInfo->wc_num == NULL ||
1095 if (termInfo->lines != NULL)
1096 free(termInfo->lines);
1097 if (termInfo->wc_num != NULL)
1098 free(termInfo->wc_num);
1099 if (strList != NULL)
1101 _DtHelpCeUnlockVolume(lockInfo);
1105 for (i = 0; i <= maxRows; i++)
1107 termInfo->lines[i] = NULL;
1108 termInfo->wc_num[i] = 0;
1111 _DtCanvasRender(canvasHandle, 0, 0, maxWidth, maxRows,
1112 _DtCvRENDER_PARTIAL, _DtCvFALSE, NULL, NULL);
1114 *helpList = strList;
1115 wcList = termInfo->lines;
1116 for (i = 0; i <= maxRows; i++, wcList++, strList++)
1118 if (*wcList == NULL)
1120 *strList = (char *) malloc (1);
1125 len = (termInfo->wc_num[i] + 1) * MB_CUR_MAX;
1126 *strList = (char *) malloc (sizeof (char) * len);
1127 if (*strList != NULL)
1128 wcstombs(*strList, *wcList, len);
1135 * free the allocated memory
1137 for (i = 0, wcList = termInfo->lines; i <= maxRows; i++, wcList++)
1138 if (*wcList != NULL)
1140 free(termInfo->lines);
1141 free(termInfo->wc_num);
1143 } /* if requested help text */
1146 * build the hyperlinks list, if requested
1148 if ( NULL != hyperList )
1151 for (i = 0; result != -1 && i < myCStruct->link_data->max; i++)
1152 result = AddHyperToList(volHandle, canvasHandle, i, hyperList);
1154 } /* if successfully formatted topic */
1156 _DtCanvasClean(canvasHandle);
1157 _DtHelpDestroyTopicData(topic, NULL, NULL);
1160 _DtHelpCeUnlockVolume(lockInfo);
1163 } /* End _DtHelpTermGetTopicData */
1165 /******************************************************************************
1166 * Function: int _DtHelpGetTopicDataHandles(ret_canvasHandle,ret_volHandle)
1169 * ret_canvasHandle Canvas used to retrieve the info
1170 * ret_volHandle Help volume in use
1173 * 0: canvas handle & volHandle are not NULL
1174 * -1: canvas handle & volHandle are NULL
1175 ******************************************************************************/
1177 _DtHelpGetTopicDataHandles(
1178 _DtCvHandle * ret_canvasHandle,
1179 _DtHelpVolumeHdl * ret_volHandle)
1181 _DtHelpProcessLock();
1182 *ret_canvasHandle = MyCanvas;
1183 *ret_volHandle = MyVolume;
1184 if (MyCanvas != NULL && MyVolume != NULL)
1186 _DtHelpProcessUnlock();
1191 _DtHelpProcessUnlock();
1197 /******************************************************************************
1198 * Function: int _DtHelpGetTopicData (char *helpVolume, char *locationId,
1199 * int maxColumns, char ***helpList, DtHelpHyperLines **hyperList)
1202 * helpVolume Specifies a file path to the volume.
1203 * locationId Specifies the locationId of the desired topic.
1204 * maxColumns Specifies the column width of the window
1205 * for which to format the information.
1206 * helpList Returns a NULL terminated array of
1208 * hyperList Returns a NULL terminated array of
1209 * DtHelpHyperLines containing the hyperlinks
1210 * found in the topic.
1212 * Returns: 0 for success, -1 for failure.
1215 * EINVAL 'helpVolume', 'locationId', 'helpList',
1216 * or 'hyperList' were NULL. 'maxColumns'
1217 * was less than one.
1218 * getcwd(2) errno set via a getcwd call.
1219 * readlink(2) errno set via a readlink call.
1220 * open(2) errno set via an open call on
1221 * the file for 'locationId'.
1223 * DtErrorExceedMaxSize
1224 * When following symbolic links, the
1225 * new path will exceed the system
1226 * maximum file path length.
1227 * DtErrorIllegalPath
1228 * When following symbolic links, the
1229 * new path would change to a parent
1230 * directory beyond the beginning
1232 * DtErrorIllegalDatabaseFile
1233 * Specifies that 'helpVolume' is
1234 * an illegal database file.
1235 * DtErrorMissingFilenameRes
1236 * Specifies that the 'Filename/filename'
1237 * resource for the topic does not exist.
1238 * DtErrorMissingFileposRes
1239 * Specifies that the 'Filepos/filepos'
1240 * resource for the topic does not exist.
1241 * DtErrorLocIdNotFound
1242 * Specifies that 'locationId' was not found.
1243 * DtErrorFormattingLabel
1244 * A label has illegal syntax.
1246 * Invalid (negative) hypertype.
1247 * DtErrorFormattingLink
1250 * Invalid 'hyper_specification' in the
1252 * DtErrorFormattingId
1253 * Invalid <ID> syntax.
1254 * DtErrorFormattingTitle
1255 * Invalid <TITLE> syntax.
1257 * Purpose: _DtHelpGetTopicData formats Help Files with
1258 * formatting information
1259 * into a form understood by a terminal
1261 *****************************************************************************/
1263 _DtHelpGetTopicData (
1267 char * * * helpList,
1268 DtHelpHyperLines * * hyperList )
1271 _DtHelpVolumeHdl volume = NULL;
1274 /* find the volume (path is malloc'd) */
1275 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, helpVolume,
1276 _DtHelpFileSuffixList,False,R_OK);
1277 if (path == NULL) { errno = EINVAL; return -1; } /* RETURN */
1279 /* open new canvas or reuse old one with new size */
1280 _DtHelpProcessLock();
1281 if (MyCanvas == NULL)
1283 _DtHelpTermCreateCanvas(maxColumns,&MyCanvas);
1284 if (MyCanvas == NULL)
1287 _DtHelpProcessUnlock();
1288 return -1; /* RETURN: errno=from CreateCanvas */
1293 MyInfo.max_columns = maxColumns;
1294 _DtCanvasResize (MyCanvas, _DtCvFALSE, NULL, NULL);
1297 if (_DtHelpOpenVolume (helpVolume, &volume) == -1)
1300 _DtHelpProcessUnlock();
1301 return -1; /* RETURN: errno=from OpenVolume */
1304 /* release any previously opened volume */
1306 _DtHelpCloseVolume (MyVolume);
1308 /* assign the new volume */
1311 /* get the terminal info */
1312 result = _DtHelpTermGetTopicData(MyCanvas,MyVolume,locationId,helpList,hyperList);
1314 _DtHelpProcessUnlock();
1319 /*****************************************************************************
1320 * Function: int _DtHelpProcessLinkData (char * ref_volume,DtHelpHyperLines *hyperLine,
1321 * char **ret_helpVolume, char **ret_locationId)
1324 * hyperLine Specifies the hypertext line that
1325 * the caller wishes to be resolved.
1326 * helpVolume Returns the help volume specified by
1328 * locationId Returns the location Id specified by
1331 * Returns: 0 if successful, -1 if errors.
1334 * EINVAL 'hyperLines', 'helpVolume', or 'locationId'
1338 * The hyper type is not _DtJUMP_REUSE,
1339 * _DtJUMP_NEW, or _DtDEFINITION.
1341 * Invalid hyper specification.
1342 * DtErrorIllegalPath
1343 * The volume used by the link spec (either
1344 * embedded or the ref_volume) could not be
1347 * Purpose: _DtHelpProcessLinkData resolves a hypertext specification
1348 * into a pathname to a help volume and a location Id within
1351 *****************************************************************************/
1353 _DtHelpProcessLinkData (
1355 DtHelpHyperLines * hyperLine,
1356 char * * ret_helpVolume,
1357 char * * ret_locationId )
1359 char * linkSpec = NULL;
1360 char * volumeName = NULL;
1361 char * idToken = NULL;
1364 if (ref_volume == NULL || hyperLine == NULL ||
1365 ret_helpVolume == NULL || ret_locationId == NULL)
1371 /* only process SameVolume or CrossVolume links */
1372 switch (hyperLine->hyper_type)
1374 case _DtCvLinkType_SameVolume:
1375 case _DtCvLinkType_CrossLink:
1379 errno = DtErrorHyperType;
1380 return -1; /* RETURN */
1383 /* Initialize the pointers. */
1384 *ret_helpVolume = NULL;
1385 *ret_locationId = NULL;
1387 /* get working copy of spec */
1388 linkSpec = strdup (hyperLine->specification);
1389 if (linkSpec == NULL)
1391 errno = DtErrorMalloc;
1395 /* parse the link spec. Syntax is: "[volume] locationId" */
1396 if (linkSpec == NULL || *linkSpec == EOS)
1398 errno = DtErrorHyperSpec; /* no spec */
1400 else /* at least one token exists */
1402 volumeName = linkSpec; /* posit that first token is the volume */
1404 /* look for another possible token */
1406 _DtHelpCeStrchr (linkSpec," ",MB_CUR_MAX,&idToken);
1409 if (idToken) /* second token */
1411 /* separate the tokens and advance idToken to first valid char */
1412 *idToken = EOS; idToken++;
1414 /* find the fully qualified volume (volName is malloc'd) */
1415 volumeName = _DtHelpFileLocate(DtHelpVOLUME_TYPE, volumeName,
1416 _DtHelpFileSuffixList,False,R_OK);
1417 if (volumeName == NULL)
1418 errno = DtErrorIllegalPath;
1420 else /* no second token */
1422 idToken = volumeName;
1423 /* find the fully qualified volume (volName is malloc'd) */
1424 volumeName = _DtHelpFileLocate(DtHelpVOLUME_TYPE, ref_volume,
1425 _DtHelpFileSuffixList,False,R_OK);
1426 if (volumeName == NULL)
1427 errno = DtErrorIllegalPath;
1430 if (idToken && volumeName)
1432 *ret_helpVolume = volumeName; /* already allocd by _DtHelpFileLocate */
1433 *ret_locationId = strdup (idToken);
1434 if (*ret_locationId == NULL)
1435 errno = DtErrorMalloc;
1437 } /* if at least one token exists */
1441 return ( (*ret_helpVolume && *ret_locationId) ? 0 : -1 );
1443 } /* End _DtHelpProcessLinkData */
1445 /*****************************************************************************
1446 * Function: void _DtHelpFreeTopicData (char **helpList,
1447 * DtHelpHyperLines *hyperList)
1450 * helpList Specifies a pointer to a NULL terminated
1452 * hyperList Specifies a pointer to a NULL terminated
1453 * list of DtHelpHyperLines.
1457 * Purpose: _DtHelpFreeTopicData frees the data associated with a topic.
1459 *****************************************************************************/
1461 _DtHelpFreeTopicData (
1463 DtHelpHyperLines *hyperList)
1465 if (helpList != NULL)
1466 _DtHelpCeFreeStringArray (helpList);
1468 if (hyperList != NULL)
1469 DeallocateHyperArray (hyperList);
1471 } /* End _DtHelpFreeTopicData */
1473 /******************************************************************************
1474 * Function: int _DtHelpGetTopicChildren (char *helpVolume, char *topic_id,
1475 * char ***ret_children)
1478 * helpVolume Specifies a file path to the volume.
1479 * topic_id Specifies the id of the desired topic.
1480 * ret_children Returns a NULL terminated array of
1481 * strings. The memory for these strings
1482 * *IS OWNED* by the caller and must be freed
1485 * Returns: > 0 for success, -1 for failure.
1489 * Purpose: _DtHelpGetTopicChildren returns the topic ids of the children
1490 * for a given topic id.
1492 *****************************************************************************/
1494 _DtHelpGetTopicChildren (
1497 char ***ret_children)
1500 _DtHelpVolumeHdl volume = NULL;
1503 /* Initialize the pointer */
1504 *ret_children = NULL;
1506 /* find the volume (path is malloc'd) */
1507 path = _DtHelpFileLocate(DtHelpVOLUME_TYPE, helpVolume,
1508 _DtHelpFileSuffixList,False,R_OK);
1509 if (path == NULL) { errno = EINVAL; return -1; } /* RETURN */
1511 /* open new canvas or reuse old one with new size */
1512 _DtHelpProcessLock();
1513 if (MyCanvas == NULL)
1515 _DtHelpTermCreateCanvas(72,&MyCanvas); /* 72: arbitary value for max columns */
1516 if (MyCanvas == NULL)
1519 _DtHelpProcessUnlock();
1520 return -1; /* RETURN: errno=??? */
1524 if (_DtHelpOpenVolume (helpVolume, &volume) == -1)
1527 _DtHelpProcessUnlock();
1528 return -1; /* RETURN: errno=??? */
1531 /* release any previously opened volume */
1533 _DtHelpCloseVolume (MyVolume);
1535 /* assign the new volume */
1538 /* Get the children */
1539 result = _DtHelpCeGetTopicChildren(MyVolume, topic_id, ret_children);
1541 _DtHelpProcessUnlock();