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: FormatCCDF.c /main/23 1999/10/14 15:06:28 mgreess $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 ** Project: Unix Desktop Help
31 ** Description: This code formats an file in CCDF (Cache Creek
32 ** Distribution Format) into internal format.
34 ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
36 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
37 ** (c) Copyright 1993, 1994 International Business Machines Corp.
38 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
39 ** (c) Copyright 1993, 1994 Novell, Inc.
43 ****************************************************************************
44 ************************************<+>*************************************/
53 #include <sys/utsname.h>
62 #include <X11/Xresource.h>
69 * Canvas Engine includes
72 #include "CanvasSegP.h"
82 #include "AccessCCDFI.h"
83 #include "CanvasError.h"
85 #include "CvStringI.h"
86 #include "CvtToArrayP.h"
87 #include "FontAttrI.h"
88 #include "FormatUtilI.h"
89 #include "FormatCCDFI.h"
90 #include "CCDFUtilI.h"
91 #include "HelpXlate.h"
92 #include "StringFuncsI.h"
94 extern char *_DtHelpGetLocale(void);
99 /******************************************************************************
100 * Private variables and defines.
101 *****************************************************************************/
102 #define BUFF_SIZE 1024
104 #define INFO_GROW 256
106 #define CCDF_LINK_JUMP_REUSE 0
107 #define CCDF_LINK_JUMP_NEW 1
108 #define CCDF_LINK_DEFINITION 2
109 #define CCDF_LINK_EXECUTE 3
110 #define CCDF_LINK_MAN_PAGE 4
111 #define CCDF_LINK_APP_DEFINE 5
113 #define IsTypeHyperText(x) (((x) & _DtCvHYPER_TEXT) ? 1 : 0)
114 #define IsTypeNewLine(x) (((x) & _DtCvNEW_LINE) ? 1 : 0)
115 #define NextAvailSeg(x) (NULL != x.list ? &(x.list[x.cnt]) : NULL)
117 /******************************************************************************
119 ******************************************************************************/
120 typedef struct _segList {
126 typedef struct _formatVariables {
138 char *topic_char_set;
153 _DtCvLinkDb my_links;
154 _FrmtUiInfo *ui_info;
164 typedef enum _processState ProcessState;
166 /******************************************************************************
167 * Private Function Declarations
168 ******************************************************************************/
169 static _DtCvSegment *AllocateSegments(
173 static int AppendCharToInfo(
174 FormatVariables *cur_vars,
176 static int AppendOctalToInfo(
177 FormatVariables *cur_vars,
179 static int AppendSpaceToInfo (
180 FormatVariables *cur_vars,
182 _DtCvFrmtOption type );
183 static int AppendToInfo (
184 FormatVariables *cur_vars,
186 const char *scan_string );
187 static int ChangeFont(
189 unsigned long seg_flags,
190 _DtCvFrmtOption frmt_type,
191 _DtHelpFontHints *font_attr,
193 FormatVariables *cur_vars,
194 ProcessState cur_state,
198 static int CheckIdString(
199 FormatVariables *cur_vars,
200 ProcessState cur_state,
201 unsigned long seg_flags,
202 _DtCvFrmtOption frmt_type,
203 _DtHelpFontHints *font_attr,
208 static int CheckSaveSegment (
209 unsigned long seg_flags,
210 _DtHelpFontHints *font_attr,
212 FormatVariables *cur_vars );
213 static int CreateSaveGraphic (
214 FormatVariables *cur_vars,
218 static int CheckSegList (
219 FormatVariables *cur_vars);
221 FormatVariables *cur_vars,
222 _FrmtUiInfo *ui_info,
224 _DtCvTopicPtr *ret_handle);
225 static int GetNextBuffer (
226 FormatVariables *cur_vars);
227 static int GetStringParameter(
228 FormatVariables *cur_vars,
230 _DtCvValue eat_escape,
231 _DtCvValue ignore_quotes,
232 _DtCvValue less_test,
234 static int GetValueParameter(
235 FormatVariables *cur_vars,
238 static int InitStructure(
239 FormatVariables *cur_vars,
240 _FrmtUiInfo *ui_info,
245 ProcessState cur_state,
246 FormatVariables *cur_vars,
247 unsigned long seg_flags,
248 _DtCvFrmtOption frmt_type,
249 _DtHelpFontHints *font_attr,
251 const char *scan_string,
255 static int ProcessFigureCmd(
256 FormatVariables *cur_vars,
257 ProcessState cur_state,
258 _DtCvFrmtOption frmt_type,
259 _DtHelpFontHints *font_attr,
262 static int ProcessHypertext(
263 FormatVariables *cur_vars,
264 ProcessState cur_state,
265 unsigned long seg_flags,
266 _DtCvFrmtOption frmt_type,
267 _DtHelpFontHints *font_attr,
271 static int ProcessInLine(
272 FormatVariables *cur_vars,
275 static int ProcessLabelCmd(
276 FormatVariables *cur_vars,
277 unsigned long seg_flags,
278 _DtCvFrmtOption frmt_type,
279 _DtHelpFontHints *font_attr,
284 _DtCvSegment **ret_list);
285 static int ProcessParagraph (
286 FormatVariables *cur_vars,
287 ProcessState cur_state,
289 static int SaveNewLine(
290 FormatVariables *cur_vars,
292 _DtHelpFontHints *font_attr,
294 static int SaveStringAsSegments (
295 FormatVariables *cur_vars,
296 unsigned long seg_flags,
297 _DtHelpFontHints *font_attr,
299 static int SkipToNextToken (
300 FormatVariables *cur_vars,
302 static void TerminateSegList (
305 static int SegmentSave(
306 FormatVariables *cur_vars,
307 unsigned long seg_type,
308 _DtHelpFontHints *font_attr,
314 /******** End Public Function Declarations ********/
316 /******************************************************************************
318 *****************************************************************************/
319 static const char *Specials = "<\n\\ ";
320 static const char *SpaceString = " ";
321 static const char *CString = "C";
322 static const char *Period = ".";
323 static const char *Slash = "/";
325 static const FormatVariables DefVars = {
326 True, /* int last_was_space; */
327 False, /* int last_was_mb; */
328 False, /* int last_was_nl; */
330 NULL, /* char *rd_buf; */
331 NULL, /* char *rd_ptr; */
332 NULL, /* char *fmt_buf; */
333 NULL, /* char *my_path; */
334 NULL, /* char *vol_name; */
335 NULL, /* char *topic_id; */
336 NULL, /* char *topic_char_set; */
337 NULL, /* char *topic_lang; */
339 0, /* int rd_size; */
340 0, /* int rd_flag; */
342 1, /* int topic_mb_max; */
343 1, /* int cur_mb_max; */
345 0, /* int fmt_buf_max; */
346 0, /* int fmt_size; */
347 0, /* int cell_cnt; */
349 NULL, /* BufFilePtr my_file; */
350 { /* SegList my_list; */
353 NULL, /* _DtCvSegment *list; */
354 }, /* SegList my_list; */
355 NULL, /* _DtCvLinkDb my_links; */
356 NULL, /* _FrmtUiInfo ui_info; */
359 static const SegList InitList =
363 NULL, /* _DtCvSegment *list; */
366 static const _DtCvContainer DefContainer =
368 NULL, /* char *id; */
369 NULL, /* char *justify_char; */
370 _DtCvDYNAMIC, /* _DtCvFrmtOption type; */
371 _DtCvBORDER_NONE, /* _DtCvFrmtOption border; */
372 _DtCvJUSTIFY_LEFT, /* _DtCvFrmtOption justify; */
373 _DtCvJUSTIFY_TOP, /* _DtCvFrmtOption vjustify; */
374 _DtCvJUSTIFY_LEFT_MARGIN,/* _DtCvFrmtOption orient; */
375 _DtCvJUSTIFY_TOP, /* _DtCvFrmtOption vorient; */
376 _DtCvWRAP_NONE, /* _DtCvFrmtOption flow; */
377 10000, /* int percent; */
378 0, /* _DtCvUnit leading; */
379 0, /* _DtCvUnit fmargin; */
380 0, /* _DtCvUnit lmargin; */
381 0, /* _DtCvUnit rmargin; */
382 0, /* _DtCvUnit tmargin; */
383 1, /* _DtCvUnit bmargin; */
384 {0, NULL}, /* _DtCvLine bdr_info; */
385 NULL, /* _DtCvSegment seg_list; */
388 static const FrmtPrivateInfo DefPrivInfo =
390 (char) False, /* char top_block; */
391 (char) False, /* char dup_flag; */
392 0, /* int sdl_type; */
393 0, /* void *match_info; */
394 NULL, /* void *id_info; */
395 NULL, /* void *tmp_info; */
398 /******************************************************************************
402 *****************************************************************************/
403 /******************************************************************************
404 * Function: int CreateMarker (
407 * cur_vars Specifies the current setting of
408 * formatting variables.
409 * id_string The id string for the marker.
411 * Returns: 0 if successful, -1 if failure.
413 * Purpose: To create a marker id.
415 *****************************************************************************/
418 FormatVariables *cur_vars,
424 * make sure there is room for the marker segment
426 result = CheckSegList(cur_vars);
429 int cnt = cur_vars->my_list.cnt;
430 _DtCvSegment *list = cur_vars->my_list.list;
433 * now make a mark segment here.
435 list[cnt].type = _DtCvSetTypeToMarker(list[cnt].type);
436 _DtCvIdOfMarkerSeg(&list[cnt]) = id_string;
437 cur_vars->my_list.cnt++;
443 /******************************************************************************
444 * Function: void GetMbLen (
447 * cur_vars Specifies the current setting of
448 * formatting variables.
449 * font_str Specifies the CCDF string for a
450 * CHARACTERSET change. The string is
451 * modified by this routine.
452 * lang_ptr Returns the language and territory
453 * value. The caller owns this memory.
454 * set_ptr Returns the code set of the language.
455 * The caller owns this memory.
459 * Purpose: 1) To decompose the font_string into a language and code set
461 * 2) To set the mb_cur_len variable in cur_vars.
463 *****************************************************************************/
466 FormatVariables *cur_vars,
473 char *langPart = NULL;
474 char *codePart = NULL;
479 while (*font_str == ' ')
482 for (i = strlen(font_str) - 1; i > -1 && font_str[i] == ' '; i--)
486 * check for locale.codeset
488 if (_DtHelpCeStrchr(font_str, ".", 1, &ptr) == 0)
491 * make font_str two separate strings by replacing
492 * the dot with a end of line.
495 langPart = strdup(font_str);
496 codePart = strdup(ptr);
504 _DtHelpCeXlateOpToStdLocale(DtLCX_OPER_CCDF, font_str,
505 NULL, &langPart, &codePart);
507 * if the language is not specified for the code set,
508 * get the environment's.
510 if (strcmp(langPart, "?") == 0)
514 langPart = _DtHelpGetLocale();
515 if (langPart == NULL || *langPart == '\0')
516 langPart = strdup((char *) CString);
517 else if (_DtHelpCeStrrchr(langPart, "_", MB_CUR_MAX, &ptr) == 0)
519 else if (_DtHelpCeStrrchr(langPart, Period, MB_CUR_MAX, &ptr) == 0)
524 cur_vars->cur_mb_max = _DtHelpCeGetMbLen(langPart, codePart);
527 * now set the return variables
529 if (lang_ptr != NULL)
530 *lang_ptr = langPart;
540 /******************************************************************************
541 * Function: int ReturnLinkWinHint (int ccdf_type)
550 *****************************************************************************/
555 int winHint = _DtCvWindowHint_CurrentWindow;
557 if (ccdf_type == CCDF_LINK_JUMP_NEW)
558 winHint = _DtCvWindowHint_NewWindow;
560 else if (ccdf_type == CCDF_LINK_DEFINITION)
561 winHint = _DtCvWindowHint_PopupWindow;
566 /******************************************************************************
567 * Function: int ReturnLinkType (int ccdf_type, char *spec)
576 *****************************************************************************/
582 int trueType = _DtCvLinkType_SameVolume;
586 case CCDF_LINK_JUMP_NEW:
587 case CCDF_LINK_JUMP_REUSE:
588 case CCDF_LINK_DEFINITION:
589 if (strchr(spec, ' ') != NULL)
590 trueType = _DtCvLinkType_CrossLink;
593 case CCDF_LINK_EXECUTE:
594 trueType = _DtCvLinkType_Execute;
597 case CCDF_LINK_MAN_PAGE:
598 trueType = _DtCvLinkType_ManPage;
601 case CCDF_LINK_APP_DEFINE:
602 trueType = _DtCvLinkType_AppDefine;
610 /******************************************************************************
611 * Function: int CheckSegList (FormatVariables *cur_vars)
615 * Returns: 0 for success, -1 for errors.
620 * Purpose: Check the global variable 'SegCount' against 'SegMax' and
621 * realloc/malloc more memory for the global variable 'SegList'
622 * if necessary. If memory is realloc'ed/malloc'ed, the entry
623 * 'para_entry->seg_list' is set to 'SegList'.
625 *****************************************************************************/
628 FormatVariables *cur_vars )
630 if (cur_vars->my_list.cnt >= cur_vars->my_list.max)
632 cur_vars->my_list.list = AllocateSegments (cur_vars->my_list.list,
633 cur_vars->my_list.max,
634 (cur_vars->my_list.max + GROW_SIZE));
636 if (NULL == cur_vars->my_list.list)
639 cur_vars->my_list.max += GROW_SIZE;
645 /******************************************************************************
646 * Function: static _DtCvSegment *AllocateSegments (_DtCvSegment p_seg,
647 * int original_size, int new_size)
650 * p_seg Specifies a pointer to the old list
652 * original_size Specifies the current size of 'p_seg'.
653 * new_size Specifies the new size of 'p_seg'.
655 * Returns: A pointer to the new list of structures.
656 * A NULL indicates an error.
658 * Purpose: (Re)Allocates _DtCvSegment structures and initializes
659 * them to the default segment which is type _DtCvNOOP
660 * and the container values set to default values.
662 *****************************************************************************/
663 static _DtCvSegment *
669 FrmtPrivateInfo *priv = NULL;
676 * reallocate the segments.
678 p_seg = (_DtCvSegment *) realloc ((void *) p_seg,
679 (sizeof(_DtCvSegment) * new_size));
681 * reallocate the private formatting information.
683 priv = p_seg->client_use;
684 priv = (FrmtPrivateInfo *) realloc ((void *) priv,
685 sizeof(FrmtPrivateInfo) * new_size);
694 * reattach the private information with their segments.
696 while (count < original_size)
697 p_seg[count++].client_use = priv++;
700 p_seg = _DtHelpAllocateSegments (new_size);
705 * want to 'empty' the type.
707 while (original_size < new_size)
710 * if we went through _DtHelpAllocateSegments, then the
711 * priv pointer will be NULL. But that's okay since the
712 * _DtHelpAllocateSegments routine will initalized the
713 * variables for us. The only reason we have to do it
714 * is if we've reallocated the list.
720 p_seg[original_size ].client_use = priv++;
721 p_seg[original_size ].type = _DtCvNOOP;
722 p_seg[original_size ].link_idx = -1;
723 p_seg[original_size ].next_seg = NULL;
724 p_seg[original_size ].next_disp = NULL;
727 p_seg[original_size++].handle.container = DefContainer;
734 /******************************************************************************
735 * Function: static int CheckList (
736 * FormatVariables cur_vars, int count, int grow)
739 * cur_vars Specifies a structure containing the list
741 * count Specifies the amount needed.
742 * grow Specifies the amount to grow by.
744 * Returns: 0 if successful, -1 if failure.
746 * Purpose: Makes sure there is 'grow' size number of segments
747 * available. If not, it calls AllocateSegments to 'grow'
748 * the segment list. cur_vars->seg_list is set to the new
749 * pointer, cur_vars->seg_max indicates the maximum number
750 * of segments in the list.
752 *****************************************************************************/
760 * what's the new count?
762 count += seg_list->cnt;
765 * is it larger than the current max?
767 if (count > seg_list->max)
770 * grow the list by the indicated amount.
772 grow += seg_list->max;
775 * check to see if it is enough. If not, force the grow value
776 * to be the required count.
784 seg_list->list = AllocateSegments(seg_list->list, seg_list->max, grow);
787 * return an code if no list allocated.
789 if (NULL == seg_list->list)
795 seg_list->max = grow;
801 /******************************************************************************
802 * Function: int SegmentSave (int type,
803 * char **font_attr, char *string, int linkspec,
804 * _DtCvSegment *p_seg)
807 * type Specifies the segment type.
808 * font_attr Specifies the resource list of quarks for the
809 * font to associate with the segment.
810 * string Specifies the string segment.
811 * link_spec Specifies the link specification for the
813 * p_seg Specifies the _DtCvSegment structure to
814 * initialize with the data.
816 * Returns: 0 if successful, -1 if errors.
821 * Purpose: Creates a new segment with the given data.
823 *****************************************************************************/
826 FormatVariables *cur_vars,
827 unsigned long seg_type,
828 _DtHelpFontHints *font_attr,
835 _DtCvSegment *pSeg = NextAvailSeg(cur_vars->my_list);
837 pSeg->type = _DtCvSetTypeToNoop(seg_type);
838 pSeg->link_idx = linkspec;
841 * We use this routine for many things.
842 * If we want an newline in here, we may not have any data.
846 pSeg->type = _DtCvSetTypeToString(pSeg->type);
849 * if a wide character representation is required,
852 if (seg_type & _DtCvWIDE_CHAR)
857 * include the null byte in the multibyte to widechar
865 pwcs = (wchar_t *) malloc(sizeof(wchar_t) * num_chars);
869 str_size = mbstowcs(pwcs, string, ((size_t) num_chars));
871 /* check to see if it converted everything */
872 if (str_size + 1 == num_chars)
873 _DtCvStringOfStringSeg(pSeg) = (void *) pwcs;
879 _DtCvStringOfStringSeg(pSeg) = (void *) strdup(string);
881 if (NULL == _DtCvStringOfStringSeg(pSeg))
885 * set the default font. This should really be passed in via
886 * the format entry point (or the ui_info structure).
888 _DtCvFontOfStringSeg(pSeg) = 0;
893 if (NULL != cur_vars->ui_info->load_font)
894 (*(cur_vars->ui_info->load_font))(
895 cur_vars->ui_info->client_data,
896 _DtHelpFontHintsLang(*font_attr),
897 _DtHelpFontHintsCharSet(*font_attr),
899 &(_DtCvFontOfStringSeg(pSeg)));
905 /******************************************************************************
906 * Function: int SaveStringAsSegments (FormatVariables, int type, char **font_attr,
910 * type Specifies the segment type.
911 * font_attr Specifies the resource list of quarks for the
912 * font to associate with the segment.
913 * link_spec Specifies the link specification for the
916 * Returns: 0 if successful, -1 if errors.
920 * Purpose: Saves a segment into the global 'SegList'. This is
921 * a wrapper around SegmentSave that adds specific
922 * information relative to this module.
924 *****************************************************************************/
926 SaveStringAsSegments (
927 FormatVariables *cur_vars,
928 unsigned long seg_flags,
929 _DtHelpFontHints *font_attr,
939 seg_flags = _DtCvSetTypeToNoop(seg_flags);
940 if (cur_vars->cur_mb_max != 1 && cur_vars->fmt_size > 1)
942 if (IsTypeNewLine(seg_flags))
945 seg_flags = seg_flags & ~(_DtCvNEW_LINE);
948 ptr = cur_vars->fmt_buf;
952 * what type of character is this?
954 len = mblen (ptr, cur_vars->cur_mb_max);
957 * How many of the following characters are of the same size?
959 size = _DtHelpFmtFindBreak (ptr, len, &numChars);
962 * save off the character that doesn't match
967 * put in the null byte for the string.
968 * and set to wide char if not doing multi-byte sequence.
972 seg_flags = _DtCvSetTypeToWideChar (seg_flags);
975 * does this segment get the newline flag?
977 if (True == newLine && size >= cur_vars->fmt_size)
978 seg_flags = _DtCvSetTypeToNewLine(seg_flags);
983 if (CheckSegList(cur_vars) == -1 ||
984 SegmentSave (cur_vars, seg_flags, font_attr, ptr, size,
985 numChars, link_spec) == -1)
989 * remove the wide char flag
991 seg_flags &= ~(_DtCvWIDE_CHAR);
994 * Bump the segment list count.
996 cur_vars->my_list.cnt++;
999 * replace the character that didn't match.
1000 * and bump the pointer to it.
1002 ptr[size] = tmpChar;
1004 cur_vars->fmt_size -= size;
1005 } while (0 < cur_vars->fmt_size);
1009 if (CheckSegList (cur_vars) == -1 ||
1010 SegmentSave (cur_vars, seg_flags, font_attr,
1011 cur_vars->fmt_buf, cur_vars->fmt_size,
1015 cur_vars->my_list.cnt++;
1018 cur_vars->fmt_size = 0;
1019 if (cur_vars->fmt_buf)
1020 cur_vars->fmt_buf[0] = '\0';
1025 /******************************************************************************
1026 * Function: int CheckSaveSegment (int type, char **font_attr, int link_spec,
1027 * FormatVariables cur_vars)
1030 * type Specifies the segment type.
1031 * font_attr Specifies the resource list of quarks for the
1032 * font to associate with the segment.
1033 * link_spec Specifies the link specification for the
1036 * Returns: 0 if successful, -1 if errors.
1040 * Purpose: Checks 'cur_vars->fmt_size' for a non-zero value. If it is,
1041 * calls SaveSegment.
1043 *****************************************************************************/
1046 unsigned long seg_flags,
1047 _DtHelpFontHints *font_attr,
1049 FormatVariables *cur_vars)
1053 if (cur_vars->fmt_size)
1054 result = SaveStringAsSegments (cur_vars, seg_flags, font_attr, link_spec);
1059 /******************************************************************************
1060 * Function: void TerminateSegList (
1064 * Returns: 0 if successful, -1 if errors.
1066 * Purpose: Links the segments together.
1068 *****************************************************************************/
1075 _DtCvSegment *lastDisp = NULL;
1078 if (True == flag && 0 == seg_list->cnt && NULL != seg_list->list)
1080 free(seg_list->list);
1081 *seg_list = InitList;
1085 * set the next segment and display segment pointers.
1087 for (count = 1, pSeg = seg_list->list; count < seg_list->cnt;
1091 * link this segment to the next segment
1093 pSeg->next_seg = &(pSeg[1]);
1096 * is this a displayable segment?
1097 * If so, link it into the displayable list.
1099 if (_DtCvIsSegNoop(pSeg) || _DtCvIsSegRegion(pSeg)
1100 || _DtCvIsSegString(pSeg))
1103 * Is there a displayable segment yet?
1104 * If so, set its next displayable link to this segment.
1106 if (NULL != lastDisp)
1107 lastDisp->next_disp = pSeg;
1110 * this segment becomes the last displayable segment.
1118 if (NULL != pSeg && NULL != lastDisp
1119 && (_DtCvIsSegNoop(pSeg) || _DtCvIsSegRegion(pSeg)
1120 || _DtCvIsSegString(pSeg)))
1121 lastDisp->next_disp = pSeg;
1125 /******************************************************************************
1126 * Function: int InitStructure (FormatVariables *cur_vars,
1127 * char *rd_buf, int rd_size,
1130 * rd_buffer Specifies the buffer all reads use.
1131 * id_string Specifies the location ID to search for.
1133 * Returns: 0 if successful, -1 if errors.
1137 * Purpose: Attach formatting information to the structure that gets
1138 * passed around by, among other things, setting the global
1139 * variable 'cur_vars->rd_ptr' to 'rd_buffer', and
1140 * remembering the location id.
1142 *****************************************************************************/
1145 FormatVariables *cur_vars,
1146 _FrmtUiInfo *ui_info,
1150 cur_vars->ui_info = ui_info;
1151 cur_vars->rd_size = rd_size;
1152 cur_vars->rd_buf = rd_buf;
1153 cur_vars->rd_ptr = cur_vars->rd_buf;
1155 cur_vars->fmt_size = 0;
1156 if (cur_vars->fmt_buf)
1157 cur_vars->fmt_buf[0] = '\0';
1160 * allocate the link data base.
1162 cur_vars->my_links = _DtLinkDbCreate();
1163 if (NULL == cur_vars->my_links)
1169 /******************************************************************************
1170 * Function: int AppendToInfo (FormatVariables *cur_vars,
1171 * char **src, const char *scan_string)
1174 * src Specifies the source string to read.
1175 * Returns pointing at a special character,
1176 * an invalid character or the
1178 * scan_string Specifies the special characters to
1179 * look for in 'src'.
1181 * Returns: 0 if stopped on a special character.
1182 * 1 if found the end of string.
1183 * 2 if found an invalid character.
1188 * Purpose: Appends onto 'cur_vars->fmt_buf' the number of characters
1189 * found in 'src' that does not match any character in
1192 * Sets 'cur_vars->last_was_space' to false (assumes that one
1193 * of the special characters is a space).
1195 *****************************************************************************/
1198 FormatVariables *cur_vars,
1200 const char *scan_string )
1205 cur_vars->last_was_space = False;
1206 spnResult = _DtHelpCeStrcspn(*src, scan_string, cur_vars->cur_mb_max,
1210 if (_DtHelpCeAddStrToBuf(src,&(cur_vars->fmt_buf),&(cur_vars->fmt_size),
1211 &(cur_vars->fmt_buf_max),size,INFO_GROW) == -1)
1213 cur_vars->last_was_space = False;
1216 if (spnResult == -1)
1219 if (0 == size && 1 == spnResult)
1225 /******************************************************************************
1226 * Function: int AppendOctalToInfo (FormatVariables *cur_vars, char *src)
1229 * src Specifies the source string to read.
1231 * Returns: 0 if successful, -1 if errors.
1234 * CEErrorFormattingValue
1237 * Purpose: Convert the octal representation pointed to by 'src' and
1238 * change it into a character byte. The routine only allows
1239 * a number between the values 1-255.
1241 * Append the byte onto the global variable 'Info'.
1242 * Set 'cur_vars->last_was_space' to false.
1244 *****************************************************************************/
1247 FormatVariables *cur_vars,
1253 if (((int)strlen(src)) < 4 && cur_vars->my_file != NULL)
1255 if (GetNextBuffer (cur_vars) == -1)
1258 src = cur_vars->rd_ptr;
1261 if (_DtHelpCeAddOctalToBuf(src,&(cur_vars->fmt_buf),&(cur_vars->fmt_size),
1262 &(cur_vars->fmt_buf_max),INFO_GROW) == -1)
1265 cur_vars->last_was_space = False;
1270 /******************************************************************************
1271 * Function: int AppendCharToInfo (FormatVariables *cur_vars, char **src)
1274 * src Specifies the source string to read.
1275 * Returns pointing at the next character
1278 * Returns: 0 if successful, -1 if errors.
1282 * Purpose: Appends the character pointed to by 'src' onto the
1283 * global buffer 'Info', updating the pointers associated
1284 * with 'Info' accordingly.
1286 * Sets 'cur_vars->last_was_space' to False;
1288 *****************************************************************************/ static int
1290 FormatVariables *cur_vars,
1293 cur_vars->last_was_space = False;
1294 return (_DtHelpCeAddCharToBuf (src, &(cur_vars->fmt_buf),
1295 &(cur_vars->fmt_size),
1296 &(cur_vars->fmt_buf_max), INFO_GROW));
1299 /******************************************************************************
1300 * Function: int AppendSpaceToInfo (char **src, int type)
1303 * src Specifies the source string to read.
1304 * Returns pointing at the next character
1306 * type Specifies the type of the segment being
1309 * Returns: 0 if successful, -1 if errors.
1313 * Purpose: Appends a space onto the global buffer 'Info', if
1314 * the variable 'cur_vars->last_was_space' is false or the
1315 * static string flag is set in 'type'.
1317 * Sets 'cur_vars->last_was_space' to true.
1319 *****************************************************************************/
1322 FormatVariables *cur_vars,
1324 _DtCvFrmtOption type)
1327 char *space = (char *) SpaceString;
1329 if (!cur_vars->last_was_space || _DtCvLITERAL == type) {
1331 result = _DtHelpCeAddCharToBuf (&space, &(cur_vars->fmt_buf),
1332 &(cur_vars->fmt_size),
1333 &(cur_vars->fmt_buf_max), INFO_GROW);
1334 cur_vars->last_was_space = True;
1342 /******************************************************************************
1343 * Function: int FindEndMarker (FormatVariables *cur_vars)
1345 * Returns: 0 if successful, -1 if errors.
1349 * Purpose: Wrapper around __DtHelpFindEndMarker.
1350 * Find the '>' token.
1352 *****************************************************************************/
1355 FormatVariables *cur_vars)
1357 return (_DtHelpCeGetCcdfEndMark (cur_vars->my_file, cur_vars->rd_buf,
1358 &(cur_vars->rd_ptr),cur_vars->rd_size,1));
1361 /******************************************************************************
1362 * Function: int GetNextBuffer (FormatVariables *cur_vars)
1364 * Returns: 0 if successful, -1 if errors.
1368 * Purpose: Wrapper around __DtHelpGetNextBuffer.
1369 * Read the next buffer's worth of information.
1371 *****************************************************************************/
1374 FormatVariables *cur_vars)
1376 cur_vars->rd_flag = _DtHelpCeGetNxtBuf (cur_vars->my_file,
1378 &(cur_vars->rd_ptr),
1380 return (cur_vars->rd_flag);
1383 /******************************************************************************
1384 * Function: int SaveNewLine (FormatVariables *cur_vars, int cur_type,
1389 * cur_cmd Specifies the type of segment being processed.
1390 * font_attr Specifies the list of font quarks associated
1391 * with the current segment.
1392 * link_spec Specifies the hypertext link specification
1393 * associated with the current segment.
1395 * Returns: 0 if successful, -1 if errors.
1399 * Purpose: Sets the newline flag on a segment and saves it by calling
1400 * 'SaveStringAsSegments'.
1401 * If the current segment is non-null, save it with the
1403 * Otherwise if there are no segments saved, create one with the
1404 * a type of CE_old_NOOP.
1405 * Otherwise there are other segments, but the current segment is
1406 * empty. Look back at the previous segment.
1407 * If it doesn't have the newline set on it,
1408 * its newline flag is enabled.
1409 * Otherwise the previous segment had the newline set, so
1410 * create another segment just like it with a
1411 * null length and the newline flag set (if the
1412 * previous segment is a graphic, create it
1413 * with a type of CE_old_NOOP).
1415 *****************************************************************************/
1418 FormatVariables *cur_vars,
1420 _DtHelpFontHints *font_attr,
1427 * If there is information in the buffer, save it with the newline flag
1429 if (cur_vars->fmt_size)
1430 result = SaveStringAsSegments (cur_vars, _DtCvSetTypeToNewLine (cur_type),
1431 font_attr, link_spec);
1433 * check to see if there is any segments. If not create a new one
1434 * with the type NOOP.
1436 else if (0 == cur_vars->my_list.cnt)
1437 result = SaveStringAsSegments (cur_vars, _DtCvSetTypeToNewLine(_DtCvNOOP),
1438 font_attr, link_spec);
1440 * There was not any information in the buffer and we have one or
1441 * more segments. Try placing the flag on the previous segment.
1445 pSeg = NextAvailSeg(cur_vars->my_list);
1449 * Does the previous segment already have a newline flag?
1450 * If so, create a new NOOP segment with the newline set.
1452 if (_DtCvIsSegNewLine (pSeg))
1453 result = SaveStringAsSegments (cur_vars, _DtCvSetTypeToNewLine (_DtCvNOOP),
1454 font_attr, link_spec);
1456 pSeg->type = _DtCvSetTypeToNewLine (pSeg->type);
1459 cur_vars->last_was_space = True;
1463 /******************************************************************************
1464 * Function: int CreateSaveGraphic (FormatVariables cur_vars,
1466 * char *file_name, int link_spec )
1469 * type Specifies the type of graphic segment
1471 * file_name Specifies the file name of the graphic.
1472 * link_spec Specifies the hypertext link specification
1473 * associated with the graphic.
1475 * Returns: 0 if successful, -1 if errors.
1477 * Purpose: Save a graphic segment.
1478 * If 'file_name' is not an absolute path, resolve it to
1479 * a full path by using the path to the volume.
1481 *****************************************************************************/
1484 FormatVariables *cur_vars,
1490 _DtCvSegment *cvRegion;
1492 if (CheckList (&(cur_vars->my_list), 1, 1) == -1)
1496 * create the path to the file name
1498 if (*file_name == '/')
1499 fullName = strdup (file_name);
1502 fullName = (char *) malloc (strlen (cur_vars->my_path) +
1503 strlen (file_name) + 2);
1504 if (fullName == NULL)
1507 strcpy (fullName, cur_vars->my_path);
1508 strcat (fullName, "/");
1509 strcat (fullName, file_name);
1513 * load the graphic into the current segment
1515 cvRegion = NextAvailSeg(cur_vars->my_list);
1516 if (NULL != cur_vars->ui_info->load_graphic &&
1517 (*(cur_vars->ui_info->load_graphic))(
1518 cur_vars->ui_info->client_data,
1524 &(_DtCvWidthOfRegionSeg(cvRegion)),
1525 &(_DtCvHeightOfRegionSeg(cvRegion)),
1526 &(_DtCvInfoOfRegionSeg(cvRegion))) == 0)
1529 * set the type and index.
1530 * and indicate that this segment has been used.
1532 _DtCvAscentOfRegionSeg(cvRegion) = -1;
1533 cvRegion->type = _DtCvSetTypeToRegion(type);
1534 cvRegion->link_idx = link_spec;
1535 cur_vars->my_list.cnt++;
1539 * free the file name path
1546 /******************************************************************************
1547 * Function: int ChangeFont (int whichOne, int segType,
1548 * char **font_attr, int linkspec,
1549 * FormatVariables *cur_vars, int flags)
1552 * whichOne Specifies the index into 'font_attr' to
1554 * segType Specifies the type of segment currently
1556 * font_attr Specifies the list of font quarks associated
1557 * with the current segment.
1558 * linkspec Specifies the hypertext link specification
1559 * associated with the segment.
1560 * flags Specifies the routines flags.
1562 * Returns: The value returned from 'routine' if successful, -1 if errors.
1566 * Purpose: Saves any segment with the current font type and
1567 * process the next segment using the new font type.
1569 *****************************************************************************/
1573 unsigned long seg_flags,
1574 _DtCvFrmtOption frmt_type,
1575 _DtHelpFontHints *font_attr,
1577 FormatVariables *cur_vars,
1578 ProcessState cur_state,
1584 int oldMb_Len = cur_vars->cur_mb_max;
1586 _DtHelpFontHints oldFontStruct;
1588 if (CheckSaveSegment (seg_flags, font_attr, linkspec, cur_vars) == -1)
1591 oldFontStruct = *font_attr;
1593 if (GetStringParameter(cur_vars, _DtCvTRUE, _DtCvTRUE, _DtCvFALSE,
1594 _DtCvFALSE, &fontString) == -1)
1598 * Is this font change allowed to go through?
1600 if (!(fnt_flag & (1 << whichOne)))
1604 case _CEFONT_SPACING:
1605 font_attr->spacing = _DtHelpFontSpacingProp;
1606 if (fontString[0] == 'm')
1607 font_attr->spacing = _DtHelpFontSpacingMono;
1610 font_attr->pointsz = atoi(fontString);
1613 font_attr->slant = _DtHelpFontSlantRoman;
1614 if (fontString[0] == 'i')
1615 font_attr->slant = _DtHelpFontSlantItalic;
1617 case _CEFONT_WEIGHT:
1618 font_attr->weight = _DtHelpFontWeightMedium;
1619 if (fontString[0] == 'b')
1620 font_attr->weight = _DtHelpFontWeightBold;
1623 font_attr->style = _DtHelpFontStyleSanSerif;
1624 if (*fontString == 's')
1626 if (fontString[1] == 'e')
1627 font_attr->style = _DtHelpFontStyleSerif;
1628 else if (fontString[1] == 'y')
1629 font_attr->style = _DtHelpFontStyleSymbol;
1632 case _CEFONT_CHAR_SET:
1634 * Change to the correct mb_len.
1636 GetMbLen(cur_vars, fontString,
1637 &(_DtHelpFontHintsLang(*font_attr)),
1638 &(_DtHelpFontHintsCharSet(*font_attr)));
1643 result = FindEndMarker (cur_vars);
1645 result = Parse (CCDF_FONT_CMD, cur_state, cur_vars,
1646 seg_flags, frmt_type,
1647 font_attr, linkspec,
1648 Specials, flags, ret_on_nl, fnt_flag);
1650 * free the lanugage and code sets strings.
1652 if (!(fnt_flag & (1 << whichOne)) && whichOne == _CEFONT_CHAR_SET)
1654 free(_DtHelpFontHintsLang(*font_attr));
1655 free(_DtHelpFontHintsCharSet(*font_attr));
1659 * reset the old quark
1660 * if necessary, reset the MB_LEN
1662 *font_attr = oldFontStruct;
1663 cur_vars->cur_mb_max = oldMb_Len;
1677 /******************************************************************************
1678 * Function: int SkipToNextToken (FormatVariables *cur_vars, int flag)
1681 * flag Specifies whether the routine returns a -1
1682 * if '>' is the next token.
1684 * Returns: The value from __DtHelpSkipToNextToken:
1685 * -1 If problems encountered finding the next token.
1686 * 0 If no problems encountered finding the next token.
1687 * 1 If flag is true and the next token is a > character.
1691 * Purpose: Wrapper around __DtHelpSkipToNextToken.
1692 * Skip the current string and any spaces or newline
1693 * characters after it.
1695 *****************************************************************************/
1698 FormatVariables *cur_vars,
1701 return (_DtHelpCeSkipToNextCcdfToken (cur_vars->my_file, cur_vars->rd_buf,
1702 cur_vars->rd_size, 1, &(cur_vars->rd_ptr), flag));
1705 /******************************************************************************
1706 * Function: int GetStringParameter (FormatVariables *cur_vars,
1707 * int flag, int eat_escape,
1708 * int ignore_quotes, int less_test,
1709 * char **ret_string)
1712 * flag Specifies whether the routine returns
1713 * a -1 if '>' is the next token.
1714 * eat_secape Specifies whether the backslash is not
1715 * placed in the returned string.
1716 * True - it is skipped.
1717 * False - it is saved in 'ret_string'.
1718 * ignore_quotes Specifies whether quotes are to be included
1719 * in the returned string.
1720 * less_test Specifies whether the routine should
1721 * stop when it finds a '<' character.
1722 * ret_string Returns the string found.
1723 * If NULL, throws the information away.
1725 * Returns: The value from __DtHelpFormatGetStringParameter:
1726 * -1 If problems encountered.
1727 * 0 If no problems encountered getting the string.
1728 * 1 If flag is false and the no string was found.
1732 * Purpose: Wrapper around __DtHelpFormatGetStringParameter.
1733 * Skip the current string and any spaces or newline
1734 * characters after it. Get the next quoted/unquoted
1735 * string after that.
1737 *****************************************************************************/
1740 FormatVariables *cur_vars,
1742 _DtCvValue eat_escape,
1743 _DtCvValue ignore_quotes,
1744 _DtCvValue less_test,
1747 return (_DtHelpCeGetCcdfStrParam (cur_vars->my_file,
1748 cur_vars->rd_buf, cur_vars->rd_size, cur_vars->cur_mb_max,
1749 &(cur_vars->rd_ptr),
1750 flag, eat_escape, ignore_quotes, less_test, ret_string));
1753 /******************************************************************************
1754 * Function: int GetValueParameter (FormatVariables *cur_vars,
1755 * int flag, int *ret_value)
1758 * flag Specifies whether the routine returns
1759 * a -2 if '>' is the next token.
1760 * ret_value Returns the atoi conversion
1761 * of the string found.
1763 * Returns: The value from __DtHelpFormatGetValueParameter:
1764 * -1 If problems encountered.
1765 * 0 If no problems encountered getting the string.
1766 * -2 If flag is true and the next token is a >
1771 * Purpose: Wrapper around __DtHelpFormatGetValueParameter.
1772 * Skip the current string and any spaces or newline
1773 * characters after it. Process the next string as
1776 *****************************************************************************/
1779 FormatVariables *cur_vars,
1783 return (_DtHelpCeGetCcdfValueParam (cur_vars->my_file, cur_vars->rd_buf,
1785 &(cur_vars->rd_ptr), flag, cur_vars->cur_mb_max,
1789 /******************************************************************************
1790 * Function: int GetParagraphParameters (FormatVariables *cur_vars,
1791 * int seg_type, int graphic_type,
1792 * char **label, char **file_name,
1793 * char **link_string, int *link_type,
1794 * char **description)
1797 * seg_type Specifies the default type for the segment.
1798 * Returns the new type for the segment.
1799 * graphic_type Specifies the default type for a graphic
1800 * if a justified graphic is
1801 * encountered in the paragraph options.
1802 * Returns the new type for a graphic
1803 * if a justified graphic was
1804 * encountered in the paragraph options.
1805 * label Returns the label if one is specified
1806 * in the paragraph options.
1807 * file_name Returns the file name of a graphic if
1808 * one is specified in the paragraph
1810 * link_string Returns the hypertext specification if one
1811 * is specified in the paragraph options.
1812 * link_type Returns the hypertext link type if one is
1814 * description Returns the hypertext description if one
1817 * Returns: 0 if successfult, -1 if errors.
1821 * Purpose: Wrapper around __DtHelpParagraphGetOptions.
1822 * Process the options found in <PARAGRAPH> syntax.
1823 * Test to see if the id specified in the <PARAGRAPH>
1824 * is the one we are looking at.
1826 *****************************************************************************/
1828 GetParagraphParameters(
1829 FormatVariables *cur_vars,
1831 _DtCvFrmtOption *frmt_type,
1832 _DtCvFrmtOption *gpos,
1842 int optionCount = 0;
1844 char *tmpString = NULL;
1847 * initialize string variables if valid addresses
1852 *description = NULL;
1854 *gpos = _DtCvJUSTIFY_LEFT;
1858 while (False == done && result != -1)
1860 if (SkipToNextToken (cur_vars, _DtCvFALSE) == -1)
1863 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
1866 * end of paragraph spec
1869 (cur_vars->rd_ptr)++;
1877 if (GetValueParameter (cur_vars, _DtCvFALSE, &value) == -1)
1880 _DtCvContainerBMarginOfSeg(para) = 0;
1881 if (value > 0 && 0 < cur_vars->ui_info->line_height)
1882 _DtCvContainerBMarginOfSeg(para) = value *
1883 (cur_vars->ui_info->line_height / 2);
1890 if (GetValueParameter (cur_vars, _DtCvFALSE, &value) == -1)
1893 _DtCvContainerTMarginOfSeg(para) = 0;
1894 if (value > 0 && 0 < cur_vars->ui_info->line_height)
1895 _DtCvContainerTMarginOfSeg(para) = value *
1896 (cur_vars->ui_info->line_height / 2);
1900 * description [string | "string" | 'string']
1903 result = GetStringParameter(cur_vars, _DtCvTRUE, _DtCvTRUE,
1904 _DtCvFALSE, _DtCvFALSE, description);
1911 if (GetValueParameter (cur_vars, _DtCvFALSE, &value) == -1)
1914 _DtCvContainerFMarginOfSeg(para) =
1915 value * cur_vars->ui_info->avg_char;
1919 * glink [string | "string" | 'string']
1927 * to determine what token this is we must look at the
1930 (cur_vars->rd_ptr)++;
1933 * do we need to read more?
1935 if (*(cur_vars->rd_ptr) == '\0'
1936 && GetNextBuffer(cur_vars) == -1)
1940 * check for the next permutation
1942 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
1945 * glink [string | "string" | 'string']
1948 result = GetStringParameter(cur_vars, _DtCvTRUE,
1949 _DtCvTRUE, _DtCvFALSE, _DtCvFALSE, glink);
1956 result = GetStringParameter(cur_vars, _DtCvTRUE,
1957 _DtCvTRUE, _DtCvFALSE, _DtCvFALSE, &tmpString);
1959 if (-1 != result && _DtCvToLower (*tmpString) == 'r')
1960 *gpos = _DtCvJUSTIFY_RIGHT;
1970 result = GetStringParameter(cur_vars, _DtCvTRUE,
1971 _DtCvTRUE, _DtCvFALSE, _DtCvFALSE, file_name);
1978 if (GetValueParameter(cur_vars,_DtCvFALSE,&value) == -1
1982 *gspace = value * cur_vars->ui_info->avg_char;
1989 if (GetValueParameter(cur_vars,_DtCvFALSE,glinktype) == -1
2004 if (GetStringParameter(cur_vars, _DtCvTRUE, _DtCvTRUE,
2005 _DtCvFALSE, _DtCvFALSE, &tmpString) == -1)
2008 _DtCvContainerIdOfSeg(para) = tmpString;
2012 * label [string | "string" | 'string']
2017 * to determine what token this is we must look at the
2018 * second and possibly the third characters.
2020 (cur_vars->rd_ptr)++;
2023 * do we need to read more?
2025 if (*(cur_vars->rd_ptr) == '\0'
2026 && GetNextBuffer(cur_vars) == -1)
2030 * check for the next permutation
2032 if (_DtCvToLower(*(cur_vars->rd_ptr)) == 'a')
2037 if (GetStringParameter(cur_vars, _DtCvTRUE, _DtCvFALSE,
2038 _DtCvFALSE, _DtCvFALSE, &tmpString) == -1)
2042 * If we got a label process it.
2044 if (ret_label == NULL || *ret_label)
2047 * we've already processed a label!
2054 *ret_label = tmpString;
2056 else if (_DtCvToLower(*(cur_vars->rd_ptr)) == 'e')
2061 if (GetValueParameter (cur_vars, _DtCvFALSE, &value) == -1)
2064 _DtCvContainerLMarginOfSeg(para) =
2065 value * cur_vars->ui_info->avg_char;
2075 _DtCvContainerTypeOfSeg(para) = _DtCvLITERAL;
2076 *frmt_type = _DtCvLITERAL;
2083 if (GetValueParameter (cur_vars, _DtCvFALSE, &value) == -1)
2086 _DtCvContainerRMarginOfSeg(para) =
2087 value * cur_vars->ui_info->avg_char;
2094 _DtCvContainerTypeOfSeg(para) = _DtCvDYNAMIC;
2095 *frmt_type = _DtCvDYNAMIC;
2099 * Found an option we don't understand.
2108 * adjust the first margin to correctly indicate the offset from the
2109 * left margin. In the old CCDF, the first margin indicated left plus
2110 * and additional indent. For the new Canvas Engine, it is suppose
2111 * to be an addition on top of the left margin.
2113 _DtCvContainerFMarginOfSeg(para) = _DtCvContainerLMarginOfSeg(para) -
2114 _DtCvContainerFMarginOfSeg(para);
2118 return (optionCount - 1);
2120 } /* End GetParagraphParameters */
2122 /******************************************************************************
2123 * Function: int FlowingParagraph (
2131 * Purpose: Process the <PARAGRAPH> specification.
2133 *****************************************************************************/
2136 FormatVariables *cur_vars,
2137 ProcessState cur_state,
2138 _DtCvFrmtOption frmt_flags,
2143 _DtCvFrmtOption gpos,
2146 _DtHelpFontHints *font_attr)
2150 _DtCvSegment *graphSeg;
2151 _DtCvSegment *bodySeg;
2152 SegList flowList = InitList;
2155 * reset current list
2157 cur_vars->my_list = InitList;
2160 * create two containers.
2162 if (0 == CheckList(&(flowList), 2, 2))
2165 * point to the containers for the graphic and body.
2167 graphSeg = flowList.list;
2168 bodySeg = flowList.list;
2172 * set the bottom margins to zero.
2174 graphSeg->type = _DtCvSetTypeToContainer(graphSeg->type);
2175 bodySeg->type = _DtCvSetTypeToContainer(bodySeg->type);
2176 _DtCvContainerBMarginOfSeg(graphSeg) = 0;
2177 _DtCvContainerBMarginOfSeg(bodySeg) = 0;
2180 * so the first segment is the container for the graphic.
2181 * set the controller flag and values.
2183 graphSeg->type = _DtCvSetTypeToController(graphSeg->type);
2184 _DtCvContainerFlowOfSeg(graphSeg) = _DtCvWRAP;
2185 _DtCvContainerPercentOfSeg(graphSeg) = 0;
2186 _DtCvContainerOrientOfSeg(graphSeg) = gpos;
2187 if (_DtCvJUSTIFY_LEFT == gpos)
2189 _DtCvContainerJustifyOfSeg(graphSeg) = gpos;
2190 _DtCvContainerRMarginOfSeg(graphSeg) = gspace;
2194 _DtCvContainerJustifyOfSeg(graphSeg) = gpos;
2195 _DtCvContainerLMarginOfSeg(graphSeg) = gspace;
2199 * mark the first segment as used.
2204 * check for hypertext link.
2207 type = _DtCvHYPER_TEXT;
2210 * re-set the segment list and create the graphic.
2212 if (0 == CreateSaveGraphic(cur_vars, type, file_name, link_idx))
2215 * so the first segment in cur_vars is a region.
2216 * attach it to the graphic container.
2218 _DtCvContainerListOfSeg(graphSeg) = cur_vars->my_list.list;
2221 * now process the following information as the body of
2222 * the paragraph as the list for the non-controller
2225 cur_vars->my_list = InitList;
2226 if (-1 != Parse (CCDF_PARAGRAPH_CMD, cur_state, cur_vars,
2230 ret_on_nl, fnt_flag))
2233 * establish the links between the segments
2235 TerminateSegList(&(cur_vars->my_list), True);
2238 * if there was a segment list generated,
2239 * attach the it to the non-controller
2240 * container and mark it as used.
2242 if (NULL != cur_vars->my_list.list)
2244 _DtCvContainerListOfSeg(bodySeg) = cur_vars->my_list.list;
2252 cur_vars->my_list = flowList;
2253 TerminateSegList(&(cur_vars->my_list), True);
2257 /******************************************************************************
2258 * Function: int ProcessParagraph (
2266 * Purpose: Process the <PARAGRAPH> specification.
2268 *****************************************************************************/
2271 FormatVariables *cur_vars,
2272 ProcessState cur_state,
2276 int labelFnd = False;
2277 int allowed = ~(CCDF_TOPIC_CMD | CCDF_TITLE_CMD | CCDF_ABBREV_CMD);
2278 int oldMbLenMax = cur_vars->cur_mb_max;
2281 _DtCvUnit gspace = 0;
2282 char *glinkSpec = NULL;
2284 char *fileName = NULL;
2285 char *description = NULL;
2288 ProcessState myState = NormalState;
2289 _DtCvFrmtOption gpos;
2290 _DtCvFrmtOption frmtType = _DtCvDYNAMIC;
2291 _DtCvSegment *paraSeg;
2292 _DtCvSegment *labelSeg = NULL;
2293 _DtCvSegment *col1 = NULL;
2294 _DtCvSegment *col2 = NULL;
2295 _DtCvSegment **childList;
2297 SegList tableList = InitList;
2298 _DtHelpFontHints fontAttrs;
2301 * remember the old font list.
2302 * initialize the font quark list
2303 * and use the char set specified for this topic.
2305 _DtHelpCeCopyDefFontAttrList (&fontAttrs);
2306 cur_vars->cur_mb_max = cur_vars->topic_mb_max;
2307 _DtHelpFontHintsLang(fontAttrs) = cur_vars->topic_lang;
2308 _DtHelpFontHintsCharSet(fontAttrs) = cur_vars->topic_char_set;
2311 * Make next segment in my parent's list for a container for this
2314 if (-1 == CheckSegList(cur_vars))
2318 * remember the parent list
2319 * make sure the defaults are set
2321 oldList = cur_vars->my_list;
2322 paraSeg = NextAvailSeg(cur_vars->my_list);
2323 paraSeg->handle.container = DefContainer;
2324 paraSeg->type = _DtCvSetTypeToContainer(paraSeg->type);
2325 _DtCvContainerLeadingOfSeg(paraSeg) = cur_vars->ui_info->leading;
2326 cur_vars->my_list = InitList;
2329 * get the parameters on the paragraph
2330 * and set the default for the bottom.
2332 result = GetParagraphParameters (cur_vars, paraSeg, &frmtType,
2333 &gpos, &glinkSpec, &glinktype, &gspace,
2334 &label, &fileName, &description);
2337 * for lists, we will inherit our parent's bottom margin
2338 * when we return to the loop processing the list. Therefore,
2339 * set our bottom margin to zero if we are part of a label body.
2341 if (0 == result && LabelBody == cur_state)
2342 _DtCvContainerBMarginOfSeg(paraSeg) = 0;
2343 else if (result > 0)
2347 * check for a label specification. Either as a 'label' parameter
2348 * or a the <LABEL> command.
2353 * check for the parameter
2357 FormatVariables oldVars = *cur_vars;
2359 cur_vars->rd_buf = label;
2360 cur_vars->rd_flag = 0;
2361 cur_vars->rd_ptr = label;
2362 cur_vars->my_file = NULL;
2364 result = Parse (CCDF_LABEL_CMD, NormalState, cur_vars,
2368 (CCDF_FONT_CMD | CCDF_OCTAL_CMD),
2372 result = CheckSaveSegment (_DtCvSTRING, &fontAttrs,
2375 TerminateSegList(&(cur_vars->my_list), True);
2376 cur_vars->rd_buf = oldVars.rd_buf;
2377 cur_vars->rd_flag = oldVars.rd_flag;
2378 cur_vars->rd_ptr = oldVars.rd_ptr;
2379 cur_vars->my_file = oldVars.my_file;
2380 cur_vars->last_was_space = True;
2382 labelSeg = cur_vars->my_list.list;
2383 cur_vars->my_list = InitList;
2387 * check for the command.
2389 else if (0 == _DtHelpCeCheckNextCcdfCmd("lab", cur_vars->my_file,
2391 cur_vars->rd_size, 1,
2392 &(cur_vars->rd_ptr)))
2394 result = ProcessLabelCmd(cur_vars, 0, frmtType,
2396 allowed, False, fnt_flag,
2402 * if a label was processed, create the containers for it.
2404 if (-1 != result && True == labelFnd)
2407 * set the correct state.
2409 myState = LabelBody;
2412 * create containers for the label and it's body
2414 result = CheckList(&tableList, 2, 2);
2418 * set the top and bottom margins on both the child
2419 * containers (so they are the same) to reflect
2420 * the list's before/after values.
2423 * set the pointer to the first column
2424 * overwrite the left and right margin values.
2426 col1 = NextAvailSeg(tableList);
2427 col1->type = _DtCvSetTypeToContainer(col1->type);
2428 _DtCvContainerTMarginOfSeg(col1) =
2429 _DtCvContainerTMarginOfSeg(paraSeg);
2430 _DtCvContainerBMarginOfSeg(col1) =
2431 _DtCvContainerBMarginOfSeg(paraSeg);
2432 _DtCvContainerLMarginOfSeg(col1) = 0;
2433 _DtCvContainerRMarginOfSeg(col1) = cur_vars->ui_info->avg_char;
2437 * set the pointer for the second column
2438 * and set the top/bottom values.
2440 col2 = NextAvailSeg(tableList);
2441 col2->type = _DtCvSetTypeToContainer(col2->type);
2442 _DtCvContainerTMarginOfSeg(col2) =
2443 _DtCvContainerTMarginOfSeg(paraSeg);
2444 _DtCvContainerBMarginOfSeg(col2) =
2445 _DtCvContainerBMarginOfSeg(paraSeg);
2449 * create an id for this label
2451 sprintf(numChar, "%d", cur_vars->cell_cnt++);
2452 _DtCvContainerIdOfSeg(col1) = (char *) malloc (
2453 strlen("&CCDF_RES_") + strlen(numChar) + 1);
2454 if (NULL != _DtCvContainerIdOfSeg(col1))
2457 * copy over the id and attach the list.
2459 strcpy(_DtCvContainerIdOfSeg(col1), "&CCDF_RES_");
2460 strcat(_DtCvContainerIdOfSeg(col1), numChar);
2461 _DtCvContainerListOfSeg(col1) = labelSeg;
2464 * set the id for the second column.
2466 sprintf(numChar, "%d", cur_vars->cell_cnt++);
2467 _DtCvContainerIdOfSeg(col2) = (char *) malloc (
2468 strlen("&CCDF_RES_") + strlen(numChar) + 1);
2469 if (NULL != _DtCvContainerIdOfSeg(col2))
2471 strcpy(_DtCvContainerIdOfSeg(col2), "&CCDF_RES_");
2472 strcat(_DtCvContainerIdOfSeg(col2), numChar);
2484 * disallow labels from here on out. Either one was found and processed
2487 allowed &= (~(CCDF_LABEL_CMD));
2490 * Now check and process the graphic specification.
2495 * initialize the segment list for the children of the paragraph.
2497 cur_vars->my_list = InitList;
2500 * check for a graphic in the specification.
2501 * If so, then we need to create, as the list for the
2502 * paragraph container, two containers; one container
2503 * that is a controller and has the graphic and the
2504 * other contains the rest of the content of the
2507 * First, create the link index for the graphic.
2509 if (NULL != glinkSpec)
2512 * but if there isn't a graphic, throw away the link
2513 * specifications since they are useless!
2515 if (NULL != fileName && strlen (glinkSpec))
2517 linkIndex = _DtLinkDbAddLink (cur_vars->my_links,
2520 ReturnLinkType(glinktype, glinkSpec),
2521 ReturnLinkWinHint(glinktype),
2525 * had problems creating the link index, bail
2527 if (linkIndex == -1)
2533 * now create the graphic and process the graphic body..
2534 * or just process the rest of the paragraph....
2538 if (NULL != fileName)
2539 result = FlowingParagraph(cur_vars,
2544 gpos, gspace, fileName,
2548 result = Parse (CCDF_PARAGRAPH_CMD, myState, cur_vars,
2556 * establish the links
2558 TerminateSegList (&(cur_vars->my_list), True);
2566 _DtCvFrmtOption *colJ;
2568 if (True == labelFnd)
2570 char *colW1 = "1"; /* default bulletted list */
2571 char *colW2 = "99,0,98"; /* default bulletted list */
2575 * set the body of the label in it's container.
2577 _DtCvContainerListOfSeg(col2) = cur_vars->my_list.list;
2580 * figure out which column widths should be used.
2582 if (14 * cur_vars->ui_info->avg_char
2583 == _DtCvContainerLMarginOfSeg(paraSeg))
2589 else if (3 * cur_vars->ui_info->avg_char
2590 == _DtCvContainerLMarginOfSeg(paraSeg))
2593 else if (0 == _DtCvContainerLMarginOfSeg(paraSeg))
2598 * create the column width strings.
2601 colW = (char **) _DtCvAddPtrToArray((void **) colW,
2602 ((void *) strdup(colW1)));
2604 colW = (char **) _DtCvAddPtrToArray((void **) colW,
2605 ((void *) strdup (colW2)));
2608 * create the array for column justification.
2610 colJ = (_DtCvFrmtOption *) malloc (sizeof(_DtCvFrmtOption) * 2);
2613 colJ[0] = _DtCvJUSTIFY_LEFT;
2614 colJ[1] = _DtCvJUSTIFY_LEFT;
2618 * set this segment's type to a table and fill in all
2619 * the relevant information.
2621 paraSeg->type = _DtCvTABLE;
2622 _DtCvNumColsOfTableSeg(paraSeg) = 2;
2623 _DtCvColWOfTableSeg(paraSeg) = colW;
2624 _DtCvColJustifyOfTableSeg(paraSeg) = colJ;
2625 _DtCvJustifyCharsOfTableSeg(paraSeg) = NULL;
2628 * now create the list of ids in this table.
2630 ids = (char *) malloc (
2631 strlen(_DtCvContainerIdOfSeg(col1)) +
2632 strlen(_DtCvContainerIdOfSeg(col2)) + 2);
2635 strcpy(ids, _DtCvContainerIdOfSeg(col1));
2637 strcat(ids, _DtCvContainerIdOfSeg(col2));
2639 _DtCvCellIdsOfTableSeg(paraSeg) = NULL;
2640 _DtCvCellIdsOfTableSeg(paraSeg) = (char **)
2642 (void **) _DtCvCellIdsOfTableSeg(paraSeg),
2646 * now create the list of cells in the table.
2648 _DtCvCellsOfTableSeg(paraSeg) = NULL;
2649 _DtCvCellsOfTableSeg(paraSeg) = (_DtCvSegment **)
2651 (void **) _DtCvCellsOfTableSeg(paraSeg),
2653 if (NULL != _DtCvCellsOfTableSeg(paraSeg))
2654 _DtCvCellsOfTableSeg(paraSeg) = (_DtCvSegment **)
2656 (void **) _DtCvCellsOfTableSeg(paraSeg),
2659 if (NULL == colW || NULL == colJ || NULL == ids
2660 || NULL == _DtCvCellIdsOfTableSeg(paraSeg)
2661 || NULL == _DtCvCellsOfTableSeg(paraSeg))
2669 * attach the list to my container.
2671 _DtCvContainerListOfSeg(paraSeg) = cur_vars->my_list.list;
2674 * consolidate any table children I have.
2676 for (pSeg = cur_vars->my_list.list, labelSeg = NULL;
2677 -1 != result && NULL != pSeg;
2678 pSeg = pSeg->next_seg)
2680 if (_DtCvIsSegTable(pSeg))
2682 if (NULL != labelSeg)
2685 * bypass this segment since it will no
2686 * longer be 'used' by consolidating it
2687 * with another label set.
2689 labelSeg->next_seg = pSeg->next_seg;
2692 * free the other justification and width info.
2694 free((void *) _DtCvColJustifyOfTableSeg(pSeg));
2695 colW = _DtCvColWOfTableSeg(pSeg);
2698 free(_DtCvColWOfTableSeg(pSeg));
2701 * add the segments to the list
2703 childList = _DtCvCellsOfTableSeg(pSeg);
2704 _DtCvCellsOfTableSeg(labelSeg) = (_DtCvSegment **)
2706 (void **) _DtCvCellsOfTableSeg(labelSeg),
2709 if (NULL != _DtCvCellsOfTableSeg(labelSeg))
2710 _DtCvCellsOfTableSeg(labelSeg) = (_DtCvSegment **)
2712 (void **)_DtCvCellsOfTableSeg(labelSeg),
2714 free((void *) _DtCvCellsOfTableSeg(pSeg));
2717 * add the ids to the list
2719 _DtCvCellIdsOfTableSeg(labelSeg) = (char **)
2721 (void **)_DtCvCellIdsOfTableSeg(labelSeg),
2722 (void *)(*(_DtCvCellIdsOfTableSeg(pSeg))));
2724 free((void *) _DtCvCellIdsOfTableSeg(pSeg));
2726 if (NULL == _DtCvCellIdsOfTableSeg(labelSeg)
2727 || NULL == _DtCvCellsOfTableSeg(labelSeg))
2733 * this segment becomes the segment holding
2734 * the consolidated table.
2747 * restore the font MB_CUR_MAX
2749 cur_vars->cur_mb_max = oldMbLenMax;
2752 * free all the strings
2756 if (fileName != NULL)
2760 * free the linkSpec and description,
2762 if (NULL != description)
2764 if (NULL != glinkSpec)
2771 cur_vars->my_list = oldList;
2772 cur_vars->last_was_space = True;
2775 } /* End ProcessParagraph */
2777 /******************************************************************************
2778 * Function: int ProcessHypertext (
2779 * FormatVariables *cur_vars, int segType,
2780 * char **font_attr, int flags )
2783 * segType Specifies the type of segment currently
2785 * font_attr Specifies the list of font quarks to
2786 * associate with the string.
2787 * flags Specifies the formatting commands allowed.
2789 * Returns: 0 if successful, -1 if errors.
2793 * Purpose: Process the <LINK> specification.
2795 *****************************************************************************/
2798 FormatVariables *cur_vars,
2799 ProcessState cur_state,
2800 unsigned long seg_flags,
2801 _DtCvFrmtOption frmt_type,
2802 _DtHelpFontHints *font_attr,
2810 char *description = NULL;
2811 char *hyperlink = NULL;
2814 * is a <LINK> command allowed here?
2816 if (CCDF_NOT_ALLOW_CMD(flags, CCDF_LINK_CMD))
2820 * get the hypertext type
2822 if (GetValueParameter (cur_vars, _DtCvTRUE, &hyperType) < 0)
2827 errno = CEErrorHyperType;
2832 * get the hypertext link spec.
2834 result = GetStringParameter(cur_vars, _DtCvTRUE, _DtCvTRUE, _DtCvFALSE,
2835 _DtCvFALSE, &hyperlink);
2839 * See if we have the optional description string
2841 result = GetStringParameter (cur_vars, _DtCvFALSE, _DtCvTRUE,
2842 _DtCvFALSE, _DtCvFALSE, &description);
2846 result = _DtLinkDbAddLink (cur_vars->my_links,
2849 ReturnLinkType(hyperType, hyperlink),
2850 ReturnLinkWinHint(hyperType),
2852 if (NULL != description)
2859 * if no problems encountered, start parsing with this
2864 hyperIndex = result;
2865 result = FindEndMarker (cur_vars);
2869 * set the hypertext flag and type.
2871 seg_flags = _DtCvSetTypeToHyperText(seg_flags);
2873 result = Parse (CCDF_LINK_CMD, cur_state, cur_vars,
2874 seg_flags, frmt_type,
2878 ret_on_nl, fnt_flag);
2883 * Don't free the hypertext string or description.
2884 * It is now owned by the Link List.
2892 } /* End ProcessHypertext */
2894 /******************************************************************************
2895 * Function: int ProcessLabelCmd (
2896 * FormatVariables *cur_vars, int seg_type,
2897 * char **font_attr, int link_spec,
2901 * font_attr Specifies the list of font quarks to
2902 * associate with the string.
2903 * link_spec Specifies the hypertext link to associate
2905 * flags Specifies the formatting commands allowed.
2907 * Returns: 0 if successful, -1 if errors.
2911 * Purpose: Process the <LABEL> specification.
2913 *****************************************************************************/
2916 FormatVariables *cur_vars,
2917 unsigned long seg_flags,
2918 _DtCvFrmtOption frmt_type,
2919 _DtHelpFontHints *font_attr,
2924 _DtCvSegment **ret_list)
2926 SegList oldList = cur_vars->my_list;
2929 * is a <LABEL> command allowed?
2931 if (CCDF_NOT_ALLOW_CMD(flags, CCDF_LABEL_CMD))
2935 * can't have another <LABEL> command inside this one
2937 flags &= (~(CCDF_LABEL_CMD));
2940 * Find the end marker
2942 if (FindEndMarker (cur_vars) != 0)
2945 cur_vars->my_list = InitList;
2946 if (Parse (CCDF_LABEL_CMD, NormalState, cur_vars,
2952 ret_on_nl, fnt_flag) == -1)
2956 * set the links, return the segment list and restore the old list.
2958 TerminateSegList(&(cur_vars->my_list), True);
2959 *ret_list = cur_vars->my_list.list;
2960 cur_vars->my_list = oldList;
2963 * Indicate that preceding space on the next text should be ignored
2965 cur_vars->last_was_space = True;
2969 } /* End ProcessLabelCmd */
2971 /******************************************************************************
2972 * Function: int ProcessFigureCmd (
2973 * FormatVariables *cur_vars,
2977 * font_attr Specifies the list of font quarks to
2978 * associate with the string.
2980 * Returns: 0 if successful, -1 if errors.
2984 * Purpose: Process the <FIGURE> specification.
2986 *****************************************************************************/
2989 FormatVariables *cur_vars,
2990 ProcessState cur_state,
2991 _DtCvFrmtOption frmt_type,
2992 _DtHelpFontHints *font_attr,
2999 int linkType = CCDF_LINK_JUMP_REUSE;
3001 int segType = _DtCvREGION;
3002 char *description = NULL;
3003 char *idString = NULL;
3004 char *filename = NULL;
3005 char *linkspec = NULL;
3006 _DtCvFrmtOption vertOrientCap = _DtCvJUSTIFY_BOTTOM;
3007 _DtCvFrmtOption horzOrientCap = _DtCvJUSTIFY_CENTER;
3008 _DtCvFrmtOption justifyCap = _DtCvJUSTIFY_CENTER;
3009 _DtCvFrmtOption justifyGraphic = _DtCvJUSTIFY_CENTER;
3010 _DtCvSegment *figContainer;
3013 SegList figList = InitList;
3016 * create a container for this figure (and possibly a caption)
3018 if (-1 == CheckSegList(cur_vars))
3021 figContainer = NextAvailSeg(cur_vars->my_list);
3022 figContainer->handle.container = DefContainer;
3023 figContainer->type = _DtCvSetTypeToContainer(figContainer->type);
3024 _DtCvContainerLeadingOfSeg(figContainer) = cur_vars->ui_info->leading;
3027 * remember the old list and initialize for the figure.
3029 oldList = cur_vars->my_list;
3030 cur_vars->my_list = InitList;
3033 * process the parameters of the figure cmd.
3035 while (!done && result != -1)
3037 if (SkipToNextToken (cur_vars, _DtCvFALSE) == -1)
3043 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
3046 * end of figure spec
3050 * move past the end of token marker
3051 * and skip the leading blanks in the caption.
3053 (cur_vars->rd_ptr)++;
3054 while (result != -1 && !done)
3056 if (*(cur_vars->rd_ptr) == '\0')
3057 result = GetNextBuffer (cur_vars);
3058 else if ((cur_vars->cur_mb_max == 1 ||
3059 mblen(cur_vars->rd_ptr, cur_vars->cur_mb_max) == 1)
3060 && *(cur_vars->rd_ptr) == ' ')
3061 (cur_vars->rd_ptr)++;
3077 * Go to the next character.
3079 (cur_vars->rd_ptr)++;
3082 * Do we need to read more information?
3084 if (*(cur_vars->rd_ptr) == '\0' && GetNextBuffer (cur_vars) == -1)
3090 * look at the next charager to determine the token.
3092 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
3094 case 'c': /* caption center */
3095 justifyCap = _DtCvJUSTIFY_CENTER;
3096 horzOrientCap = _DtCvJUSTIFY_CENTER;
3099 case 'e': /* graphic centered */
3100 justifyGraphic = _DtCvJUSTIFY_CENTER;
3103 case 'b': /* caption below graphic */
3104 vertOrientCap = _DtCvJUSTIFY_BOTTOM;
3107 case 'l': /* caption justified left */
3108 justifyCap = _DtCvJUSTIFY_LEFT;
3109 horzOrientCap = _DtCvJUSTIFY_LEFT_MARGIN;
3112 case 'r': /* caption right justified */
3113 justifyCap = _DtCvJUSTIFY_RIGHT;
3114 horzOrientCap = _DtCvJUSTIFY_RIGHT_MARGIN;
3117 case 't': /* caption at top */
3118 vertOrientCap = _DtCvJUSTIFY_TOP;
3125 * description [string | "string" | 'string']
3128 result = GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3129 _DtCvFALSE, _DtCvFALSE, &description);
3136 result = GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3137 _DtCvFALSE, _DtCvFALSE, &filename);
3147 result = GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3148 _DtCvFALSE, _DtCvFALSE, &idString);
3150 * if this figure had an id associated with it, create
3151 * marker segment for it.
3153 if (-1 != result && NULL != idString && '\0' != *idString)
3156 * create the marker. If there is an error, free the
3159 result = CreateMarker(cur_vars, idString);
3167 * link [string | "string" | 'string']
3171 * Go to the next character.
3173 (cur_vars->rd_ptr)++;
3176 * Do we need to read more information?
3178 if (*(cur_vars->rd_ptr) == '\0' && GetNextBuffer (cur_vars) == -1)
3184 * look at the next charager to determine the token.
3186 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
3189 justifyGraphic = _DtCvJUSTIFY_LEFT;
3193 segType = _DtCvSetTypeToHyperText (segType);
3194 result = GetStringParameter (cur_vars, _DtCvTRUE,
3195 _DtCvTRUE, _DtCvFALSE, _DtCvFALSE,
3209 justifyGraphic = _DtCvJUSTIFY_RIGHT;
3216 if (GetValueParameter (cur_vars, _DtCvTRUE, &linkType) == -1)
3218 else if (linkType < 0)
3220 errno = CEErrorHyperType;
3230 if (result != -1 && (filename == NULL || strlen(filename) == 0))
3236 * check to see if the hypertext flag is set but we don't
3237 * have a link specification.
3239 if (IsTypeHyperText(segType) && !linkspec)
3241 segType = segType & ~(_DtCvHYPER_TEXT);
3243 if (NULL != description)
3249 * do we still have a good hypertext?
3250 * if so, create a link index for it.
3252 if (IsTypeHyperText(segType))
3254 linkIndex = _DtLinkDbAddLink (cur_vars->my_links,
3257 ReturnLinkType(linkType, linkspec),
3258 ReturnLinkWinHint(linkType),
3260 if (linkIndex == -1)
3268 * parse the caption. If there is a caption, we will need to
3269 * wrap it and the figure in containers with the appropriate
3270 * controller flags set to get the correct layout.
3272 result = Parse (CCDF_FIGURE_CMD, cur_state, cur_vars,
3276 (CCDF_NEWLINE_CMD | CCDF_LINK_CMD |
3277 CCDF_FONT_CMD | CCDF_ID_CMD),
3278 ret_on_nl, fnt_flag);
3281 * save the caption List.
3283 TerminateSegList(&(cur_vars->my_list), True);
3284 capList = cur_vars->my_list;
3287 * is there a caption? If so, create two segments instead
3291 if (-1 != result && 0 != capList.cnt)
3295 * allocate room for the figure (and caption)
3298 result = CheckList(&figList, cnt, cnt);
3303 * process any caption that was specified
3305 if (0 != capList.cnt)
3307 _DtCvSegment *pSeg = figList.list;
3310 * create a controller for the caption.
3312 pSeg->type = _DtCvSetTypeToController(
3313 _DtCvSetTypeToContainer(pSeg->type));
3316 * set its orientation and justification.
3318 _DtCvContainerOrientOfSeg(pSeg) = horzOrientCap;
3319 _DtCvContainerVOrientOfSeg(pSeg) = vertOrientCap;
3320 _DtCvContainerJustifyOfSeg(pSeg) = justifyCap;
3321 _DtCvContainerBMarginOfSeg(pSeg) = 0;
3324 * attach the caption to the container.
3326 _DtCvContainerListOfSeg(pSeg) = capList.list;
3329 * indicate this segment has been used.
3335 * now load the graphic into the next available segment
3336 * allocated for the figure.
3338 cur_vars->my_list = figList;
3339 result = CreateSaveGraphic (cur_vars, segType, filename, linkIndex);
3342 * if no problems, attach the figure (and caption) to the
3350 TerminateSegList(&(cur_vars->my_list), True);
3353 * attach the figure (and caption) to the wrapper
3355 _DtCvContainerListOfSeg(figContainer) = cur_vars->my_list.list;
3358 * set the justify to the correct value to act on the
3361 _DtCvContainerJustifyOfSeg(figContainer) = justifyGraphic;
3364 * indicate that this segment has been used
3372 * restore the segment list.
3375 cur_vars->my_list = oldList;
3379 * don't free the link string or description,
3380 * the link list owns them now.
3385 } /* End ProcessFigureCmd */
3387 /******************************************************************************
3388 * Function: int ProcessInLine (FormatVariables cur_vars,
3389 * int seg_type, int link_spec )
3392 * seg_type Specifes the type of segment currently
3394 * link_spec Specifies the hypertext link associated
3395 * with this segment.
3397 * Returns: 0 if successful, -1 if errors.
3401 * Purpose: Process a <GRAPHIC> specification.
3403 *****************************************************************************/
3406 FormatVariables *cur_vars,
3412 char *idString = NULL;
3413 char *filename = NULL;
3416 * process the graphic parameters
3418 while (!done && result != -1)
3420 if (SkipToNextToken (cur_vars, _DtCvFALSE) == -1)
3423 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
3426 * end of in line spec
3430 * move past the end of token marker
3432 (cur_vars->rd_ptr)++;
3440 result = GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3441 _DtCvFALSE, _DtCvFALSE, &filename);
3451 result = GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3452 _DtCvFALSE, _DtCvFALSE, &idString);
3454 * if this graphic had an id associated with it, create
3455 * marker segment for it.
3457 if (-1 != result && NULL != idString && '\0' != *idString)
3460 * create the marker. If there is an error, free the
3463 result = CreateMarker(cur_vars, idString);
3475 if (result != -1 && (filename == NULL || strlen(filename) == 0))
3481 * create the graphic.
3483 result = CreateSaveGraphic (cur_vars,
3484 _DtCvSetTypeToInLine(seg_type),
3485 filename, link_spec);
3486 cur_vars->last_was_space = False;
3493 } /* End ProcessInLine */
3495 /******************************************************************************
3496 * Function: int CheckIdString (
3497 * FormatVariables *cur_vars, int segType,
3498 * char **font_attr, int linkspec,
3502 * segType Specifies the type of segment currently
3504 * font_attr Specifies the list of font quarks to
3505 * associate with the string.
3506 * linkspec Specifies the hypertext link associated
3508 * flags Specifies the formatting commands allowed.
3510 * Returns: 0 if successful, -1 if errors.
3514 * Purpose: Create a marker at this location.
3516 *****************************************************************************/
3519 FormatVariables *cur_vars,
3520 ProcessState cur_state,
3521 unsigned long seg_flags,
3522 _DtCvFrmtOption frmt_type,
3523 _DtHelpFontHints *font_attr,
3533 * is it legal to have a <ID> command at this point?
3535 if (CCDF_NOT_ALLOW_CMD (flags, CCDF_ID_CMD))
3540 * clear out any current information in the buffer
3541 * and make sure there is a segment available.
3543 if (-1 != GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3544 _DtCvFALSE, _DtCvFALSE, &ptr)
3546 -1 != CheckSaveSegment (seg_flags, font_attr, linkspec, cur_vars))
3549 * create the marker. If there is an error, free the
3552 result = CreateMarker(cur_vars, ptr);
3557 * find the end of the <ID> syntax
3558 * and parse the data between the begin <ID> and </ID>.
3560 if (0 == result && -1 != FindEndMarker (cur_vars) &&
3561 -1 != Parse (CCDF_ID_CMD, cur_state, cur_vars,
3562 seg_flags, frmt_type,
3566 ret_on_nl, fnt_flag))
3571 * return an error code if necessary
3575 } /* End CheckIdString */
3577 /******************************************************************************
3578 * Function: int Parse (int cur_cmd,
3579 * FormatVariables *cur_vars, int segType,
3581 * int linkspec, int allowed)
3584 * cur_cmd Specifies the current formatting command
3586 * parent Specifies the parent paragraph.
3587 * segType Specifies the type of segment currently
3589 * font_attr Specifies the list of font quarks to
3590 * associate with the string.
3591 * linkspec Specifies the hypertext link associated
3593 * allowed Specifies the formatting commands allowed.
3596 * 1 if ran into a </> specification.
3601 * Purpose: Parse the data.
3603 *****************************************************************************/
3607 ProcessState cur_state,
3608 FormatVariables *cur_vars,
3609 unsigned long seg_flags,
3610 _DtCvFrmtOption frmt_type,
3611 _DtHelpFontHints *font_attr,
3613 const char *scan_string,
3621 int fontType = False;
3622 int cmdType = False;
3627 if (cur_vars->cur_mb_max != 1)
3628 charSize = mblen(cur_vars->rd_ptr, cur_vars->cur_mb_max);
3633 * check to see if a newline was the previous character.
3634 * If so, it may need to be replaced with a space.
3636 if (cur_vars->last_was_nl == True &&
3637 AppendSpaceToInfo(cur_vars, NULL, frmt_type) == -1)
3640 cur_vars->last_was_nl = False;
3641 cur_vars->last_was_mb = False;
3643 switch (*(cur_vars->rd_ptr))
3647 * Go to the next character.
3649 (cur_vars->rd_ptr)++;
3654 cmdType = _DtHelpCeGetCcdfCmd (cur_cmd, cur_vars->rd_buf,
3655 &(cur_vars->rd_ptr),
3664 case CCDF_FIGURE_CMD:
3665 if (CheckSaveSegment(seg_flags, font_attr,
3666 linkspec, cur_vars) == -1
3668 ProcessFigureCmd(cur_vars,
3672 ret_on_nl, fnt_flag) == -1)
3685 fontType = _DtHelpCeGetCcdfFontType (cur_vars->rd_ptr);
3686 done = ChangeFont(fontType, seg_flags,
3688 font_attr , linkspec,
3700 case CCDF_FORMAT_END:
3701 if (CheckSaveSegment(seg_flags, font_attr,
3702 linkspec, cur_vars) == -1 ||
3703 FindEndMarker (cur_vars) == -1)
3711 case CCDF_GRAPHIC_CMD:
3713 * clear out any information
3714 * in the buffer and then
3715 * process the figure.
3717 if (CheckSaveSegment (seg_flags, font_attr,
3718 linkspec, cur_vars) == -1
3720 ProcessInLine (cur_vars, seg_flags,
3729 done = CheckIdString (cur_vars,
3736 ret_on_nl, fnt_flag);
3743 if (CheckSaveSegment (seg_flags, font_attr,
3744 linkspec, cur_vars) == -1
3746 ProcessHypertext(cur_vars, cur_state,
3747 seg_flags, frmt_type,
3749 ret_on_nl, fnt_flag) == -1)
3756 case CCDF_NEWLINE_CMD:
3757 if (SaveNewLine (cur_vars, seg_flags, font_attr,
3760 FindEndMarker (cur_vars) == -1)
3764 case CCDF_OCTAL_CMD:
3765 if (AppendOctalToInfo(cur_vars,
3766 cur_vars->rd_ptr) == -1
3767 || FindEndMarker (cur_vars) == -1)
3774 case CCDF_PARAGRAPH_CMD:
3775 if (CheckSaveSegment (seg_flags, font_attr,
3776 linkspec, cur_vars) == -1
3778 ProcessParagraph(cur_vars, cur_state,
3785 * this should never be hit if the markup is
3786 * correct. Processing labels is through the
3787 * the paragraph processor now.
3789 case CCDF_LABEL_CMD:
3801 * Go to the next character
3803 (cur_vars->rd_ptr)++;
3806 * If processing a static segment, we want to
3807 * keep the author defined end-of-lines.
3809 * Otherwise, we throw them away.
3811 if (_DtCvLITERAL == frmt_type || True == ret_on_nl)
3813 done = SaveStringAsSegments (cur_vars,
3814 _DtCvSetTypeToNewLine(seg_flags),
3815 font_attr, linkspec);
3820 else if (cur_vars->last_was_space == False)
3821 cur_vars->last_was_nl = True;
3827 * go past this character.
3829 (cur_vars->rd_ptr)++;
3832 * append 1-8 characters on the end of the buffer.
3834 _DtHelpCeCountChars(cur_vars->fmt_buf, MB_CUR_MAX,
3836 leftOver = leftOver % 8;
3837 ptr = ((char *) SpaceString) + leftOver;
3838 done = _DtHelpCeAddStrToBuf (&ptr,
3839 &(cur_vars->fmt_buf),
3840 &(cur_vars->fmt_size),
3841 &(cur_vars->fmt_buf_max),
3848 * The author has escaped a character.
3849 * Increment to the escaped character.
3851 (cur_vars->rd_ptr)++;
3854 * Do we need to read more information?
3856 if (*(cur_vars->rd_ptr) == '\0' &&
3857 GetNextBuffer (cur_vars) == -1)
3860 * If we didn't read more information or
3861 * was successful on the read, save the
3862 * escaped character.
3864 done = AppendCharToInfo (cur_vars, &(cur_vars->rd_ptr));
3869 * Put a space in the segment.
3871 done = AppendSpaceToInfo (cur_vars,
3872 &(cur_vars->rd_ptr), frmt_type);
3877 * put the information in the buffer
3879 if (AppendToInfo (cur_vars, &(cur_vars->rd_ptr),
3885 else if (charSize > 1)
3887 if ((cur_vars->ui_info->nl_to_space == 1 ||
3888 (cur_vars->last_was_mb == False
3889 && cur_vars->last_was_nl == True))
3890 && AppendSpaceToInfo(cur_vars, NULL, frmt_type) == -1)
3893 cur_vars->last_was_nl = False;
3894 cur_vars->last_was_mb = True;
3895 if (AppendToInfo (cur_vars, &(cur_vars->rd_ptr), scan_string) == -1)
3898 else if (charSize < 0)
3901 * we have either invalid characters or part of a multi-byte
3902 * character. Read the next buffer for more info.
3904 leftOver = strlen (cur_vars->rd_ptr);
3905 if (leftOver < ((int) MB_CUR_MAX))
3907 if (GetNextBuffer (cur_vars) == -1)
3913 * In trouble brothers and sisters. We have garbage in the
3914 * buffer - BAIL OUT!
3919 if (!done && *(cur_vars->rd_ptr) == '\0')
3922 * We're at the end of the buffer, can we read more?
3924 if (cur_vars->rd_flag > 0 && GetNextBuffer (cur_vars) == -1)
3927 if (cur_vars->rd_flag == 0)
3933 * DO NOT MODIFY 'done' HERE
3934 * If you do, the caller is unable to test for return value == 1!!!!
3937 CheckSaveSegment (seg_flags, font_attr, linkspec, cur_vars) == -1)
3943 /*****************************************************************************
3944 * Function: int ParseTitle (FormatVariables cur_vars)
3947 * cur_vars Specifies the current values for formatting.
3949 * Returns: 0 if successful, -1 if failure.
3953 * Purpose: ParseTitle gets the data between a <TITLE> and </TITLE>
3954 * pair; putting it in a controlling container.
3956 *****************************************************************************/
3959 FormatVariables *cur_vars,
3963 _DtHelpFontHints *fontAttrs)
3966 SegList oldList = cur_vars->my_list;
3969 * rest the current segment list
3971 cur_vars->my_list = InitList;
3974 * check for the <TITLE> directive.
3976 if (_DtHelpCeCheckNextCcdfCmd ("ti", cur_vars->my_file, cur_vars->rd_buf,
3977 cur_vars->rd_size, 1, &(cur_vars->rd_ptr)) != 0
3978 || FindEndMarker (cur_vars) != 0)
3983 * 1 when a </> is found,
3984 * 0 if the data runs out before we finish parsing,
3987 * A return of 1 is required from Parse
3989 if (1 == Parse (CCDF_TITLE_CMD, NormalState, cur_vars,
3991 fontAttrs, -1, Specials,
3992 ~(CCDF_TOPIC_CMD | CCDF_TITLE_CMD | CCDF_ABBREV_CMD |
3993 CCDF_PARAGRAPH_CMD | CCDF_FIGURE_CMD | CCDF_LABEL_CMD),
3997 * skip the any abbreviation that might be there
4001 result = _DtHelpCeSkipCcdfAbbrev (cur_vars->my_file,
4003 &(cur_vars->rd_ptr), cur_vars->rd_size,
4004 cur_vars->cur_mb_max);
4007 * if we successfully skipped the abbreviation and there is
4008 * a title - then attach the title body to the controlling
4009 * container (and make the container a controller).
4011 if (result != -1 && cur_vars->my_list.list)
4013 _DtCvSegment *list = oldList.list;
4014 int cnt = oldList.cnt;
4016 TerminateSegList (&(cur_vars->my_list), True);
4019 * when this segment was allocated, it was initialized
4020 * to the correct vertical and horizontal orientation
4021 * for a CCDF title. Simply set the type to container
4022 * and controller to get it to act properly.
4026 list[cnt].type = _DtCvSetTypeToContainer(list[cnt].type);
4027 if (True == cont_flag)
4028 list[cnt].type = _DtCvSetTypeToController(list[cnt].type);
4031 * attach the title body to the controller container.
4033 _DtCvContainerListOfSeg(&list[cnt]) = cur_vars->my_list.list;
4036 * and count this segment as used.
4041 * otherwise, a container hasn't been created for this list.
4042 * but we don't want to loose the information.
4045 oldList.list = cur_vars->my_list.list;
4050 * restore segment usage information.
4052 cur_vars->my_list = oldList;
4057 /*****************************************************************************
4058 * Function: int Format (FormatVariables cur_vars, char *id_string,
4066 * Purpose: Format is the top entry point for formating Help Files with
4067 * formatting information into a form understood by a display area.
4068 * It will keep calling Parse, until the entire topic is read
4069 * or an error occurs.
4071 *****************************************************************************/
4074 FormatVariables *cur_vars,
4075 _FrmtUiInfo *ui_info,
4077 _DtCvTopicPtr *ret_topic )
4081 char *charSet = NULL;
4082 char readBuf[BUFF_SIZE];
4083 _DtHelpFontHints fontAttrs;
4084 _DtCvTopicInfo *topicHandle;
4085 SegList myList = InitList;
4088 * malloc space for the topic handle.
4090 topicHandle = (_DtCvTopicInfo *) malloc (sizeof(_DtCvTopicInfo));
4091 if (topicHandle == NULL)
4095 * initialize the font attributes to the default hints
4097 _DtHelpCeCopyDefFontAttrList (&fontAttrs);
4100 * set up the formatting variable structure
4102 if (InitStructure (cur_vars, ui_info, readBuf, BUFF_SIZE) == -1)
4106 * read the first buffer's worth of the topic.
4108 cur_vars->rd_flag = _DtHelpCeReadBuf (cur_vars->my_file, cur_vars->rd_buf,
4110 if (cur_vars->rd_flag == -1)
4114 * The first command in the buffer MUST be the <TOPIC> command.
4115 * It is in a one byte charset.
4117 if (_DtHelpCeGetCcdfTopicCmd (((void *) NULL), cur_vars->my_file,
4118 cur_vars->rd_buf, &(cur_vars->rd_ptr),
4119 cur_vars->rd_size, 1, &charSet) == -1)
4123 * change the character set to the returned character set
4124 * Assume that the charset is 'iso8859' if not specified.
4126 cur_vars->cur_mb_max = 1;
4127 if (NULL != charSet)
4128 GetMbLen(cur_vars, charSet, &(_DtHelpFontHintsLang(fontAttrs)),
4129 &(_DtHelpFontHintsCharSet(fontAttrs)));
4132 * Remember the topic code set and MB_CUR_MAX.
4134 cur_vars->topic_char_set = _DtHelpFontHintsCharSet(fontAttrs);
4135 cur_vars->topic_lang = _DtHelpFontHintsLang(fontAttrs);
4136 cur_vars->topic_mb_max = cur_vars->cur_mb_max;
4139 * allocate two segments for the topic - one for the <title>
4140 * and one for the body of the topic.
4142 if (0 != CheckList(&(cur_vars->my_list), 2, 2))
4144 if (NULL != charSet)
4146 free(_DtHelpFontHintsLang(fontAttrs));
4147 free(_DtHelpFontHintsCharSet(fontAttrs));
4154 * get the title and skip the abbreviation.
4156 if (0 != ParseTitle(cur_vars, True, True, 0, &fontAttrs))
4158 if (NULL != charSet)
4160 free(_DtHelpFontHintsLang(fontAttrs));
4161 free(_DtHelpFontHintsCharSet(fontAttrs));
4168 * remember this current list since we will be attaching any more
4169 * information as a child of these segments.
4171 myList = cur_vars->my_list;
4174 * process the rest of the information
4176 while (0 == result && !done)
4179 * reset the segment count before processing the information
4180 * for this paragraph
4182 cur_vars->my_list = InitList;
4185 * make sure we've got a container for this paragraph
4187 done = CheckList(&myList, 1, GROW_SIZE);
4190 * now process the information while finding paragraphs.
4194 done = Parse (CCDF_PARAGRAPH_CMD, NormalState, cur_vars,
4196 &fontAttrs, -1, Specials,
4197 ~(CCDF_TOPIC_CMD | CCDF_TITLE_CMD | CCDF_ABBREV_CMD),
4199 } while (0 == done);
4202 * if no errors, attach the resulting child information to the
4203 * paragraph container.
4208 * clean up the last segment.
4210 if (cur_vars->my_list.list)
4212 _DtCvSegment *list = NextAvailSeg(myList);
4214 TerminateSegList (&(cur_vars->my_list), True);
4217 * make it a container.
4219 list->type = _DtCvSetTypeToContainer(list->type);
4222 * attach the information to the container
4224 _DtCvContainerListOfSeg(list) = cur_vars->my_list.list;
4227 * and count this container as used.
4237 * If we had errors, deallocate the memory.
4240 _DtHelpFreeSegments(myList.list, _DtCvFALSE, ui_info->destroy_region,
4241 ui_info->client_data);
4245 * Tighten up the paragraph structures if too many allocated.
4247 if (0 != myList.cnt)
4248 TerminateSegList (&(myList), True);
4251 free ((char *) myList.list);
4257 * return the values, even if they are null and zero.
4260 if (id_string == NULL)
4261 topicHandle->id_str = id_string;
4263 topicHandle->id_str = strdup(id_string);
4265 topicHandle->seg_list = myList.list;
4266 topicHandle->mark_list = NULL;
4267 topicHandle->link_data = cur_vars->my_links;
4269 *ret_topic = (void *) topicHandle;
4274 if (NULL != charSet)
4276 free(_DtHelpFontHintsLang(fontAttrs));
4277 free(_DtHelpFontHintsCharSet(fontAttrs));
4287 /*****************************************************************************
4288 * Function: int FormatCCDFTitle (FormatVariables cur_vars
4291 * cur_vars Specifies the current values for formatting.
4292 * id_string Specifies the id to look for or NULL.
4293 * ret_para Returns a pointer to a list of _DtCvSegment
4295 * ret_num Specifies the number of structures in
4297 * ret_seg Specifies the segment containing 'id_string'
4304 * Purpose: Format is the top entry point for formating Help Files with
4305 * formatting information into a form understood by a display area.
4306 * It will keep calling Parse, until the entire topic is read
4307 * or an error occurs.
4309 *****************************************************************************/
4312 FormatVariables *cur_vars,
4313 _DtHelpFontHints fontAttrs,
4321 char *charSet = NULL;
4323 int origCnt = cur_vars->my_list.cnt;
4325 _DtCvSegment *titleSeg;
4328 cur_vars->rd_buf[0] = '\0';
4329 cur_vars->rd_ptr = cur_vars->rd_buf;
4331 if (_DtHelpCeFileOpenAndSeek(filename, offset, -1,
4332 &(cur_vars->my_file), NULL) != 0)
4335 cur_vars->rd_flag = _DtHelpCeReadBuf (cur_vars->my_file, cur_vars->rd_buf,
4338 if (cur_vars->rd_flag == -1)
4340 _DtHelpCeBufFileClose (cur_vars->my_file, True);
4345 * The first command in the buffer MUST be the <TOPIC> command.
4346 * It is in a one byte charset.
4348 if (_DtHelpCeGetCcdfTopicCmd (((void *) NULL), cur_vars->my_file,
4349 cur_vars->rd_buf, &(cur_vars->rd_ptr),
4350 cur_vars->rd_size, 1, &charSet) == -1)
4352 _DtHelpCeBufFileClose (cur_vars->my_file, True);
4357 * change the character set to the returned character set
4358 * Assume that the charset is 'iso8859' if not specified.
4360 cur_vars->cur_mb_max = 1;
4361 if (NULL != charSet)
4362 GetMbLen(cur_vars, charSet, &(_DtHelpFontHintsLang(fontAttrs)),
4363 &(_DtHelpFontHintsCharSet(fontAttrs)));
4366 * Remember the topic code set and MB_CUR_MAX.
4368 cur_vars->topic_char_set = _DtHelpFontHintsCharSet(fontAttrs);
4369 cur_vars->topic_lang = _DtHelpFontHintsLang(fontAttrs);
4370 cur_vars->topic_mb_max = cur_vars->cur_mb_max;
4373 * allocate another segment for this title.
4375 if (0 != CheckSegList(cur_vars))
4377 if (NULL != charSet)
4379 free(_DtHelpFontHintsLang(fontAttrs));
4380 free(_DtHelpFontHintsCharSet(fontAttrs));
4383 _DtHelpCeBufFileClose(cur_vars->my_file, True);
4388 * set the left margin correctly.
4390 titleSeg = NextAvailSeg(cur_vars->my_list);
4391 titleSeg->handle.container = DefContainer;
4392 titleSeg->type = _DtCvSetTypeToContainer(titleSeg->type);
4393 _DtCvContainerLMarginOfSeg(titleSeg) = level*2*cur_vars->ui_info->avg_char;
4394 _DtCvContainerBMarginOfSeg(titleSeg) = 0;
4395 _DtCvContainerTypeOfSeg(titleSeg) = _DtCvLITERAL;
4396 _DtCvContainerLeadingOfSeg(titleSeg) = cur_vars->ui_info->leading;
4401 if (-1 == ParseTitle(cur_vars, False, False, fnt_flags, &fontAttrs))
4403 if (NULL != charSet)
4405 free(_DtHelpFontHintsLang(fontAttrs));
4406 free(_DtHelpFontHintsCharSet(fontAttrs));
4409 _DtHelpCeBufFileClose(cur_vars->my_file, True);
4414 * We've parsed the title. see if we want the abbrev.
4417 * if the title is null or we want the abbrev,
4418 * process the abbreviation.
4420 if (NULL == _DtCvContainerListOfSeg(titleSeg) || want_abbrev)
4422 SegList titleList = cur_vars->my_list;
4425 * reset the buffer to get the abbreviation
4427 if (cur_vars->fmt_buf != NULL)
4429 free(cur_vars->fmt_buf);
4430 cur_vars->fmt_buf = NULL;
4431 cur_vars->fmt_size = 0;
4432 cur_vars->fmt_buf_max = 0;
4435 result = _DtHelpCeGetCcdfAbbrevCmd (cur_vars->my_file, cur_vars->rd_buf,
4436 cur_vars->rd_size, cur_vars->cur_mb_max,
4437 &(cur_vars->rd_ptr), &(cur_vars->fmt_buf));
4440 * If no errors getting the abbreviation, save it
4445 * save the abbreviation
4447 if (cur_vars->fmt_buf != NULL)
4450 * If there was a title, free it
4452 if (NULL != _DtCvContainerListOfSeg(titleSeg))
4453 _DtHelpFreeSegments(_DtCvContainerListOfSeg(titleSeg),
4455 cur_vars->ui_info->destroy_region,
4456 cur_vars->ui_info->client_data);
4459 * save the abbreviation
4461 cur_vars->my_list = InitList;
4462 cur_vars->fmt_size = strlen (cur_vars->fmt_buf);
4463 cur_vars->fmt_buf_max = cur_vars->fmt_size + 1;
4464 if (cur_vars->fmt_size > 0)
4465 result = SaveStringAsSegments (cur_vars, 0, &fontAttrs, -1);
4468 TerminateSegList(&(cur_vars->my_list), True);
4470 titleSeg->type = _DtCvSetTypeToContainer(titleSeg->type);
4471 _DtCvContainerListOfSeg(titleSeg) = cur_vars->my_list.list;
4477 * eliminate this segment if no title or abbrev was found.
4479 if (NULL == _DtCvContainerListOfSeg(titleSeg))
4481 titleList.cnt = origCnt;
4482 _DtCvContainerTypeOfSeg(titleSeg) = _DtCvDYNAMIC;
4486 * reset the title list
4488 cur_vars->my_list = titleList;
4491 result = _DtHelpCeSkipCcdfAbbrev (cur_vars->my_file, cur_vars->rd_buf,
4492 &(cur_vars->rd_ptr), cur_vars->rd_size,
4493 cur_vars->cur_mb_max);
4495 if (cur_vars->fmt_buf != NULL)
4496 cur_vars->fmt_buf[0] = '\0';
4497 cur_vars->fmt_size = 0;
4500 * remove the newline from the lists and
4501 * change all the newlines on the segments into a space.
4503 for (list = _DtCvContainerListOfSeg(titleSeg);
4504 NULL != list; list = list->next_seg)
4506 if (_DtCvIsSegNewLine(list))
4509 * clear the newline flag.
4511 list->type &= ~(_DtCvNEW_LINE);
4514 * check to see if the last character of this segment or
4515 * the first character of the next segment is a space.
4518 if (NULL != list->next_disp && _DtCvIsSegString(list)
4519 && _DtCvIsSegRegChar(list))
4522 * is the last character of the string a space?
4525 len = strlen((char *) _DtCvStringOfStringSeg(list)) - 1;
4526 if (' ' != ((char *) _DtCvStringOfStringSeg(list))[len])
4529 * is the next segment a one byte string?
4530 * and if so, is the first character a space?
4531 * if so, do nothing.
4533 if (_DtCvIsSegString(list->next_disp)
4534 && _DtCvIsSegRegChar(list->next_disp)
4535 && ' ' != *((char *)_DtCvStringOfStringSeg(list->next_disp)))
4538 * need to add a space to one of these strings.
4541 _DtCvStringOfStringSeg(list) = (char *) realloc(
4542 (void *) _DtCvStringOfStringSeg(list),
4543 sizeof(char *) * len);
4544 if (NULL == _DtCvStringOfStringSeg(list))
4547 strPtr = (char *) _DtCvStrPtr(
4548 _DtCvStringOfStringSeg(list),
4559 _DtHelpCeBufFileClose (cur_vars->my_file, True);
4564 if (NULL != charSet)
4566 free(_DtHelpFontHintsLang(fontAttrs));
4567 free(_DtHelpFontHintsCharSet(fontAttrs));
4577 /******************************************************************************
4578 * Function: int FormatEntryInToc (
4582 * Returns: 0 if successful, -1 if errors
4588 ******************************************************************************/
4591 _DtHelpVolumeHdl volume,
4593 FormatVariables *cur_vars,
4594 _DtHelpFontHints font_attrs,
4601 char *strPtr = NULL;
4603 _DtCvSegment *titleSeg;
4607 * check to see that there is a segment for this title.
4609 if (0 != CheckSegList(cur_vars))
4613 * The next segment in the list will become the next title.
4614 * Get a pointer to it for later use.
4616 titleList = cur_vars->my_list;
4617 titleSeg = NextAvailSeg(titleList);
4618 titleSeg->handle.container = DefContainer;
4619 titleSeg->type = _DtCvSetTypeToContainer(titleSeg->type);
4620 _DtCvContainerBMarginOfSeg(titleSeg) = 0;
4621 _DtCvContainerLeadingOfSeg(titleSeg) = cur_vars->ui_info->leading;
4624 * Get the file and offset for the topic.
4625 * and process the topic's title, ignoring most font changes.
4627 if (True == _DtHelpCeFindId(volume, loc_id, -1, &strPtr, &offset) &&
4628 -1 != FormatCCDFTitle(cur_vars, font_attrs, strPtr, offset, level,
4629 ((1<<_CEFONT_SIZE)|(1<<_CEFONT_WEIGHT)|(1<<_CEFONT_ANGLE)|(1<<_CEFONT_TYPE)),
4633 * now create the hypertext link index for the ghostlink.
4635 num = _DtLinkDbAddLink(cur_vars->my_links, NULL, loc_id,
4636 _DtCvLinkType_SameVolume,
4637 _DtCvWindowHint_CurrentWindow,
4640 * if a link index was successfully created, process the item.
4647 * check to see if this title had any segments.
4649 pSeg = _DtCvContainerListOfSeg(titleSeg);
4652 while (NULL != pSeg)
4655 * If this segment has a hypertext link, remove it.
4657 if (pSeg->link_idx != -1)
4658 _DtLinkDbRemoveLink(cur_vars->my_links, pSeg->link_idx);
4661 * change the link index and flag to the ghost link.
4663 pSeg->link_idx = num;
4664 pSeg->type &= ~(_DtCvHYPER_TEXT);
4665 pSeg->type = _DtCvSetTypeToGhostLink(pSeg->type);
4668 * go to the next segment.
4670 pSeg = pSeg->next_seg;
4676 * no title or abbreviation, so use the location id.
4677 * allocate room for it and put it between parens.
4679 tocLen = strlen (loc_id) + 9;
4680 if (tocLen > cur_vars->fmt_buf_max)
4682 if (NULL == cur_vars->fmt_buf)
4683 cur_vars->fmt_buf = (char *) malloc (tocLen);
4685 cur_vars->fmt_buf = (char *) realloc(
4688 cur_vars->fmt_buf_max = tocLen;
4691 cur_vars->fmt_size = tocLen - 1;
4692 strcpy (cur_vars->fmt_buf, "...(");
4693 strcat (cur_vars->fmt_buf, loc_id);
4694 strcat (cur_vars->fmt_buf, ")...");
4697 * don't overwrite the title's
4699 cur_vars->my_list = InitList;
4702 * save the string off and then attach to the title
4705 result = SaveStringAsSegments(cur_vars, _DtCvGHOST_LINK,
4708 _DtCvContainerListOfSeg(titleSeg) = cur_vars->my_list.list;
4711 * restore the title list.
4713 cur_vars->my_list = titleList;
4723 } /* End FormatEntryInToc */
4725 /******************************************************************************
4726 * Function: int FormatExpandToc (
4727 * _DtHelpVolumeHdl volume,
4730 ******************************************************************************/
4733 _DtHelpVolumeHdl volume,
4736 FormatVariables *cur_vars,
4737 _DtHelpFontHints font_attrs,
4742 if (*path_lst != NULL)
4744 font_attrs.weight = _DtHelpFontWeightMedium;
4745 if (_DtCvStrCaseCmpLatin1(*path_lst, cur_id) == 0)
4746 font_attrs.weight = _DtHelpFontWeightBold;
4748 result = FormatEntryInToc(volume, *path_lst, cur_vars,
4755 int count = _DtHelpCeGetCcdfTopicChildren(volume,
4756 *path_lst, &children);
4759 * if there are children, format them
4763 childLst = children;
4764 font_attrs.weight = _DtHelpFontWeightMedium;
4765 while (result != -1 && count > 0)
4768 * found the next item in the list
4770 if (*path_lst != NULL &&
4771 _DtCvStrCaseCmpLatin1(*path_lst, *childLst) == 0)
4772 result = FormatExpandedToc(volume,
4774 cur_vars, font_attrs, level);
4776 result = FormatEntryInToc(volume, *childLst,
4777 cur_vars, font_attrs, level);
4783 if (children != NULL)
4784 _DtCvFreeArray((void **) children);
4791 /******************************************************************************
4793 * Semi-Public Functions
4795 *****************************************************************************/
4796 /******************************************************************************
4797 * Function: VarHandle *__DtHelpCeSetUpVars (char *rd_buf, grow_size)
4801 * Returns: NULL if unsuccessful.
4807 ******************************************************************************/
4809 __DtHelpCeSetUpVars(
4812 _FrmtUiInfo *ui_info)
4814 FormatVariables *newVars;
4816 newVars = (FormatVariables *) malloc (sizeof(FormatVariables));
4818 newVars->ui_info = ui_info;
4820 newVars->topic_mb_max = _DtHelpCeGetMbLen(lang, code_set);
4821 newVars->cur_mb_max = newVars->topic_mb_max;
4823 return ((VarHandle) newVars);
4825 } /* End __DtHelpCeSetUpVars */
4827 /******************************************************************************
4828 * Function: int __DtHelpCeProcessString (char *in_string, int seg_type,
4833 * Returns: 0 if successful, -1 if errors.
4839 ******************************************************************************/
4841 __DtHelpCeProcessString(
4842 VarHandle var_handle,
4844 _DtCvFrmtOption frmt_type,
4850 _DtHelpFontHints *font_attr )
4853 FormatVariables *myVars = (FormatVariables *) var_handle;
4854 SegList oldList = myVars->my_list;
4856 myVars->rd_buf = in_string;
4857 myVars->rd_size = in_size;
4858 myVars->rd_ptr = in_string;
4859 myVars->my_file = my_file;
4861 if (my_file == NULL)
4862 myVars->rd_flag = 0;
4864 myVars->rd_flag = strlen(in_string);
4868 if (True == ret_on_nl)
4869 myVars->my_list = InitList;
4871 done = Parse (CCDF_FONT_CMD, NormalState, myVars,
4874 -1, scan_string, (CCDF_FONT_CMD | CCDF_OCTAL_CMD), ret_on_nl,
4877 if (done != -1 && True == ret_on_nl)
4879 TerminateSegList (&(myVars->my_list), True);
4880 if (NULL != myVars->my_list.list)
4882 done = CheckList (&oldList, 1, GROW_SIZE);
4885 _DtCvSegment *newSeg = NextAvailSeg(oldList);
4887 newSeg->type = _DtCvSetTypeToContainer(newSeg->type);
4888 _DtCvContainerListOfSeg(newSeg) = myVars->my_list.list;
4889 _DtCvContainerTypeOfSeg(newSeg) = _DtCvDYNAMIC;
4893 TerminateSegList(&oldList, False);
4899 if (False == ret_on_nl)
4900 oldList = myVars->my_list;
4902 myVars->my_list = oldList;
4905 } /* End __DtHelpCeProcessString */
4907 /*****************************************************************************
4908 * Function: int __DtHelpCeGetParagraphList (
4912 * Returns: 0 if successful, -1 if errors.
4916 * Purpose: _DtHelpFormatGetParagraphList places a terminator on the
4917 * last segment in the current paragraph and returns the
4918 * segment list included in the topic information structure.
4920 * If make_cont is true, the segment list is first included
4921 * in a container with the specified type.
4923 *****************************************************************************/
4925 __DtHelpCeGetParagraphList (
4926 VarHandle var_handle,
4928 _DtCvFrmtOption type,
4929 _DtCvTopicPtr *ret_handle)
4932 FormatVariables *myVars = (FormatVariables *) var_handle;
4933 _DtCvTopicInfo *topicHandle;
4936 * check the parameters.
4938 if (ret_handle == NULL || myVars == NULL)
4944 TerminateSegList(&(myVars->my_list), True);
4946 topicHandle = (_DtCvTopicInfo *) malloc (sizeof(_DtCvTopicInfo));
4947 if (topicHandle != NULL)
4951 if (True == make_cont)
4953 _DtCvSegment *myCont = AllocateSegments(NULL, 0, 1);
4957 myCont->type = _DtCvSetTypeToContainer(myCont->type);
4958 _DtCvContainerTypeOfSeg(myCont) = type;
4959 _DtCvContainerListOfSeg(myCont) = myVars->my_list.list;
4961 myVars->my_list.list = myCont;
4962 myVars->my_list.cnt = 1;
4963 myVars->my_list.max = 1;
4969 topicHandle->id_str = NULL;
4970 topicHandle->seg_list = myVars->my_list.list;
4971 topicHandle->mark_list = NULL;
4972 topicHandle->link_data = myVars->my_links;
4974 *ret_handle = (_DtCvTopicPtr) topicHandle;
4977 if (myVars->fmt_buf != NULL)
4978 free(myVars->fmt_buf);
4983 /******************************************************************************
4984 * Function: int _DtHelpCeFrmtCcdfTopic (_DtHelpVolumeHdl volume, char *filename,
4985 * int offset, char *id_string,
4986 * _DtCvTopicPtr *ret_handle)
4989 * volume Specifies the Help Volume the information
4990 * is associated with.
4991 * filename Specifies the file containing the Help Topic
4993 * offset Specifies the offset into 'filename' to
4994 * the Help Topic desired.
4995 * id_string Specifies the location id to look for or NULL.
4996 * ret_handle Returns a handle to the topic information
4997 * including the number of paragraphs and the
5000 * Returns: 0 if successful, -1 if errors
5004 * Purpose: _DtHelpCeFrmtCcdfTopic formats Help Files with formatting
5005 * information into a Canvas Engine structure.
5007 ******************************************************************************/
5009 _DtHelpCeFrmtCcdfTopic(
5010 _DtHelpVolumeHdl volume,
5014 _FrmtUiInfo *ui_info,
5015 _DtCvTopicPtr *ret_handle )
5019 FormatVariables variables;
5022 * Check the parameters
5024 if (volume == NULL || filename == NULL || offset < 0 || ret_handle == NULL)
5031 * get the current file path.
5033 variables = DefVars;
5034 variables.topic_id = id_string;
5037 variables.vol_name = _DtHelpCeGetVolumeName(volume);
5038 variables.my_path = strdup (variables.vol_name);
5039 if (variables.my_path == NULL)
5042 result = _DtHelpCeStrrchr (variables.my_path, Slash, MB_CUR_MAX, &ptr);
5044 ptr = strrchr (variables.my_path, '/');
5051 * open the file and seek to the correct place.
5053 result = _DtHelpCeFileOpenAndSeek (filename, offset, -1,
5054 &(variables.my_file), NULL);
5058 * Initialize the X variables.
5060 result = Format (&variables, ui_info, id_string, ret_handle);
5062 _DtHelpCeBufFileClose (variables.my_file, True);
5065 if (variables.fmt_buf != NULL)
5066 free (variables.fmt_buf);
5068 if (variables.my_path != NULL)
5069 free (variables.my_path);
5073 } /* End _DtHelpCeFrmtCcdfTopic */
5075 /******************************************************************************
5076 * Function: int _DtHelpCeFrmtCcdfPathAndChildren (
5077 * _DtHelpVolumeHdl volume,
5078 * _DtCvTopicPtr *ret_handle)
5081 * ret_handle Returns a handle to the topic information
5082 * including the number of paragraphs and the
5085 * Returns: 0 if successful, -1 if errors, 1 if there the path is empty.
5089 * Purpose: _DtHelpCeFormatCcdfToc formats Table of Contents for
5092 ******************************************************************************/
5094 _DtHelpCeFrmtCcdfPathAndChildren(
5095 _DtHelpVolumeHdl volume,
5097 _FrmtUiInfo *ui_info,
5098 _DtCvTopicPtr *ret_handle )
5104 char readBuf[BUFF_SIZE];
5105 FormatVariables myVars;
5106 _DtHelpFontHints fontAttrs;
5108 _DtHelpCeCopyDefFontAttrList (&fontAttrs);
5109 fontAttrs.pointsz = 10;
5110 fontAttrs.weight = _DtHelpFontWeightMedium;
5111 fontAttrs.style = _DtHelpFontStyleSanSerif;
5114 * Check the parameters
5116 if (volume == NULL || ret_handle == NULL)
5124 if (InitStructure (&myVars, ui_info, readBuf, BUFF_SIZE) == -1)
5128 * get the list of topics in the volume.
5130 pathCnt = _DtHelpCeGetCcdfIdPath(volume, loc_id, &pathHead);
5135 * Check to see if this topic is in the topic list.
5136 * I.e. if a count of 1 is returned this should match the
5137 * top topic, otherwise this is an hidden topic.
5141 if (_DtHelpCeGetCcdfTopTopic(volume, &ptr) == -1)
5143 else if (_DtCvStrCaseCmpLatin1(ptr, *pathHead) != 0)
5148 * if result is non-zero, we had problems or this is a hidden topic
5152 fontAttrs.slant = _DtHelpFontSlantRoman;
5154 myVars.topic_id = loc_id;
5155 myVars.vol_name = _DtHelpCeGetVolumeName(volume);
5156 myVars.my_path = strdup (myVars.vol_name);
5157 if (myVars.my_path == NULL)
5160 if (-1 == _DtHelpCeStrrchr (myVars.my_path, Slash, MB_CUR_MAX, &ptr))
5161 ptr = strrchr (myVars.my_path, '/');
5166 result = FormatExpandedToc(volume, loc_id, pathHead,
5167 &myVars, fontAttrs, 0);
5168 _DtCvFreeArray((void **) pathHead);
5172 result = __DtHelpCeGetParagraphList (&myVars, False, _DtCvDYNAMIC,
5176 * check for an empty path.
5178 if (-1 != result && NULL == ((_DtCvTopicInfo *) *ret_handle)->seg_list)
5181 if (myVars.my_path != NULL)
5182 free(myVars.my_path);
5186 } /* End _DtHelpCeFrmtCcdfPathAndChildren */
5188 /******************************************************************************
5189 * Function: int _DtHelpCeGetCcdfTitleChunks (
5190 * _DtHelpVolumeHdl volume,
5191 * _DtCvTopicPtr *ret_handle)
5194 * ret_handle Returns a handle to the topic information
5195 * including the number of paragraphs and the
5198 * Returns: 0 if successful, -1 if errors
5202 * Purpose: _DtHelpCeFormatCcdfToc formats Table of Contents for
5205 ******************************************************************************/
5207 _DtHelpCeGetCcdfTitleChunks(
5208 _DtHelpVolumeHdl volume,
5210 _FrmtUiInfo *ui_info,
5218 char readBuf[BUFF_SIZE];
5219 _DtCvSegment *titleSeg;
5220 _DtCvSegment *list = NULL;
5221 FormatVariables myVars;
5222 _DtHelpFontHints fontAttrs;
5223 _DtHelpCeLockInfo lockInfo;
5226 * Check the parameters
5228 if (volume == NULL || ret_chunks == NULL)
5235 * init the return value
5240 * get the topic in the volume.
5242 if (_DtHelpCeLockVolume(volume, &lockInfo) != 0)
5245 if (_DtHelpCeFindId(volume, loc_id, -1, &fileName, &offset) == False)
5247 _DtHelpCeUnlockVolume(lockInfo);
5251 _DtHelpCeCopyDefFontAttrList (&fontAttrs);
5253 if (InitStructure (&myVars, ui_info, readBuf, BUFF_SIZE) == -1)
5255 _DtHelpCeUnlockVolume(lockInfo);
5260 * initialize my variables.
5262 myVars.topic_id = loc_id;
5263 myVars.vol_name = _DtHelpCeGetVolumeName(volume);
5264 myVars.my_path = strdup (myVars.vol_name);
5265 if (myVars.my_path == NULL)
5267 _DtHelpCeUnlockVolume(lockInfo);
5271 if (-1 == _DtHelpCeStrrchr (myVars.my_path, Slash, MB_CUR_MAX, &ptr))
5272 ptr = strrchr (myVars.my_path, '/');
5277 result = FormatCCDFTitle(&myVars, fontAttrs, fileName,
5278 offset, 0, (1 << _CEFONT_SIZE), True);
5281 if (-1 != result && 0 < myVars.my_list.cnt)
5283 titleSeg = &(myVars.my_list.list[myVars.my_list.cnt - 1]);
5284 list = _DtCvContainerListOfSeg(titleSeg);
5287 if (result != -1 && NULL != list)
5289 _DtCvSegment *pSeg = list;
5291 while (-1 != result && NULL != pSeg)
5294 * create the types and add the informatio to the array.
5296 type = DT_HELP_CE_FONT_PTR | DT_HELP_CE_STRING;
5297 if (_DtCvIsSegNewLine(pSeg))
5298 type |= DT_HELP_CE_NEWLINE;
5300 if (_DtCvIsSegString(pSeg))
5302 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5304 if (NULL != *ret_chunks)
5305 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5306 (void *) _DtCvFontOfStringSeg(pSeg));
5308 if (NULL != *ret_chunks)
5310 if (_DtCvIsSegWideChar(pSeg))
5312 offset = _DtCvStrLen(_DtCvStringOfStringSeg(pSeg), 1)
5314 ptr = (char *) malloc (sizeof(char) * offset);
5317 (wchar_t *)_DtCvStringOfStringSeg(pSeg),
5321 ptr = strdup((char *) _DtCvStringOfStringSeg(pSeg));
5324 *ret_chunks = (void **)_DtCvAddPtrToArray(
5325 *ret_chunks, (void *) ptr);
5328 if (NULL == *ret_chunks || NULL == ptr)
5333 * go to the next segment
5335 pSeg = pSeg->next_seg;
5342 int idLen = strlen (loc_id) + 9;
5345 * create the location id string.
5347 idStr = (char *) malloc (idLen);
5351 * format the location id
5353 strcpy (idStr, "...(");
5354 strcat (idStr, loc_id);
5355 strcat (idStr, ")...");
5358 * format the language and codeset
5360 strcpy(buf, _DtHelpFontHintsLang(fontAttrs));
5362 strcpy(buf, _DtHelpFontHintsCharSet(fontAttrs));
5365 * creat a chunk table
5367 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5368 (void *) (DT_HELP_CE_CHARSET | DT_HELP_CE_STRING));
5369 if (NULL != *ret_chunks)
5370 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5371 (void *) strdup(buf));
5372 if (NULL != *ret_chunks)
5373 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5378 if (NULL != *ret_chunks)
5379 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5380 (void *) DT_HELP_CE_END);
5385 if (0 < myVars.my_list.cnt)
5386 _DtHelpFreeSegments(myVars.my_list.list, _DtCvFALSE,
5387 ui_info->destroy_region,
5388 ui_info->client_data);
5391 * free the link database
5393 _DtLinkDbDestroy(myVars.my_links);
5398 if (myVars.my_path != NULL)
5399 free(myVars.my_path);
5400 if (myVars.fmt_buf != NULL)
5401 free(myVars.fmt_buf);
5403 _DtHelpCeUnlockVolume(lockInfo);
5406 * indicate an error if problems.
5409 if (NULL == *ret_chunks)
5414 } /* End _DtHelpCeGetCcdfTitleChunks */
5416 /******************************************************************************
5417 * Function: int _DtHelpCeGetCcdfVolTitleChunks (
5418 * _DtHelpVolumeHdl volume,
5419 * void ***ret_chunks)
5422 * ret_chunks Returns a ptr to the title information chunks
5423 * The title chunks are stored in allocated memory
5424 * that is owned by the caller and should be
5425 * freed when no longer needed.
5428 * Returns: 0 if successful, -1 if errors
5432 * Purpose: _DtHelpCeFormatCcdfVolTitleChunks formats volume title for
5435 ******************************************************************************/
5437 _DtHelpCeGetCcdfVolTitleChunks(
5438 _DtHelpVolumeHdl volume,
5439 _FrmtUiInfo *ui_info,
5446 * get the title of the volume (we own the memory).
5448 charSet = _DtHelpCeGetCcdfVolLocale(volume);
5449 if (charSet == NULL)
5450 charSet = strdup("C.ISO-8859-1");
5452 titleStr = _DtHelpCeGetCcdfVolTitle(volume);
5453 if (titleStr != NULL)
5455 *ret_chunks = (void **) malloc(sizeof(void *) * 4);
5456 if (*ret_chunks == NULL)
5459 (*ret_chunks)[0] = (void *) (DT_HELP_CE_CHARSET | DT_HELP_CE_STRING);
5460 (*ret_chunks)[1] = (void *) strdup(charSet);
5461 (*ret_chunks)[2] = (void *) strdup(titleStr);
5462 (*ret_chunks)[3] = (void *) DT_HELP_CE_END;
5467 if (_DtHelpCeGetCcdfTitleChunks(volume, "_title",
5468 ui_info, ret_chunks) != 0
5470 _DtHelpCeGetCcdfTitleChunks(volume, "_hometopic",
5471 ui_info, ret_chunks) != 0)
5477 } /* End _DtHelpCeGetCcdfVolTitleChunks */