2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: 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 NULL, /* 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 seperate 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);
690 * reattach the private information with their segments.
692 while (count < original_size)
693 p_seg[count++].client_use = priv++;
696 p_seg = _DtHelpAllocateSegments (new_size);
701 * want to 'empty' the type.
703 while (original_size < new_size)
706 * if we went through _DtHelpAllocateSegments, then the
707 * priv pointer will be NULL. But that's okay since the
708 * _DtHelpAllocateSegments routine will initalized the
709 * variables for us. The only reason we have to do it
710 * is if we've reallocated the list.
716 p_seg[original_size ].client_use = priv++;
717 p_seg[original_size ].type = _DtCvNOOP;
718 p_seg[original_size ].link_idx = -1;
719 p_seg[original_size ].next_seg = NULL;
720 p_seg[original_size ].next_disp = NULL;
723 p_seg[original_size++].handle.container = DefContainer;
730 /******************************************************************************
731 * Function: static int CheckList (
732 * FormatVariables cur_vars, int count, int grow)
735 * cur_vars Specifies a structure containing the list
737 * count Specifies the amount needed.
738 * grow Specifies the amount to grow by.
740 * Returns: 0 if successful, -1 if failure.
742 * Purpose: Makes sure there is 'grow' size number of segments
743 * available. If not, it calls AllocateSegments to 'grow'
744 * the segment list. cur_vars->seg_list is set to the new
745 * pointer, cur_vars->seg_max indicates the maximum number
746 * of segments in the list.
748 *****************************************************************************/
756 * what's the new count?
758 count += seg_list->cnt;
761 * is it larger than the current max?
763 if (count > seg_list->max)
766 * grow the list by the indicated amount.
768 grow += seg_list->max;
771 * check to see if it is enough. If not, force the grow value
772 * to be the required count.
780 seg_list->list = AllocateSegments(seg_list->list, seg_list->max, grow);
783 * return an code if no list allocated.
785 if (NULL == seg_list->list)
791 seg_list->max = grow;
797 /******************************************************************************
798 * Function: int SegmentSave (int type,
799 * char **font_attr, char *string, int linkspec,
800 * _DtCvSegment *p_seg)
803 * type Specifies the segment type.
804 * font_attr Specifies the resource list of quarks for the
805 * font to associate with the segment.
806 * string Specifies the string segment.
807 * link_spec Specifies the link specification for the
809 * p_seg Specifies the _DtCvSegment structure to
810 * initialize with the data.
812 * Returns: 0 if successful, -1 if errors.
817 * Purpose: Creates a new segment with the given data.
819 *****************************************************************************/
822 FormatVariables *cur_vars,
823 unsigned long seg_type,
824 _DtHelpFontHints *font_attr,
831 _DtCvSegment *pSeg = NextAvailSeg(cur_vars->my_list);
833 pSeg->type = _DtCvSetTypeToNoop(seg_type);
834 pSeg->link_idx = linkspec;
837 * We use this routine for many things.
838 * If we want an newline in here, we may not have any data.
842 pSeg->type = _DtCvSetTypeToString(pSeg->type);
845 * if a wide character representation is required,
848 if (seg_type & _DtCvWIDE_CHAR)
853 * include the null byte in the multibyte to widechar
861 pwcs = (wchar_t *) malloc(sizeof(wchar_t) * num_chars);
865 str_size = mbstowcs(pwcs, string, ((size_t) num_chars));
867 /* check to see if it converted everything */
868 if (str_size + 1 == num_chars)
869 _DtCvStringOfStringSeg(pSeg) = (void *) pwcs;
875 _DtCvStringOfStringSeg(pSeg) = (void *) strdup(string);
877 if (NULL == _DtCvStringOfStringSeg(pSeg))
881 * set the default font. This should really be passed in via
882 * the format entry point (or the ui_info structure).
884 _DtCvFontOfStringSeg(pSeg) = 0;
889 if (NULL != cur_vars->ui_info->load_font)
890 (*(cur_vars->ui_info->load_font))(
891 cur_vars->ui_info->client_data,
892 _DtHelpFontHintsLang(*font_attr),
893 _DtHelpFontHintsCharSet(*font_attr),
895 &(_DtCvFontOfStringSeg(pSeg)));
901 /******************************************************************************
902 * Function: int SaveStringAsSegments (FormatVariables, int type, char **font_attr,
906 * type Specifies the segment type.
907 * font_attr Specifies the resource list of quarks for the
908 * font to associate with the segment.
909 * link_spec Specifies the link specification for the
912 * Returns: 0 if successful, -1 if errors.
916 * Purpose: Saves a segment into the global 'SegList'. This is
917 * a wrapper around SegmentSave that adds specific
918 * information relative to this module.
920 *****************************************************************************/
922 SaveStringAsSegments (
923 FormatVariables *cur_vars,
924 unsigned long seg_flags,
925 _DtHelpFontHints *font_attr,
935 seg_flags = _DtCvSetTypeToNoop(seg_flags);
936 if (cur_vars->cur_mb_max != 1 && cur_vars->fmt_size > 1)
938 if (IsTypeNewLine(seg_flags))
941 seg_flags = seg_flags & ~(_DtCvNEW_LINE);
944 ptr = cur_vars->fmt_buf;
948 * what type of character is this?
950 len = mblen (ptr, cur_vars->cur_mb_max);
953 * How many of the following characters are of the same size?
955 size = _DtHelpFmtFindBreak (ptr, len, &numChars);
958 * save off the character that doesn't match
963 * put in the null byte for the string.
964 * and set to wide char if not doing multi-byte sequence.
968 seg_flags = _DtCvSetTypeToWideChar (seg_flags);
971 * does this segment get the newline flag?
973 if (True == newLine && size >= cur_vars->fmt_size)
974 seg_flags = _DtCvSetTypeToNewLine(seg_flags);
979 if (CheckSegList(cur_vars) == -1 ||
980 SegmentSave (cur_vars, seg_flags, font_attr, ptr, size,
981 numChars, link_spec) == -1)
985 * remove the wide char flag
987 seg_flags &= ~(_DtCvWIDE_CHAR);
990 * Bump the segment list count.
992 cur_vars->my_list.cnt++;
995 * replace the character that didn't match.
996 * and bump the pointer to it.
1000 cur_vars->fmt_size -= size;
1001 } while (0 < cur_vars->fmt_size);
1005 if (CheckSegList (cur_vars) == -1 ||
1006 SegmentSave (cur_vars, seg_flags, font_attr,
1007 cur_vars->fmt_buf, cur_vars->fmt_size,
1011 cur_vars->my_list.cnt++;
1014 cur_vars->fmt_size = 0;
1015 if (cur_vars->fmt_buf)
1016 cur_vars->fmt_buf[0] = '\0';
1021 /******************************************************************************
1022 * Function: int CheckSaveSegment (int type, char **font_attr, int link_spec,
1023 * FormatVariables cur_vars)
1026 * type Specifies the segment type.
1027 * font_attr Specifies the resource list of quarks for the
1028 * font to associate with the segment.
1029 * link_spec Specifies the link specification for the
1032 * Returns: 0 if successful, -1 if errors.
1036 * Purpose: Checks 'cur_vars->fmt_size' for a non-zero value. If it is,
1037 * calls SaveSegment.
1039 *****************************************************************************/
1042 unsigned long seg_flags,
1043 _DtHelpFontHints *font_attr,
1045 FormatVariables *cur_vars)
1049 if (cur_vars->fmt_size)
1050 result = SaveStringAsSegments (cur_vars, seg_flags, font_attr, link_spec);
1055 /******************************************************************************
1056 * Function: void TerminateSegList (
1060 * Returns: 0 if successful, -1 if errors.
1062 * Purpose: Links the segments together.
1064 *****************************************************************************/
1071 _DtCvSegment *lastDisp = NULL;
1074 if (True == flag && 0 == seg_list->cnt && NULL != seg_list->list)
1076 free(seg_list->list);
1077 *seg_list = InitList;
1081 * set the next segment and display segment pointers.
1083 for (count = 1, pSeg = seg_list->list; count < seg_list->cnt;
1087 * link this segment to the next segment
1089 pSeg->next_seg = &(pSeg[1]);
1092 * is this a displayable segment?
1093 * If so, link it into the displayable list.
1095 if (_DtCvIsSegNoop(pSeg) || _DtCvIsSegRegion(pSeg)
1096 || _DtCvIsSegString(pSeg))
1099 * Is there a displayable segment yet?
1100 * If so, set its next displayable link to this segment.
1102 if (NULL != lastDisp)
1103 lastDisp->next_disp = pSeg;
1106 * this segment becomes the last displayable segment.
1114 if (NULL != pSeg && NULL != lastDisp
1115 && (_DtCvIsSegNoop(pSeg) || _DtCvIsSegRegion(pSeg)
1116 || _DtCvIsSegString(pSeg)))
1117 lastDisp->next_disp = pSeg;
1121 /******************************************************************************
1122 * Function: int InitStructure (FormatVariables *cur_vars,
1123 * char *rd_buf, int rd_size,
1126 * rd_buffer Specifies the buffer all reads use.
1127 * id_string Specifies the location ID to search for.
1129 * Returns: 0 if successful, -1 if errors.
1133 * Purpose: Attach formatting information to the structure that gets
1134 * passed around by, among other things, setting the global
1135 * variable 'cur_vars->rd_ptr' to 'rd_buffer', and
1136 * remembering the location id.
1138 *****************************************************************************/
1141 FormatVariables *cur_vars,
1142 _FrmtUiInfo *ui_info,
1146 cur_vars->ui_info = ui_info;
1147 cur_vars->rd_size = rd_size;
1148 cur_vars->rd_buf = rd_buf;
1149 cur_vars->rd_ptr = cur_vars->rd_buf;
1151 cur_vars->fmt_size = 0;
1152 if (cur_vars->fmt_buf)
1153 cur_vars->fmt_buf[0] = '\0';
1156 * allocate the link data base.
1158 cur_vars->my_links = _DtLinkDbCreate();
1159 if (NULL == cur_vars->my_links)
1165 /******************************************************************************
1166 * Function: int AppendToInfo (FormatVariables *cur_vars,
1167 * char **src, const char *scan_string)
1170 * src Specifies the source string to read.
1171 * Returns pointing at a special character,
1172 * an invalid character or the
1174 * scan_string Specifies the special characters to
1175 * look for in 'src'.
1177 * Returns: 0 if stopped on a special character.
1178 * 1 if found the end of string.
1179 * 2 if found an invalid character.
1184 * Purpose: Appends onto 'cur_vars->fmt_buf' the number of characters
1185 * found in 'src' that does not match any character in
1188 * Sets 'cur_vars->last_was_space' to false (assumes that one
1189 * of the special characters is a space).
1191 *****************************************************************************/
1194 FormatVariables *cur_vars,
1196 const char *scan_string )
1201 cur_vars->last_was_space = False;
1202 spnResult = _DtHelpCeStrcspn(*src, scan_string, cur_vars->cur_mb_max,
1206 if (_DtHelpCeAddStrToBuf(src,&(cur_vars->fmt_buf),&(cur_vars->fmt_size),
1207 &(cur_vars->fmt_buf_max),size,INFO_GROW) == -1)
1209 cur_vars->last_was_space = False;
1212 if (spnResult == -1)
1215 if (0 == size && 1 == spnResult)
1221 /******************************************************************************
1222 * Function: int AppendOctalToInfo (FormatVariables *cur_vars, char *src)
1225 * src Specifies the source string to read.
1227 * Returns: 0 if successful, -1 if errors.
1230 * CEErrorFormattingValue
1233 * Purpose: Convert the octal representation pointed to by 'src' and
1234 * change it into a character byte. The routine only allows
1235 * a number between the values 1-255.
1237 * Append the byte onto the global variable 'Info'.
1238 * Set 'cur_vars->last_was_space' to false.
1240 *****************************************************************************/
1243 FormatVariables *cur_vars,
1249 if (((int)strlen(src)) < 4 && cur_vars->my_file != NULL)
1251 if (GetNextBuffer (cur_vars) == -1)
1254 src = cur_vars->rd_ptr;
1257 if (_DtHelpCeAddOctalToBuf(src,&(cur_vars->fmt_buf),&(cur_vars->fmt_size),
1258 &(cur_vars->fmt_buf_max),INFO_GROW) == -1)
1261 cur_vars->last_was_space = False;
1266 /******************************************************************************
1267 * Function: int AppendCharToInfo (FormatVariables *cur_vars, char **src)
1270 * src Specifies the source string to read.
1271 * Returns pointing at the next character
1274 * Returns: 0 if successful, -1 if errors.
1278 * Purpose: Appends the character pointed to by 'src' onto the
1279 * global buffer 'Info', updating the pointers associated
1280 * with 'Info' accordingly.
1282 * Sets 'cur_vars->last_was_space' to False;
1284 *****************************************************************************/ static int
1286 FormatVariables *cur_vars,
1289 cur_vars->last_was_space = False;
1290 return (_DtHelpCeAddCharToBuf (src, &(cur_vars->fmt_buf),
1291 &(cur_vars->fmt_size),
1292 &(cur_vars->fmt_buf_max), INFO_GROW));
1295 /******************************************************************************
1296 * Function: int AppendSpaceToInfo (char **src, int type)
1299 * src Specifies the source string to read.
1300 * Returns pointing at the next character
1302 * type Specifies the type of the segment being
1305 * Returns: 0 if successful, -1 if errors.
1309 * Purpose: Appends a space onto the global buffer 'Info', if
1310 * the variable 'cur_vars->last_was_space' is false or the
1311 * static string flag is set in 'type'.
1313 * Sets 'cur_vars->last_was_space' to true.
1315 *****************************************************************************/
1318 FormatVariables *cur_vars,
1320 _DtCvFrmtOption type)
1323 char *space = (char *) SpaceString;
1325 if (!cur_vars->last_was_space || _DtCvLITERAL == type) {
1327 result = _DtHelpCeAddCharToBuf (&space, &(cur_vars->fmt_buf),
1328 &(cur_vars->fmt_size),
1329 &(cur_vars->fmt_buf_max), INFO_GROW);
1330 cur_vars->last_was_space = True;
1338 /******************************************************************************
1339 * Function: int FindEndMarker (FormatVariables *cur_vars)
1341 * Returns: 0 if successful, -1 if errors.
1345 * Purpose: Wrapper around __DtHelpFindEndMarker.
1346 * Find the '>' token.
1348 *****************************************************************************/
1351 FormatVariables *cur_vars)
1353 return (_DtHelpCeGetCcdfEndMark (cur_vars->my_file, cur_vars->rd_buf,
1354 &(cur_vars->rd_ptr),cur_vars->rd_size,1));
1357 /******************************************************************************
1358 * Function: int GetNextBuffer (FormatVariables *cur_vars)
1360 * Returns: 0 if successful, -1 if errors.
1364 * Purpose: Wrapper around __DtHelpGetNextBuffer.
1365 * Read the next buffer's worth of information.
1367 *****************************************************************************/
1370 FormatVariables *cur_vars)
1372 cur_vars->rd_flag = _DtHelpCeGetNxtBuf (cur_vars->my_file,
1374 &(cur_vars->rd_ptr),
1376 return (cur_vars->rd_flag);
1379 /******************************************************************************
1380 * Function: int SaveNewLine (FormatVariables *cur_vars, int cur_type,
1385 * cur_cmd Specifies the type of segment being processed.
1386 * font_attr Specifies the list of font quarks associated
1387 * with the current segment.
1388 * link_spec Specifies the hypertext link specification
1389 * associated with the current segment.
1391 * Returns: 0 if successful, -1 if errors.
1395 * Purpose: Sets the newline flag on a segment and saves it by calling
1396 * 'SaveStringAsSegments'.
1397 * If the current segment is non-null, save it with the
1399 * Otherwise if there are no segments saved, create one with the
1400 * a type of CE_old_NOOP.
1401 * Otherwise there are other segments, but the current segment is
1402 * empty. Look back at the previous segment.
1403 * If it doesn't have the newline set on it,
1404 * its newline flag is enabled.
1405 * Otherwise the previous segment had the newline set, so
1406 * create another segment just like it with a
1407 * null length and the newline flag set (if the
1408 * previous segment is a graphic, create it
1409 * with a type of CE_old_NOOP).
1411 *****************************************************************************/
1414 FormatVariables *cur_vars,
1416 _DtHelpFontHints *font_attr,
1423 * If there is information in the buffer, save it with the newline flag
1425 if (cur_vars->fmt_size)
1426 result = SaveStringAsSegments (cur_vars, _DtCvSetTypeToNewLine (cur_type),
1427 font_attr, link_spec);
1429 * check to see if there is any segments. If not create a new one
1430 * with the type NOOP.
1432 else if (0 == cur_vars->my_list.cnt)
1433 result = SaveStringAsSegments (cur_vars, _DtCvSetTypeToNewLine(_DtCvNOOP),
1434 font_attr, link_spec);
1436 * There was not any information in the buffer and we have one or
1437 * more segments. Try placing the flag on the previous segment.
1441 pSeg = NextAvailSeg(cur_vars->my_list);
1445 * Does the previous segment already have a newline flag?
1446 * If so, create a new NOOP segment with the newline set.
1448 if (_DtCvIsSegNewLine (pSeg))
1449 result = SaveStringAsSegments (cur_vars, _DtCvSetTypeToNewLine (_DtCvNOOP),
1450 font_attr, link_spec);
1452 pSeg->type = _DtCvSetTypeToNewLine (pSeg->type);
1455 cur_vars->last_was_space = True;
1459 /******************************************************************************
1460 * Function: int CreateSaveGraphic (FormatVariables cur_vars,
1462 * char *file_name, int link_spec )
1465 * type Specifies the type of graphic segment
1467 * file_name Specifies the file name of the graphic.
1468 * link_spec Specifies the hypertext link specification
1469 * associated with the graphic.
1471 * Returns: 0 if successful, -1 if errors.
1473 * Purpose: Save a graphic segment.
1474 * If 'file_name' is not an absolute path, resolve it to
1475 * a full path by using the path to the volume.
1477 *****************************************************************************/
1480 FormatVariables *cur_vars,
1486 _DtCvSegment *cvRegion;
1488 if (CheckList (&(cur_vars->my_list), 1, 1) == -1)
1492 * create the path to the file name
1494 if (*file_name == '/')
1495 fullName = strdup (file_name);
1498 fullName = (char *) malloc (strlen (cur_vars->my_path) +
1499 strlen (file_name) + 2);
1500 if (fullName == NULL)
1503 strcpy (fullName, cur_vars->my_path);
1504 strcat (fullName, "/");
1505 strcat (fullName, file_name);
1509 * load the graphic into the current segment
1511 cvRegion = NextAvailSeg(cur_vars->my_list);
1512 if (NULL != cur_vars->ui_info->load_graphic &&
1513 (*(cur_vars->ui_info->load_graphic))(
1514 cur_vars->ui_info->client_data,
1520 &(_DtCvWidthOfRegionSeg(cvRegion)),
1521 &(_DtCvHeightOfRegionSeg(cvRegion)),
1522 &(_DtCvInfoOfRegionSeg(cvRegion))) == 0)
1525 * set the type and index.
1526 * and indicate that this segment has been used.
1528 _DtCvAscentOfRegionSeg(cvRegion) = -1;
1529 cvRegion->type = _DtCvSetTypeToRegion(type);
1530 cvRegion->link_idx = link_spec;
1531 cur_vars->my_list.cnt++;
1535 * free the file name path
1542 /******************************************************************************
1543 * Function: int ChangeFont (int whichOne, int segType,
1544 * char **font_attr, int linkspec,
1545 * FormatVariables *cur_vars, int flags)
1548 * whichOne Specifies the index into 'font_attr' to
1550 * segType Specifies the type of segment currently
1552 * font_attr Specifies the list of font quarks associated
1553 * with the current segment.
1554 * linkspec Specifies the hypertext link specification
1555 * associated with the segment.
1556 * flags Specifies the routines flags.
1558 * Returns: The value returned from 'routine' if successful, -1 if errors.
1562 * Purpose: Saves any segment with the current font type and
1563 * process the next segment using the new font type.
1565 *****************************************************************************/
1569 unsigned long seg_flags,
1570 _DtCvFrmtOption frmt_type,
1571 _DtHelpFontHints *font_attr,
1573 FormatVariables *cur_vars,
1574 ProcessState cur_state,
1580 int oldMb_Len = cur_vars->cur_mb_max;
1582 _DtHelpFontHints oldFontStruct;
1584 if (CheckSaveSegment (seg_flags, font_attr, linkspec, cur_vars) == -1)
1587 oldFontStruct = *font_attr;
1589 if (GetStringParameter(cur_vars, _DtCvTRUE, _DtCvTRUE, _DtCvFALSE,
1590 _DtCvFALSE, &fontString) == -1)
1594 * Is this font change allowed to go through?
1596 if (!(fnt_flag & (1 << whichOne)))
1600 case _CEFONT_SPACING:
1601 font_attr->spacing = _DtHelpFontSpacingProp;
1602 if (fontString[0] == 'm')
1603 font_attr->spacing = _DtHelpFontSpacingMono;
1606 font_attr->pointsz = atoi(fontString);
1609 font_attr->slant = _DtHelpFontSlantRoman;
1610 if (fontString[0] == 'i')
1611 font_attr->slant = _DtHelpFontSlantItalic;
1613 case _CEFONT_WEIGHT:
1614 font_attr->weight = _DtHelpFontWeightMedium;
1615 if (fontString[0] == 'b')
1616 font_attr->weight = _DtHelpFontWeightBold;
1619 font_attr->style = _DtHelpFontStyleSanSerif;
1620 if (*fontString == 's')
1622 if (fontString[1] == 'e')
1623 font_attr->style = _DtHelpFontStyleSerif;
1624 else if (fontString[1] == 'y')
1625 font_attr->style = _DtHelpFontStyleSymbol;
1628 case _CEFONT_CHAR_SET:
1630 * Change to the correct mb_len.
1632 GetMbLen(cur_vars, fontString,
1633 &(_DtHelpFontHintsLang(*font_attr)),
1634 &(_DtHelpFontHintsCharSet(*font_attr)));
1639 result = FindEndMarker (cur_vars);
1641 result = Parse (CCDF_FONT_CMD, cur_state, cur_vars,
1642 seg_flags, frmt_type,
1643 font_attr, linkspec,
1644 Specials, flags, ret_on_nl, fnt_flag);
1646 * free the lanugage and code sets strings.
1648 if (!(fnt_flag & (1 << whichOne)) && whichOne == _CEFONT_CHAR_SET)
1650 free(_DtHelpFontHintsLang(*font_attr));
1651 free(_DtHelpFontHintsCharSet(*font_attr));
1655 * reset the old quark
1656 * if necessary, reset the MB_LEN
1658 *font_attr = oldFontStruct;
1659 cur_vars->cur_mb_max = oldMb_Len;
1673 /******************************************************************************
1674 * Function: int SkipToNextToken (FormatVariables *cur_vars, int flag)
1677 * flag Specifies whether the routine returns a -1
1678 * if '>' is the next token.
1680 * Returns: The value from __DtHelpSkipToNextToken:
1681 * -1 If problems encountered finding the next token.
1682 * 0 If no problems encountered finding the next token.
1683 * 1 If flag is true and the next token is a > character.
1687 * Purpose: Wrapper around __DtHelpSkipToNextToken.
1688 * Skip the current string and any spaces or newline
1689 * characters after it.
1691 *****************************************************************************/
1694 FormatVariables *cur_vars,
1697 return (_DtHelpCeSkipToNextCcdfToken (cur_vars->my_file, cur_vars->rd_buf,
1698 cur_vars->rd_size, 1, &(cur_vars->rd_ptr), flag));
1701 /******************************************************************************
1702 * Function: int GetStringParameter (FormatVariables *cur_vars,
1703 * int flag, int eat_escape,
1704 * int ignore_quotes, int less_test,
1705 * char **ret_string)
1708 * flag Specifies whether the routine returns
1709 * a -1 if '>' is the next token.
1710 * eat_secape Specifies whether the backslash is not
1711 * placed in the returned string.
1712 * True - it is skipped.
1713 * False - it is saved in 'ret_string'.
1714 * ignore_quotes Specifies whether quotes are to be included
1715 * in the returned string.
1716 * less_test Specifies whether the routine should
1717 * stop when it finds a '<' character.
1718 * ret_string Returns the string found.
1719 * If NULL, throws the information away.
1721 * Returns: The value from __DtHelpFormatGetStringParameter:
1722 * -1 If problems encountered.
1723 * 0 If no problems encountered getting the string.
1724 * 1 If flag is false and the no string was found.
1728 * Purpose: Wrapper around __DtHelpFormatGetStringParameter.
1729 * Skip the current string and any spaces or newline
1730 * characters after it. Get the next quoted/unquoted
1731 * string after that.
1733 *****************************************************************************/
1736 FormatVariables *cur_vars,
1738 _DtCvValue eat_escape,
1739 _DtCvValue ignore_quotes,
1740 _DtCvValue less_test,
1743 return (_DtHelpCeGetCcdfStrParam (cur_vars->my_file,
1744 cur_vars->rd_buf, cur_vars->rd_size, cur_vars->cur_mb_max,
1745 &(cur_vars->rd_ptr),
1746 flag, eat_escape, ignore_quotes, less_test, ret_string));
1749 /******************************************************************************
1750 * Function: int GetValueParameter (FormatVariables *cur_vars,
1751 * int flag, int *ret_value)
1754 * flag Specifies whether the routine returns
1755 * a -2 if '>' is the next token.
1756 * ret_value Returns the atoi conversion
1757 * of the string found.
1759 * Returns: The value from __DtHelpFormatGetValueParameter:
1760 * -1 If problems encountered.
1761 * 0 If no problems encountered getting the string.
1762 * -2 If flag is true and the next token is a >
1767 * Purpose: Wrapper around __DtHelpFormatGetValueParameter.
1768 * Skip the current string and any spaces or newline
1769 * characters after it. Process the next string as
1772 *****************************************************************************/
1775 FormatVariables *cur_vars,
1779 return (_DtHelpCeGetCcdfValueParam (cur_vars->my_file, cur_vars->rd_buf,
1781 &(cur_vars->rd_ptr), flag, cur_vars->cur_mb_max,
1785 /******************************************************************************
1786 * Function: int GetParagraphParameters (FormatVariables *cur_vars,
1787 * int seg_type, int graphic_type,
1788 * char **label, char **file_name,
1789 * char **link_string, int *link_type,
1790 * char **description)
1793 * seg_type Specifies the default type for the segment.
1794 * Returns the new type for the segment.
1795 * graphic_type Specifies the default type for a graphic
1796 * if a justified graphic is
1797 * encountered in the paragraph options.
1798 * Returns the new type for a graphic
1799 * if a justified graphic was
1800 * encountered in the paragraph options.
1801 * label Returns the label if one is specified
1802 * in the paragraph options.
1803 * file_name Returns the file name of a graphic if
1804 * one is specified in the paragraph
1806 * link_string Returns the hypertext specification if one
1807 * is specified in the paragraph options.
1808 * link_type Returns the hypertext link type if one is
1810 * description Returns the hypertext description if one
1813 * Returns: 0 if successfult, -1 if errors.
1817 * Purpose: Wrapper around __DtHelpParagraphGetOptions.
1818 * Process the options found in <PARAGRAPH> syntax.
1819 * Test to see if the id specified in the <PARAGRAPH>
1820 * is the one we are looking at.
1822 *****************************************************************************/
1824 GetParagraphParameters(
1825 FormatVariables *cur_vars,
1827 _DtCvFrmtOption *frmt_type,
1828 _DtCvFrmtOption *gpos,
1838 int optionCount = 0;
1840 char *tmpString = NULL;
1843 * initialize string variables if valid addresses
1848 *description = NULL;
1850 *gpos = _DtCvJUSTIFY_LEFT;
1854 while (False == done && result != -1)
1856 if (SkipToNextToken (cur_vars, _DtCvFALSE) == -1)
1859 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
1862 * end of paragraph spec
1865 (cur_vars->rd_ptr)++;
1873 if (GetValueParameter (cur_vars, _DtCvFALSE, &value) == -1)
1876 _DtCvContainerBMarginOfSeg(para) = 0;
1877 if (value > 0 && 0 < cur_vars->ui_info->line_height)
1878 _DtCvContainerBMarginOfSeg(para) = value *
1879 (cur_vars->ui_info->line_height / 2);
1886 if (GetValueParameter (cur_vars, _DtCvFALSE, &value) == -1)
1889 _DtCvContainerTMarginOfSeg(para) = 0;
1890 if (value > 0 && 0 < cur_vars->ui_info->line_height)
1891 _DtCvContainerTMarginOfSeg(para) = value *
1892 (cur_vars->ui_info->line_height / 2);
1896 * description [string | "string" | 'string']
1899 result = GetStringParameter(cur_vars, _DtCvTRUE, _DtCvTRUE,
1900 _DtCvFALSE, _DtCvFALSE, description);
1907 if (GetValueParameter (cur_vars, _DtCvFALSE, &value) == -1)
1910 _DtCvContainerFMarginOfSeg(para) =
1911 value * cur_vars->ui_info->avg_char;
1915 * glink [string | "string" | 'string']
1923 * to determine what token this is we must look at the
1926 (cur_vars->rd_ptr)++;
1929 * do we need to read more?
1931 if (*(cur_vars->rd_ptr) == '\0'
1932 && GetNextBuffer(cur_vars) == -1)
1936 * check for the next permutation
1938 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
1941 * glink [string | "string" | 'string']
1944 result = GetStringParameter(cur_vars, _DtCvTRUE,
1945 _DtCvTRUE, _DtCvFALSE, _DtCvFALSE, glink);
1952 result = GetStringParameter(cur_vars, _DtCvTRUE,
1953 _DtCvTRUE, _DtCvFALSE, _DtCvFALSE, &tmpString);
1955 if (-1 != result && _DtCvToLower (*tmpString) == 'r')
1956 *gpos = _DtCvJUSTIFY_RIGHT;
1966 result = GetStringParameter(cur_vars, _DtCvTRUE,
1967 _DtCvTRUE, _DtCvFALSE, _DtCvFALSE, file_name);
1974 if (GetValueParameter(cur_vars,_DtCvFALSE,&value) == -1
1978 *gspace = value * cur_vars->ui_info->avg_char;
1985 if (GetValueParameter(cur_vars,_DtCvFALSE,glinktype) == -1
2000 if (GetStringParameter(cur_vars, _DtCvTRUE, _DtCvTRUE,
2001 _DtCvFALSE, _DtCvFALSE, &tmpString) == -1)
2004 _DtCvContainerIdOfSeg(para) = tmpString;
2008 * label [string | "string" | 'string']
2013 * to determine what token this is we must look at the
2014 * second and possibly the third characters.
2016 (cur_vars->rd_ptr)++;
2019 * do we need to read more?
2021 if (*(cur_vars->rd_ptr) == '\0'
2022 && GetNextBuffer(cur_vars) == -1)
2026 * check for the next permutation
2028 if (_DtCvToLower(*(cur_vars->rd_ptr)) == 'a')
2033 if (GetStringParameter(cur_vars, _DtCvTRUE, _DtCvFALSE,
2034 _DtCvFALSE, _DtCvFALSE, &tmpString) == -1)
2038 * If we got a label process it.
2040 if (ret_label == NULL || *ret_label)
2043 * we've already processed a label!
2050 *ret_label = tmpString;
2052 else if (_DtCvToLower(*(cur_vars->rd_ptr)) == 'e')
2057 if (GetValueParameter (cur_vars, _DtCvFALSE, &value) == -1)
2060 _DtCvContainerLMarginOfSeg(para) =
2061 value * cur_vars->ui_info->avg_char;
2071 _DtCvContainerTypeOfSeg(para) = _DtCvLITERAL;
2072 *frmt_type = _DtCvLITERAL;
2079 if (GetValueParameter (cur_vars, _DtCvFALSE, &value) == -1)
2082 _DtCvContainerRMarginOfSeg(para) =
2083 value * cur_vars->ui_info->avg_char;
2090 _DtCvContainerTypeOfSeg(para) = _DtCvDYNAMIC;
2091 *frmt_type = _DtCvDYNAMIC;
2095 * Found an option we don't understand.
2104 * adjust the first margin to correctly indicate the offset from the
2105 * left margin. In the old CCDF, the first margin indicated left plus
2106 * and additional indent. For the new Canvas Engine, it is suppose
2107 * to be an addition on top of the left margin.
2109 _DtCvContainerFMarginOfSeg(para) = _DtCvContainerLMarginOfSeg(para) -
2110 _DtCvContainerFMarginOfSeg(para);
2114 return (optionCount - 1);
2116 } /* End GetParagraphParameters */
2118 /******************************************************************************
2119 * Function: int FlowingParagraph (
2127 * Purpose: Process the <PARAGRAPH> specification.
2129 *****************************************************************************/
2132 FormatVariables *cur_vars,
2133 ProcessState cur_state,
2134 _DtCvFrmtOption frmt_flags,
2139 _DtCvFrmtOption gpos,
2142 _DtHelpFontHints *font_attr)
2146 _DtCvSegment *graphSeg;
2147 _DtCvSegment *bodySeg;
2148 SegList flowList = InitList;
2151 * reset current list
2153 cur_vars->my_list = InitList;
2156 * create two containers.
2158 if (0 == CheckList(&(flowList), 2, 2))
2161 * point to the containers for the graphic and body.
2163 graphSeg = flowList.list;
2164 bodySeg = flowList.list;
2168 * set the bottom margins to zero.
2170 graphSeg->type = _DtCvSetTypeToContainer(graphSeg->type);
2171 bodySeg->type = _DtCvSetTypeToContainer(bodySeg->type);
2172 _DtCvContainerBMarginOfSeg(graphSeg) = 0;
2173 _DtCvContainerBMarginOfSeg(bodySeg) = 0;
2176 * so the first segment is the container for the graphic.
2177 * set the controller flag and values.
2179 graphSeg->type = _DtCvSetTypeToController(graphSeg->type);
2180 _DtCvContainerFlowOfSeg(graphSeg) = _DtCvWRAP;
2181 _DtCvContainerPercentOfSeg(graphSeg) = 0;
2182 _DtCvContainerOrientOfSeg(graphSeg) = gpos;
2183 if (_DtCvJUSTIFY_LEFT == gpos)
2185 _DtCvContainerJustifyOfSeg(graphSeg) = gpos;
2186 _DtCvContainerRMarginOfSeg(graphSeg) = gspace;
2190 _DtCvContainerJustifyOfSeg(graphSeg) = gpos;
2191 _DtCvContainerLMarginOfSeg(graphSeg) = gspace;
2195 * mark the first segment as used.
2200 * check for hypertext link.
2203 type = _DtCvHYPER_TEXT;
2206 * re-set the segment list and create the graphic.
2208 if (0 == CreateSaveGraphic(cur_vars, type, file_name, link_idx))
2211 * so the first segment in cur_vars is a region.
2212 * attach it to the graphic container.
2214 _DtCvContainerListOfSeg(graphSeg) = cur_vars->my_list.list;
2217 * now process the following information as the body of
2218 * the paragraph as the list for the non-controller
2221 cur_vars->my_list = InitList;
2222 if (-1 != Parse (CCDF_PARAGRAPH_CMD, cur_state, cur_vars,
2226 ret_on_nl, fnt_flag))
2229 * establish the links between the segments
2231 TerminateSegList(&(cur_vars->my_list), True);
2234 * if there was a segment list generated,
2235 * attach the it to the non-controller
2236 * container and mark it as used.
2238 if (NULL != cur_vars->my_list.list)
2240 _DtCvContainerListOfSeg(bodySeg) = cur_vars->my_list.list;
2248 cur_vars->my_list = flowList;
2249 TerminateSegList(&(cur_vars->my_list), True);
2253 /******************************************************************************
2254 * Function: int ProcessParagraph (
2262 * Purpose: Process the <PARAGRAPH> specification.
2264 *****************************************************************************/
2267 FormatVariables *cur_vars,
2268 ProcessState cur_state,
2272 int labelFnd = False;
2273 int allowed = ~(CCDF_TOPIC_CMD | CCDF_TITLE_CMD | CCDF_ABBREV_CMD);
2274 int oldMbLenMax = cur_vars->cur_mb_max;
2277 _DtCvUnit gspace = 0;
2278 char *glinkSpec = NULL;
2280 char *fileName = NULL;
2281 char *description = NULL;
2284 ProcessState myState = NormalState;
2285 _DtCvFrmtOption gpos;
2286 _DtCvFrmtOption frmtType = _DtCvDYNAMIC;
2287 _DtCvSegment *paraSeg;
2288 _DtCvSegment *labelSeg = NULL;
2289 _DtCvSegment *col1 = NULL;
2290 _DtCvSegment *col2 = NULL;
2291 _DtCvSegment **childList;
2293 SegList tableList = InitList;
2294 _DtHelpFontHints fontAttrs;
2297 * remember the old font list.
2298 * initialize the font quark list
2299 * and use the char set specified for this topic.
2301 _DtHelpCeCopyDefFontAttrList (&fontAttrs);
2302 cur_vars->cur_mb_max = cur_vars->topic_mb_max;
2303 _DtHelpFontHintsLang(fontAttrs) = cur_vars->topic_lang;
2304 _DtHelpFontHintsCharSet(fontAttrs) = cur_vars->topic_char_set;
2307 * Make next segment in my parent's list for a container for this
2310 if (-1 == CheckSegList(cur_vars))
2314 * remember the parent list
2315 * make sure the defaults are set
2317 oldList = cur_vars->my_list;
2318 paraSeg = NextAvailSeg(cur_vars->my_list);
2319 paraSeg->handle.container = DefContainer;
2320 paraSeg->type = _DtCvSetTypeToContainer(paraSeg->type);
2321 _DtCvContainerLeadingOfSeg(paraSeg) = cur_vars->ui_info->leading;
2322 cur_vars->my_list = InitList;
2325 * get the parameters on the paragraph
2326 * and set the default for the bottom.
2328 result = GetParagraphParameters (cur_vars, paraSeg, &frmtType,
2329 &gpos, &glinkSpec, &glinktype, &gspace,
2330 &label, &fileName, &description);
2333 * for lists, we will inherit our parent's bottom margin
2334 * when we return to the loop processing the list. Therefore,
2335 * set our bottom margin to zero if we are part of a label body.
2337 if (0 == result && LabelBody == cur_state)
2338 _DtCvContainerBMarginOfSeg(paraSeg) = 0;
2339 else if (result > 0)
2343 * check for a label specification. Either as a 'label' parameter
2344 * or a the <LABEL> command.
2349 * check for the parameter
2353 FormatVariables oldVars = *cur_vars;
2355 cur_vars->rd_buf = label;
2356 cur_vars->rd_flag = 0;
2357 cur_vars->rd_ptr = label;
2358 cur_vars->my_file = NULL;
2360 result = Parse (CCDF_LABEL_CMD, NormalState, cur_vars,
2364 (CCDF_FONT_CMD | CCDF_OCTAL_CMD),
2368 result = CheckSaveSegment (_DtCvSTRING, &fontAttrs,
2371 TerminateSegList(&(cur_vars->my_list), True);
2372 cur_vars->rd_buf = oldVars.rd_buf;
2373 cur_vars->rd_flag = oldVars.rd_flag;
2374 cur_vars->rd_ptr = oldVars.rd_ptr;
2375 cur_vars->my_file = oldVars.my_file;
2376 cur_vars->last_was_space = True;
2378 labelSeg = cur_vars->my_list.list;
2379 cur_vars->my_list = InitList;
2383 * check for the command.
2385 else if (0 == _DtHelpCeCheckNextCcdfCmd("lab", cur_vars->my_file,
2387 cur_vars->rd_size, 1,
2388 &(cur_vars->rd_ptr)))
2390 result = ProcessLabelCmd(cur_vars, 0, frmtType,
2392 allowed, False, fnt_flag,
2398 * if a label was processed, create the containers for it.
2400 if (-1 != result && True == labelFnd)
2403 * set the correct state.
2405 myState = LabelBody;
2408 * create containers for the label and it's body
2410 result = CheckList(&tableList, 2, 2);
2414 * set the top and bottom margins on both the child
2415 * containers (so they are the same) to reflect
2416 * the list's before/after values.
2419 * set the pointer to the first column
2420 * overwrite the left and right margin values.
2422 col1 = NextAvailSeg(tableList);
2423 col1->type = _DtCvSetTypeToContainer(col1->type);
2424 _DtCvContainerTMarginOfSeg(col1) =
2425 _DtCvContainerTMarginOfSeg(paraSeg);
2426 _DtCvContainerBMarginOfSeg(col1) =
2427 _DtCvContainerBMarginOfSeg(paraSeg);
2428 _DtCvContainerLMarginOfSeg(col1) = 0;
2429 _DtCvContainerRMarginOfSeg(col1) = cur_vars->ui_info->avg_char;
2433 * set the pointer for the second column
2434 * and set the top/bottom values.
2436 col2 = NextAvailSeg(tableList);
2437 col2->type = _DtCvSetTypeToContainer(col2->type);
2438 _DtCvContainerTMarginOfSeg(col2) =
2439 _DtCvContainerTMarginOfSeg(paraSeg);
2440 _DtCvContainerBMarginOfSeg(col2) =
2441 _DtCvContainerBMarginOfSeg(paraSeg);
2445 * create an id for this label
2447 sprintf(numChar, "%d", cur_vars->cell_cnt++);
2448 _DtCvContainerIdOfSeg(col1) = (char *) malloc (
2449 strlen("&CCDF_RES_") + strlen(numChar) + 1);
2450 if (NULL != _DtCvContainerIdOfSeg(col1))
2453 * copy over the id and attach the list.
2455 strcpy(_DtCvContainerIdOfSeg(col1), "&CCDF_RES_");
2456 strcat(_DtCvContainerIdOfSeg(col1), numChar);
2457 _DtCvContainerListOfSeg(col1) = labelSeg;
2460 * set the id for the second column.
2462 sprintf(numChar, "%d", cur_vars->cell_cnt++);
2463 _DtCvContainerIdOfSeg(col2) = (char *) malloc (
2464 strlen("&CCDF_RES_") + strlen(numChar) + 1);
2465 if (NULL != _DtCvContainerIdOfSeg(col2))
2467 strcpy(_DtCvContainerIdOfSeg(col2), "&CCDF_RES_");
2468 strcat(_DtCvContainerIdOfSeg(col2), numChar);
2480 * disallow labels from here on out. Either one was found and processed
2483 allowed &= (~(CCDF_LABEL_CMD));
2486 * Now check and process the graphic specification.
2491 * initialize the segment list for the children of the paragraph.
2493 cur_vars->my_list = InitList;
2496 * check for a graphic in the specification.
2497 * If so, then we need to create, as the list for the
2498 * paragraph container, two containers; one container
2499 * that is a controller and has the graphic and the
2500 * other contains the rest of the content of the
2503 * First, create the link index for the graphic.
2505 if (NULL != glinkSpec)
2508 * but if there isn't a graphic, throw away the link
2509 * specifications since they are useless!
2511 if (NULL != fileName && strlen (glinkSpec))
2513 linkIndex = _DtLinkDbAddLink (cur_vars->my_links,
2516 ReturnLinkType(glinktype, glinkSpec),
2517 ReturnLinkWinHint(glinktype),
2521 * had problems creating the link index, bail
2523 if (linkIndex == -1)
2529 * now create the graphic and process the graphic body..
2530 * or just process the rest of the paragraph....
2534 if (NULL != fileName)
2535 result = FlowingParagraph(cur_vars,
2540 gpos, gspace, fileName,
2544 result = Parse (CCDF_PARAGRAPH_CMD, myState, cur_vars,
2552 * establish the links
2554 TerminateSegList (&(cur_vars->my_list), True);
2562 _DtCvFrmtOption *colJ;
2564 if (True == labelFnd)
2566 char *colW1 = "1"; /* default bulletted list */
2567 char *colW2 = "99,0,98"; /* default bulletted list */
2571 * set the body of the label in it's container.
2573 _DtCvContainerListOfSeg(col2) = cur_vars->my_list.list;
2576 * figure out which column widths should be used.
2578 if (14 * cur_vars->ui_info->avg_char
2579 == _DtCvContainerLMarginOfSeg(paraSeg))
2585 else if (3 * cur_vars->ui_info->avg_char
2586 == _DtCvContainerLMarginOfSeg(paraSeg))
2589 else if (0 == _DtCvContainerLMarginOfSeg(paraSeg))
2594 * create the column width strings.
2597 colW = (char **) _DtCvAddPtrToArray((void **) colW,
2598 ((void *) strdup(colW1)));
2600 colW = (char **) _DtCvAddPtrToArray((void **) colW,
2601 ((void *) strdup (colW2)));
2604 * create the array for column justification.
2606 colJ = (_DtCvFrmtOption *) malloc (sizeof(_DtCvFrmtOption) * 2);
2609 colJ[0] = _DtCvJUSTIFY_LEFT;
2610 colJ[1] = _DtCvJUSTIFY_LEFT;
2614 * set this segment's type to a table and fill in all
2615 * the relevant information.
2617 paraSeg->type = _DtCvTABLE;
2618 _DtCvNumColsOfTableSeg(paraSeg) = 2;
2619 _DtCvColWOfTableSeg(paraSeg) = colW;
2620 _DtCvColJustifyOfTableSeg(paraSeg) = colJ;
2621 _DtCvJustifyCharsOfTableSeg(paraSeg) = NULL;
2624 * now create the list of ids in this table.
2626 ids = (char *) malloc (
2627 strlen(_DtCvContainerIdOfSeg(col1)) +
2628 strlen(_DtCvContainerIdOfSeg(col2)) + 2);
2631 strcpy(ids, _DtCvContainerIdOfSeg(col1));
2633 strcat(ids, _DtCvContainerIdOfSeg(col2));
2635 _DtCvCellIdsOfTableSeg(paraSeg) = NULL;
2636 _DtCvCellIdsOfTableSeg(paraSeg) = (char **)
2638 (void **) _DtCvCellIdsOfTableSeg(paraSeg),
2642 * now create the list of cells in the table.
2644 _DtCvCellsOfTableSeg(paraSeg) = NULL;
2645 _DtCvCellsOfTableSeg(paraSeg) = (_DtCvSegment **)
2647 (void **) _DtCvCellsOfTableSeg(paraSeg),
2649 if (NULL != _DtCvCellsOfTableSeg(paraSeg))
2650 _DtCvCellsOfTableSeg(paraSeg) = (_DtCvSegment **)
2652 (void **) _DtCvCellsOfTableSeg(paraSeg),
2655 if (NULL == colW || NULL == colJ || NULL == ids
2656 || NULL == _DtCvCellIdsOfTableSeg(paraSeg)
2657 || NULL == _DtCvCellsOfTableSeg(paraSeg))
2665 * attach the list to my container.
2667 _DtCvContainerListOfSeg(paraSeg) = cur_vars->my_list.list;
2670 * consolidate any table children I have.
2672 for (pSeg = cur_vars->my_list.list, labelSeg = NULL;
2673 -1 != result && NULL != pSeg;
2674 pSeg = pSeg->next_seg)
2676 if (_DtCvIsSegTable(pSeg))
2678 if (NULL != labelSeg)
2681 * bypass this segment since it will no
2682 * longer be 'used' by consolidating it
2683 * with another label set.
2685 labelSeg->next_seg = pSeg->next_seg;
2688 * free the other justification and width info.
2690 free((void *) _DtCvColJustifyOfTableSeg(pSeg));
2691 colW = _DtCvColWOfTableSeg(pSeg);
2694 free(_DtCvColWOfTableSeg(pSeg));
2697 * add the segments to the list
2699 childList = _DtCvCellsOfTableSeg(pSeg);
2700 _DtCvCellsOfTableSeg(labelSeg) = (_DtCvSegment **)
2702 (void **) _DtCvCellsOfTableSeg(labelSeg),
2705 if (NULL != _DtCvCellsOfTableSeg(labelSeg))
2706 _DtCvCellsOfTableSeg(labelSeg) = (_DtCvSegment **)
2708 (void **)_DtCvCellsOfTableSeg(labelSeg),
2710 free((void *) _DtCvCellsOfTableSeg(pSeg));
2713 * add the ids to the list
2715 _DtCvCellIdsOfTableSeg(labelSeg) = (char **)
2717 (void **)_DtCvCellIdsOfTableSeg(labelSeg),
2718 (void *)(*(_DtCvCellIdsOfTableSeg(pSeg))));
2720 free((void *) _DtCvCellIdsOfTableSeg(pSeg));
2722 if (NULL == _DtCvCellIdsOfTableSeg(labelSeg)
2723 || NULL == _DtCvCellsOfTableSeg(labelSeg))
2729 * this segment becomes the segment holding
2730 * the consolidated table.
2743 * restore the font MB_CUR_MAX
2745 cur_vars->cur_mb_max = oldMbLenMax;
2748 * free all the strings
2752 if (fileName != NULL)
2756 * free the linkSpec and description,
2758 if (NULL != description)
2760 if (NULL != glinkSpec)
2767 cur_vars->my_list = oldList;
2768 cur_vars->last_was_space = True;
2771 } /* End ProcessParagraph */
2773 /******************************************************************************
2774 * Function: int ProcessHypertext (
2775 * FormatVariables *cur_vars, int segType,
2776 * char **font_attr, int flags )
2779 * segType Specifies the type of segment currently
2781 * font_attr Specifies the list of font quarks to
2782 * associate with the string.
2783 * flags Specifies the formatting commands allowed.
2785 * Returns: 0 if successful, -1 if errors.
2789 * Purpose: Process the <LINK> specification.
2791 *****************************************************************************/
2794 FormatVariables *cur_vars,
2795 ProcessState cur_state,
2796 unsigned long seg_flags,
2797 _DtCvFrmtOption frmt_type,
2798 _DtHelpFontHints *font_attr,
2806 char *description = NULL;
2807 char *hyperlink = NULL;
2810 * is a <LINK> command allowed here?
2812 if (CCDF_NOT_ALLOW_CMD(flags, CCDF_LINK_CMD))
2816 * get the hypertext type
2818 if (GetValueParameter (cur_vars, _DtCvTRUE, &hyperType) < 0)
2823 errno = CEErrorHyperType;
2828 * get the hypertext link spec.
2830 result = GetStringParameter(cur_vars, _DtCvTRUE, _DtCvTRUE, _DtCvFALSE,
2831 _DtCvFALSE, &hyperlink);
2835 * See if we have the optional description string
2837 result = GetStringParameter (cur_vars, _DtCvFALSE, _DtCvTRUE,
2838 _DtCvFALSE, _DtCvFALSE, &description);
2842 result = _DtLinkDbAddLink (cur_vars->my_links,
2845 ReturnLinkType(hyperType, hyperlink),
2846 ReturnLinkWinHint(hyperType),
2848 if (NULL != description)
2855 * if no problems encountered, start parsing with this
2860 hyperIndex = result;
2861 result = FindEndMarker (cur_vars);
2865 * set the hypertext flag and type.
2867 seg_flags = _DtCvSetTypeToHyperText(seg_flags);
2869 result = Parse (CCDF_LINK_CMD, cur_state, cur_vars,
2870 seg_flags, frmt_type,
2874 ret_on_nl, fnt_flag);
2879 * Don't free the hypertext string or description.
2880 * It is now owned by the Link List.
2888 } /* End ProcessHypertext */
2890 /******************************************************************************
2891 * Function: int ProcessLabelCmd (
2892 * FormatVariables *cur_vars, int seg_type,
2893 * char **font_attr, int link_spec,
2897 * font_attr Specifies the list of font quarks to
2898 * associate with the string.
2899 * link_spec Specifies the hypertext link to associate
2901 * flags Specifies the formatting commands allowed.
2903 * Returns: 0 if successful, -1 if errors.
2907 * Purpose: Process the <LABEL> specification.
2909 *****************************************************************************/
2912 FormatVariables *cur_vars,
2913 unsigned long seg_flags,
2914 _DtCvFrmtOption frmt_type,
2915 _DtHelpFontHints *font_attr,
2920 _DtCvSegment **ret_list)
2922 SegList oldList = cur_vars->my_list;
2925 * is a <LABEL> command allowed?
2927 if (CCDF_NOT_ALLOW_CMD(flags, CCDF_LABEL_CMD))
2931 * can't have another <LABEL> command inside this one
2933 flags &= (~(CCDF_LABEL_CMD));
2936 * Find the end marker
2938 if (FindEndMarker (cur_vars) != 0)
2941 cur_vars->my_list = InitList;
2942 if (Parse (CCDF_LABEL_CMD, NormalState, cur_vars,
2948 ret_on_nl, fnt_flag) == -1)
2952 * set the links, return the segment list and restore the old list.
2954 TerminateSegList(&(cur_vars->my_list), True);
2955 *ret_list = cur_vars->my_list.list;
2956 cur_vars->my_list = oldList;
2959 * Indicate that preceding space on the next text should be ignored
2961 cur_vars->last_was_space = True;
2965 } /* End ProcessLabelCmd */
2967 /******************************************************************************
2968 * Function: int ProcessFigureCmd (
2969 * FormatVariables *cur_vars,
2973 * font_attr Specifies the list of font quarks to
2974 * associate with the string.
2976 * Returns: 0 if successful, -1 if errors.
2980 * Purpose: Process the <FIGURE> specification.
2982 *****************************************************************************/
2985 FormatVariables *cur_vars,
2986 ProcessState cur_state,
2987 _DtCvFrmtOption frmt_type,
2988 _DtHelpFontHints *font_attr,
2995 int linkType = CCDF_LINK_JUMP_REUSE;
2997 int segType = _DtCvREGION;
2998 char *description = NULL;
2999 char *idString = NULL;
3000 char *filename = NULL;
3001 char *linkspec = NULL;
3002 _DtCvFrmtOption vertOrientCap = _DtCvJUSTIFY_BOTTOM;
3003 _DtCvFrmtOption horzOrientCap = _DtCvJUSTIFY_CENTER;
3004 _DtCvFrmtOption justifyCap = _DtCvJUSTIFY_CENTER;
3005 _DtCvFrmtOption justifyGraphic = _DtCvJUSTIFY_CENTER;
3006 _DtCvSegment *figContainer;
3009 SegList figList = InitList;
3012 * create a container for this figure (and possibly a caption)
3014 if (-1 == CheckSegList(cur_vars))
3017 figContainer = NextAvailSeg(cur_vars->my_list);
3018 figContainer->handle.container = DefContainer;
3019 figContainer->type = _DtCvSetTypeToContainer(figContainer->type);
3020 _DtCvContainerLeadingOfSeg(figContainer) = cur_vars->ui_info->leading;
3023 * remember the old list and initialize for the figure.
3025 oldList = cur_vars->my_list;
3026 cur_vars->my_list = InitList;
3029 * process the parameters of the figure cmd.
3031 while (!done && result != -1)
3033 if (SkipToNextToken (cur_vars, _DtCvFALSE) == -1)
3039 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
3042 * end of figure spec
3046 * move past the end of token marker
3047 * and skip the leading blanks in the caption.
3049 (cur_vars->rd_ptr)++;
3050 while (result != -1 && !done)
3052 if (*(cur_vars->rd_ptr) == '\0')
3053 result = GetNextBuffer (cur_vars);
3054 else if ((cur_vars->cur_mb_max == 1 ||
3055 mblen(cur_vars->rd_ptr, cur_vars->cur_mb_max) == 1)
3056 && *(cur_vars->rd_ptr) == ' ')
3057 (cur_vars->rd_ptr)++;
3073 * Go to the next character.
3075 (cur_vars->rd_ptr)++;
3078 * Do we need to read more information?
3080 if (*(cur_vars->rd_ptr) == '\0' && GetNextBuffer (cur_vars) == -1)
3086 * look at the next charager to determine the token.
3088 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
3090 case 'c': /* caption center */
3091 justifyCap = _DtCvJUSTIFY_CENTER;
3092 horzOrientCap = _DtCvJUSTIFY_CENTER;
3095 case 'e': /* graphic centered */
3096 justifyGraphic = _DtCvJUSTIFY_CENTER;
3099 case 'b': /* caption below graphic */
3100 vertOrientCap = _DtCvJUSTIFY_BOTTOM;
3103 case 'l': /* caption justified left */
3104 justifyCap = _DtCvJUSTIFY_LEFT;
3105 horzOrientCap = _DtCvJUSTIFY_LEFT_MARGIN;
3108 case 'r': /* caption right justified */
3109 justifyCap = _DtCvJUSTIFY_RIGHT;
3110 horzOrientCap = _DtCvJUSTIFY_RIGHT_MARGIN;
3113 case 't': /* caption at top */
3114 vertOrientCap = _DtCvJUSTIFY_TOP;
3121 * description [string | "string" | 'string']
3124 result = GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3125 _DtCvFALSE, _DtCvFALSE, &description);
3132 result = GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3133 _DtCvFALSE, _DtCvFALSE, &filename);
3143 result = GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3144 _DtCvFALSE, _DtCvFALSE, &idString);
3146 * if this figure had an id associated with it, create
3147 * marker segment for it.
3149 if (-1 != result && NULL != idString && '\0' != *idString)
3152 * create the marker. If there is an error, free the
3155 result = CreateMarker(cur_vars, idString);
3163 * link [string | "string" | 'string']
3167 * Go to the next character.
3169 (cur_vars->rd_ptr)++;
3172 * Do we need to read more information?
3174 if (*(cur_vars->rd_ptr) == '\0' && GetNextBuffer (cur_vars) == -1)
3180 * look at the next charager to determine the token.
3182 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
3185 justifyGraphic = _DtCvJUSTIFY_LEFT;
3189 segType = _DtCvSetTypeToHyperText (segType);
3190 result = GetStringParameter (cur_vars, _DtCvTRUE,
3191 _DtCvTRUE, _DtCvFALSE, _DtCvFALSE,
3205 justifyGraphic = _DtCvJUSTIFY_RIGHT;
3212 if (GetValueParameter (cur_vars, _DtCvTRUE, &linkType) == -1)
3214 else if (linkType < 0)
3216 errno = CEErrorHyperType;
3226 if (result != -1 && (filename == NULL || strlen(filename) == 0))
3232 * check to see if the hypertext flag is set but we don't
3233 * have a link specification.
3235 if (IsTypeHyperText(segType) && !linkspec)
3237 segType = segType & ~(_DtCvHYPER_TEXT);
3239 if (NULL != description)
3245 * do we still have a good hypertext?
3246 * if so, create a link index for it.
3248 if (IsTypeHyperText(segType))
3250 linkIndex = _DtLinkDbAddLink (cur_vars->my_links,
3253 ReturnLinkType(linkType, linkspec),
3254 ReturnLinkWinHint(linkType),
3256 if (linkIndex == -1)
3264 * parse the caption. If there is a caption, we will need to
3265 * wrap it and the figure in containers with the appropriate
3266 * controller flags set to get the correct layout.
3268 result = Parse (CCDF_FIGURE_CMD, cur_state, cur_vars,
3272 (CCDF_NEWLINE_CMD | CCDF_LINK_CMD |
3273 CCDF_FONT_CMD | CCDF_ID_CMD),
3274 ret_on_nl, fnt_flag);
3277 * save the caption List.
3279 TerminateSegList(&(cur_vars->my_list), True);
3280 capList = cur_vars->my_list;
3283 * is there a caption? If so, create two segments instead
3287 if (-1 != result && 0 != capList.cnt)
3291 * allocate room for the figure (and caption)
3294 result = CheckList(&figList, cnt, cnt);
3299 * process any caption that was specified
3301 if (0 != capList.cnt)
3303 _DtCvSegment *pSeg = figList.list;
3306 * create a controller for the caption.
3308 pSeg->type = _DtCvSetTypeToController(
3309 _DtCvSetTypeToContainer(pSeg->type));
3312 * set its orientation and justification.
3314 _DtCvContainerOrientOfSeg(pSeg) = horzOrientCap;
3315 _DtCvContainerVOrientOfSeg(pSeg) = vertOrientCap;
3316 _DtCvContainerJustifyOfSeg(pSeg) = justifyCap;
3317 _DtCvContainerBMarginOfSeg(pSeg) = 0;
3320 * attach the caption to the container.
3322 _DtCvContainerListOfSeg(pSeg) = capList.list;
3325 * indicate this segment has been used.
3331 * now load the graphic into the next available segment
3332 * allocated for the figure.
3334 cur_vars->my_list = figList;
3335 result = CreateSaveGraphic (cur_vars, segType, filename, linkIndex);
3338 * if no problems, attach the figure (and caption) to the
3346 TerminateSegList(&(cur_vars->my_list), True);
3349 * attach the figure (and caption) to the wrapper
3351 _DtCvContainerListOfSeg(figContainer) = cur_vars->my_list.list;
3354 * set the justify to the correct value to act on the
3357 _DtCvContainerJustifyOfSeg(figContainer) = justifyGraphic;
3360 * indicate that this segment has been used
3368 * restore the segment list.
3371 cur_vars->my_list = oldList;
3375 * don't free the link string or description,
3376 * the link list owns them now.
3381 } /* End ProcessFigureCmd */
3383 /******************************************************************************
3384 * Function: int ProcessInLine (FormatVariables cur_vars,
3385 * int seg_type, int link_spec )
3388 * seg_type Specifes the type of segment currently
3390 * link_spec Specifies the hypertext link associated
3391 * with this segment.
3393 * Returns: 0 if successful, -1 if errors.
3397 * Purpose: Process a <GRAPHIC> specification.
3399 *****************************************************************************/
3402 FormatVariables *cur_vars,
3408 char *idString = NULL;
3409 char *filename = NULL;
3412 * process the graphic parameters
3414 while (!done && result != -1)
3416 if (SkipToNextToken (cur_vars, _DtCvFALSE) == -1)
3419 switch (_DtCvToLower(*(cur_vars->rd_ptr)))
3422 * end of in line spec
3426 * move past the end of token marker
3428 (cur_vars->rd_ptr)++;
3436 result = GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3437 _DtCvFALSE, _DtCvFALSE, &filename);
3447 result = GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3448 _DtCvFALSE, _DtCvFALSE, &idString);
3450 * if this graphic had an id associated with it, create
3451 * marker segment for it.
3453 if (-1 != result && NULL != idString && '\0' != *idString)
3456 * create the marker. If there is an error, free the
3459 result = CreateMarker(cur_vars, idString);
3471 if (result != -1 && (filename == NULL || strlen(filename) == 0))
3477 * create the graphic.
3479 result = CreateSaveGraphic (cur_vars,
3480 _DtCvSetTypeToInLine(seg_type),
3481 filename, link_spec);
3482 cur_vars->last_was_space = False;
3489 } /* End ProcessInLine */
3491 /******************************************************************************
3492 * Function: int CheckIdString (
3493 * FormatVariables *cur_vars, int segType,
3494 * char **font_attr, int linkspec,
3498 * segType Specifies the type of segment currently
3500 * font_attr Specifies the list of font quarks to
3501 * associate with the string.
3502 * linkspec Specifies the hypertext link associated
3504 * flags Specifies the formatting commands allowed.
3506 * Returns: 0 if successful, -1 if errors.
3510 * Purpose: Create a marker at this location.
3512 *****************************************************************************/
3515 FormatVariables *cur_vars,
3516 ProcessState cur_state,
3517 unsigned long seg_flags,
3518 _DtCvFrmtOption frmt_type,
3519 _DtHelpFontHints *font_attr,
3529 * is it legal to have a <ID> command at this point?
3531 if (CCDF_NOT_ALLOW_CMD (flags, CCDF_ID_CMD))
3536 * clear out any current information in the buffer
3537 * and make sure there is a segment available.
3539 if (-1 != GetStringParameter (cur_vars, _DtCvTRUE, _DtCvTRUE,
3540 _DtCvFALSE, _DtCvFALSE, &ptr)
3542 -1 != CheckSaveSegment (seg_flags, font_attr, linkspec, cur_vars))
3545 * create the marker. If there is an error, free the
3548 result = CreateMarker(cur_vars, ptr);
3553 * find the end of the <ID> syntax
3554 * and parse the data between the begin <ID> and </ID>.
3556 if (0 == result && -1 != FindEndMarker (cur_vars) &&
3557 -1 != Parse (CCDF_ID_CMD, cur_state, cur_vars,
3558 seg_flags, frmt_type,
3562 ret_on_nl, fnt_flag))
3567 * return an error code if necessary
3571 } /* End CheckIdString */
3573 /******************************************************************************
3574 * Function: int Parse (int cur_cmd,
3575 * FormatVariables *cur_vars, int segType,
3577 * int linkspec, int allowed)
3580 * cur_cmd Specifies the current formatting command
3582 * parent Specifies the parent paragraph.
3583 * segType Specifies the type of segment currently
3585 * font_attr Specifies the list of font quarks to
3586 * associate with the string.
3587 * linkspec Specifies the hypertext link associated
3589 * allowed Specifies the formatting commands allowed.
3592 * 1 if ran into a </> specification.
3597 * Purpose: Parse the data.
3599 *****************************************************************************/
3603 ProcessState cur_state,
3604 FormatVariables *cur_vars,
3605 unsigned long seg_flags,
3606 _DtCvFrmtOption frmt_type,
3607 _DtHelpFontHints *font_attr,
3609 const char *scan_string,
3617 int fontType = False;
3618 int cmdType = False;
3623 if (cur_vars->cur_mb_max != 1)
3624 charSize = mblen(cur_vars->rd_ptr, cur_vars->cur_mb_max);
3629 * check to see if a newline was the previous character.
3630 * If so, it may need to be replaced with a space.
3632 if (cur_vars->last_was_nl == True &&
3633 AppendSpaceToInfo(cur_vars, NULL, frmt_type) == -1)
3636 cur_vars->last_was_nl = False;
3637 cur_vars->last_was_mb = False;
3639 switch (*(cur_vars->rd_ptr))
3643 * Go to the next character.
3645 (cur_vars->rd_ptr)++;
3650 cmdType = _DtHelpCeGetCcdfCmd (cur_cmd, cur_vars->rd_buf,
3651 &(cur_vars->rd_ptr),
3660 case CCDF_FIGURE_CMD:
3661 if (CheckSaveSegment(seg_flags, font_attr,
3662 linkspec, cur_vars) == -1
3664 ProcessFigureCmd(cur_vars,
3668 ret_on_nl, fnt_flag) == -1)
3681 fontType = _DtHelpCeGetCcdfFontType (cur_vars->rd_ptr);
3682 done = ChangeFont(fontType, seg_flags,
3684 font_attr , linkspec,
3696 case CCDF_FORMAT_END:
3697 if (CheckSaveSegment(seg_flags, font_attr,
3698 linkspec, cur_vars) == -1 ||
3699 FindEndMarker (cur_vars) == -1)
3707 case CCDF_GRAPHIC_CMD:
3709 * clear out any information
3710 * in the buffer and then
3711 * process the figure.
3713 if (CheckSaveSegment (seg_flags, font_attr,
3714 linkspec, cur_vars) == -1
3716 ProcessInLine (cur_vars, seg_flags,
3725 done = CheckIdString (cur_vars,
3732 ret_on_nl, fnt_flag);
3739 if (CheckSaveSegment (seg_flags, font_attr,
3740 linkspec, cur_vars) == -1
3742 ProcessHypertext(cur_vars, cur_state,
3743 seg_flags, frmt_type,
3745 ret_on_nl, fnt_flag) == -1)
3752 case CCDF_NEWLINE_CMD:
3753 if (SaveNewLine (cur_vars, seg_flags, font_attr,
3756 FindEndMarker (cur_vars) == -1)
3760 case CCDF_OCTAL_CMD:
3761 if (AppendOctalToInfo(cur_vars,
3762 cur_vars->rd_ptr) == -1
3763 || FindEndMarker (cur_vars) == -1)
3770 case CCDF_PARAGRAPH_CMD:
3771 if (CheckSaveSegment (seg_flags, font_attr,
3772 linkspec, cur_vars) == -1
3774 ProcessParagraph(cur_vars, cur_state,
3781 * this should never be hit if the markup is
3782 * correct. Processing labels is through the
3783 * the paragraph processor now.
3785 case CCDF_LABEL_CMD:
3797 * Go to the next character
3799 (cur_vars->rd_ptr)++;
3802 * If processing a static segment, we want to
3803 * keep the author defined end-of-lines.
3805 * Otherwise, we throw them away.
3807 if (_DtCvLITERAL == frmt_type || True == ret_on_nl)
3809 done = SaveStringAsSegments (cur_vars,
3810 _DtCvSetTypeToNewLine(seg_flags),
3811 font_attr, linkspec);
3816 else if (cur_vars->last_was_space == False)
3817 cur_vars->last_was_nl = True;
3823 * go past this character.
3825 (cur_vars->rd_ptr)++;
3828 * append 1-8 characters on the end of the buffer.
3830 _DtHelpCeCountChars(cur_vars->fmt_buf, MB_CUR_MAX,
3832 leftOver = leftOver % 8;
3833 ptr = ((char *) SpaceString) + leftOver;
3834 done = _DtHelpCeAddStrToBuf (&ptr,
3835 &(cur_vars->fmt_buf),
3836 &(cur_vars->fmt_size),
3837 &(cur_vars->fmt_buf_max),
3844 * The author has escaped a character.
3845 * Increment to the escaped character.
3847 (cur_vars->rd_ptr)++;
3850 * Do we need to read more information?
3852 if (*(cur_vars->rd_ptr) == '\0' &&
3853 GetNextBuffer (cur_vars) == -1)
3856 * If we didn't read more information or
3857 * was successful on the read, save the
3858 * escaped character.
3860 done = AppendCharToInfo (cur_vars, &(cur_vars->rd_ptr));
3865 * Put a space in the segment.
3867 done = AppendSpaceToInfo (cur_vars,
3868 &(cur_vars->rd_ptr), frmt_type);
3873 * put the information in the buffer
3875 if (AppendToInfo (cur_vars, &(cur_vars->rd_ptr),
3881 else if (charSize > 1)
3883 if ((cur_vars->ui_info->nl_to_space == 1 ||
3884 (cur_vars->last_was_mb == False
3885 && cur_vars->last_was_nl == True))
3886 && AppendSpaceToInfo(cur_vars, NULL, frmt_type) == -1)
3889 cur_vars->last_was_nl = False;
3890 cur_vars->last_was_mb = True;
3891 if (AppendToInfo (cur_vars, &(cur_vars->rd_ptr), scan_string) == -1)
3894 else if (charSize < 0)
3897 * we have either invalid characters or part of a multi-byte
3898 * character. Read the next buffer for more info.
3900 leftOver = strlen (cur_vars->rd_ptr);
3901 if (leftOver < ((int) MB_CUR_MAX))
3903 if (GetNextBuffer (cur_vars) == -1)
3909 * In trouble brothers and sisters. We have garbage in the
3910 * buffer - BAIL OUT!
3915 if (!done && *(cur_vars->rd_ptr) == '\0')
3918 * We're at the end of the buffer, can we read more?
3920 if (cur_vars->rd_flag > 0 && GetNextBuffer (cur_vars) == -1)
3923 if (cur_vars->rd_flag == 0)
3929 * DO NOT MODIFY 'done' HERE
3930 * If you do, the caller is unable to test for return value == 1!!!!
3933 CheckSaveSegment (seg_flags, font_attr, linkspec, cur_vars) == -1)
3939 /*****************************************************************************
3940 * Function: int ParseTitle (FormatVariables cur_vars)
3943 * cur_vars Specifies the current values for formatting.
3945 * Returns: 0 if successful, -1 if failure.
3949 * Purpose: ParseTitle gets the data between a <TITLE> and </TITLE>
3950 * pair; putting it in a controlling container.
3952 *****************************************************************************/
3955 FormatVariables *cur_vars,
3959 _DtHelpFontHints *fontAttrs)
3962 SegList oldList = cur_vars->my_list;
3965 * rest the current segment list
3967 cur_vars->my_list = InitList;
3970 * check for the <TITLE> directive.
3972 if (_DtHelpCeCheckNextCcdfCmd ("ti", cur_vars->my_file, cur_vars->rd_buf,
3973 cur_vars->rd_size, 1, &(cur_vars->rd_ptr)) != 0
3974 || FindEndMarker (cur_vars) != 0)
3979 * 1 when a </> is found,
3980 * 0 if the data runs out before we finish parsing,
3983 * A return of 1 is required from Parse
3985 if (1 == Parse (CCDF_TITLE_CMD, NormalState, cur_vars,
3987 fontAttrs, -1, Specials,
3988 ~(CCDF_TOPIC_CMD | CCDF_TITLE_CMD | CCDF_ABBREV_CMD |
3989 CCDF_PARAGRAPH_CMD | CCDF_FIGURE_CMD | CCDF_LABEL_CMD),
3993 * skip the any abbreviation that might be there
3997 result = _DtHelpCeSkipCcdfAbbrev (cur_vars->my_file,
3999 &(cur_vars->rd_ptr), cur_vars->rd_size,
4000 cur_vars->cur_mb_max);
4003 * if we successfully skipped the abbreviation and there is
4004 * a title - then attach the title body to the controlling
4005 * container (and make the container a controller).
4007 if (result != -1 && cur_vars->my_list.list)
4009 _DtCvSegment *list = oldList.list;
4010 int cnt = oldList.cnt;
4012 TerminateSegList (&(cur_vars->my_list), True);
4015 * when this segment was allocated, it was initialized
4016 * to the correct vertical and horizontal orientation
4017 * for a CCDF title. Simply set the type to container
4018 * and controller to get it to act properly.
4022 list[cnt].type = _DtCvSetTypeToContainer(list[cnt].type);
4023 if (True == cont_flag)
4024 list[cnt].type = _DtCvSetTypeToController(list[cnt].type);
4027 * attach the title body to the controller container.
4029 _DtCvContainerListOfSeg(&list[cnt]) = cur_vars->my_list.list;
4032 * and count this segment as used.
4037 * otherwise, a container hasn't been created for this list.
4038 * but we don't want to loose the information.
4041 oldList.list = cur_vars->my_list.list;
4046 * restore segment usage information.
4048 cur_vars->my_list = oldList;
4053 /*****************************************************************************
4054 * Function: int Format (FormatVariables cur_vars, char *id_string,
4062 * Purpose: Format is the top entry point for formating Help Files with
4063 * formatting information into a form understood by a display area.
4064 * It will keep calling Parse, until the entire topic is read
4065 * or an error occurs.
4067 *****************************************************************************/
4070 FormatVariables *cur_vars,
4071 _FrmtUiInfo *ui_info,
4073 _DtCvTopicPtr *ret_topic )
4078 char *charSet = NULL;
4079 char readBuf[BUFF_SIZE];
4080 _DtHelpFontHints fontAttrs;
4081 _DtCvTopicInfo *topicHandle;
4082 SegList myList = InitList;
4085 * malloc space for the topic handle.
4087 topicHandle = (_DtCvTopicInfo *) malloc (sizeof(_DtCvTopicInfo));
4088 if (topicHandle == NULL)
4092 * initialize the font attributes to the default hints
4094 _DtHelpCeCopyDefFontAttrList (&fontAttrs);
4097 * set up the formatting variable structure
4099 if (InitStructure (cur_vars, ui_info, readBuf, BUFF_SIZE) == -1)
4103 * read the first buffer's worth of the topic.
4105 cur_vars->rd_flag = _DtHelpCeReadBuf (cur_vars->my_file, cur_vars->rd_buf,
4107 if (cur_vars->rd_flag == -1)
4111 * The first command in the buffer MUST be the <TOPIC> command.
4112 * It is in a one byte charset.
4114 if (_DtHelpCeGetCcdfTopicCmd (((void *) NULL), cur_vars->my_file,
4115 cur_vars->rd_buf, &(cur_vars->rd_ptr),
4116 cur_vars->rd_size, 1, &charSet) == -1)
4120 * change the character set to the returned character set
4121 * Assume that the charset is 'iso8859' if not specified.
4123 cur_vars->cur_mb_max = 1;
4124 if (NULL != charSet)
4125 GetMbLen(cur_vars, charSet, &(_DtHelpFontHintsLang(fontAttrs)),
4126 &(_DtHelpFontHintsCharSet(fontAttrs)));
4129 * Remember the topic code set and MB_CUR_MAX.
4131 cur_vars->topic_char_set = _DtHelpFontHintsCharSet(fontAttrs);
4132 cur_vars->topic_lang = _DtHelpFontHintsLang(fontAttrs);
4133 cur_vars->topic_mb_max = cur_vars->cur_mb_max;
4136 * allocate two segments for the topic - one for the <title>
4137 * and one for the body of the topic.
4139 if (0 != CheckList(&(cur_vars->my_list), 2, 2))
4141 if (NULL != charSet)
4143 free(_DtHelpFontHintsLang(fontAttrs));
4144 free(_DtHelpFontHintsCharSet(fontAttrs));
4151 * get the title and skip the abbreviation.
4153 if (0 != ParseTitle(cur_vars, True, True, 0, &fontAttrs))
4155 if (NULL != charSet)
4157 free(_DtHelpFontHintsLang(fontAttrs));
4158 free(_DtHelpFontHintsCharSet(fontAttrs));
4165 * remember this current list since we will be attaching any more
4166 * information as a child of these segments.
4168 myList = cur_vars->my_list;
4171 * process the rest of the information
4173 while (0 == result && !done)
4176 * reset the segment count before processing the information
4177 * for this paragraph
4179 cur_vars->my_list = InitList;
4182 * make sure we've got a container for this paragraph
4184 done = CheckList(&myList, 1, GROW_SIZE);
4187 * now process the information while finding paragraphs.
4191 done = Parse (CCDF_PARAGRAPH_CMD, NormalState, cur_vars,
4193 &fontAttrs, -1, Specials,
4194 ~(CCDF_TOPIC_CMD | CCDF_TITLE_CMD | CCDF_ABBREV_CMD),
4196 } while (0 == done);
4199 * if no errors, attach the resulting child information to the
4200 * paragraph container.
4205 * clean up the last segment.
4207 if (cur_vars->my_list.list)
4209 _DtCvSegment *list = NextAvailSeg(myList);
4211 TerminateSegList (&(cur_vars->my_list), True);
4214 * make it a container.
4216 list->type = _DtCvSetTypeToContainer(list->type);
4219 * attach the information to the container
4221 _DtCvContainerListOfSeg(list) = cur_vars->my_list.list;
4224 * and count this container as used.
4234 * If we had errors, deallocate the memory.
4237 _DtHelpFreeSegments(myList.list, _DtCvFALSE, ui_info->destroy_region,
4238 ui_info->client_data);
4242 * Tighten up the paragraph structures if too many allocated.
4244 if (0 != myList.cnt)
4245 TerminateSegList (&(myList), True);
4248 free ((char *) myList.list);
4254 * return the values, even if they are null and zero.
4257 if (id_string == NULL)
4258 topicHandle->id_str = id_string;
4260 topicHandle->id_str = strdup(id_string);
4262 topicHandle->seg_list = myList.list;
4263 topicHandle->mark_list = NULL;
4264 topicHandle->link_data = cur_vars->my_links;
4266 *ret_topic = (void *) topicHandle;
4271 if (NULL != charSet)
4273 free(_DtHelpFontHintsLang(fontAttrs));
4274 free(_DtHelpFontHintsCharSet(fontAttrs));
4284 /*****************************************************************************
4285 * Function: int FormatCCDFTitle (FormatVariables cur_vars
4288 * cur_vars Specifies the current values for formatting.
4289 * id_string Specifies the id to look for or NULL.
4290 * ret_para Returns a pointer to a list of _DtCvSegment
4292 * ret_num Specifies the number of structures in
4294 * ret_seg Specifies the segment containing 'id_string'
4301 * Purpose: Format is the top entry point for formating Help Files with
4302 * formatting information into a form understood by a display area.
4303 * It will keep calling Parse, until the entire topic is read
4304 * or an error occurs.
4306 *****************************************************************************/
4309 FormatVariables *cur_vars,
4310 _DtHelpFontHints fontAttrs,
4318 char *charSet = NULL;
4320 int origCnt = cur_vars->my_list.cnt;
4322 _DtCvSegment *titleSeg;
4325 cur_vars->rd_buf[0] = '\0';
4326 cur_vars->rd_ptr = cur_vars->rd_buf;
4328 if (_DtHelpCeFileOpenAndSeek(filename, offset, -1,
4329 &(cur_vars->my_file), NULL) != 0)
4332 cur_vars->rd_flag = _DtHelpCeReadBuf (cur_vars->my_file, cur_vars->rd_buf,
4335 if (cur_vars->rd_flag == -1)
4337 _DtHelpCeBufFileClose (cur_vars->my_file, True);
4342 * The first command in the buffer MUST be the <TOPIC> command.
4343 * It is in a one byte charset.
4345 if (_DtHelpCeGetCcdfTopicCmd (((void *) NULL), cur_vars->my_file,
4346 cur_vars->rd_buf, &(cur_vars->rd_ptr),
4347 cur_vars->rd_size, 1, &charSet) == -1)
4349 _DtHelpCeBufFileClose (cur_vars->my_file, True);
4354 * change the character set to the returned character set
4355 * Assume that the charset is 'iso8859' if not specified.
4357 cur_vars->cur_mb_max = 1;
4358 if (NULL != charSet)
4359 GetMbLen(cur_vars, charSet, &(_DtHelpFontHintsLang(fontAttrs)),
4360 &(_DtHelpFontHintsCharSet(fontAttrs)));
4363 * Remember the topic code set and MB_CUR_MAX.
4365 cur_vars->topic_char_set = _DtHelpFontHintsCharSet(fontAttrs);
4366 cur_vars->topic_lang = _DtHelpFontHintsLang(fontAttrs);
4367 cur_vars->topic_mb_max = cur_vars->cur_mb_max;
4370 * allocate another segment for this title.
4372 if (0 != CheckSegList(cur_vars))
4374 if (NULL != charSet)
4376 free(_DtHelpFontHintsLang(fontAttrs));
4377 free(_DtHelpFontHintsCharSet(fontAttrs));
4380 _DtHelpCeBufFileClose(cur_vars->my_file, True);
4385 * set the left margin correctly.
4387 titleSeg = NextAvailSeg(cur_vars->my_list);
4388 titleSeg->handle.container = DefContainer;
4389 titleSeg->type = _DtCvSetTypeToContainer(titleSeg->type);
4390 _DtCvContainerLMarginOfSeg(titleSeg) = level*2*cur_vars->ui_info->avg_char;
4391 _DtCvContainerBMarginOfSeg(titleSeg) = 0;
4392 _DtCvContainerTypeOfSeg(titleSeg) = _DtCvLITERAL;
4393 _DtCvContainerLeadingOfSeg(titleSeg) = cur_vars->ui_info->leading;
4398 if (-1 == ParseTitle(cur_vars, False, False, fnt_flags, &fontAttrs))
4400 if (NULL != charSet)
4402 free(_DtHelpFontHintsLang(fontAttrs));
4403 free(_DtHelpFontHintsCharSet(fontAttrs));
4406 _DtHelpCeBufFileClose(cur_vars->my_file, True);
4411 * We've parsed the title. see if we want the abbrev.
4414 * if the title is null or we want the abbrev,
4415 * process the abbreviation.
4417 if (NULL == _DtCvContainerListOfSeg(titleSeg) || want_abbrev)
4419 SegList titleList = cur_vars->my_list;
4422 * reset the buffer to get the abbreviation
4424 if (cur_vars->fmt_buf != NULL)
4426 free(cur_vars->fmt_buf);
4427 cur_vars->fmt_buf = NULL;
4428 cur_vars->fmt_size = 0;
4429 cur_vars->fmt_buf_max = 0;
4432 result = _DtHelpCeGetCcdfAbbrevCmd (cur_vars->my_file, cur_vars->rd_buf,
4433 cur_vars->rd_size, cur_vars->cur_mb_max,
4434 &(cur_vars->rd_ptr), &(cur_vars->fmt_buf));
4437 * If no errors getting the abbreviation, save it
4442 * save the abbreviation
4444 if (cur_vars->fmt_buf != NULL)
4447 * If there was a title, free it
4449 if (NULL != _DtCvContainerListOfSeg(titleSeg))
4450 _DtHelpFreeSegments(_DtCvContainerListOfSeg(titleSeg),
4452 cur_vars->ui_info->destroy_region,
4453 cur_vars->ui_info->client_data);
4456 * save the abbreviation
4458 cur_vars->my_list = InitList;
4459 cur_vars->fmt_size = strlen (cur_vars->fmt_buf);
4460 cur_vars->fmt_buf_max = cur_vars->fmt_size + 1;
4461 if (cur_vars->fmt_size > 0)
4462 result = SaveStringAsSegments (cur_vars, 0, &fontAttrs, -1);
4465 TerminateSegList(&(cur_vars->my_list), True);
4467 titleSeg->type = _DtCvSetTypeToContainer(titleSeg->type);
4468 _DtCvContainerListOfSeg(titleSeg) = cur_vars->my_list.list;
4474 * eliminate this segment if no title or abbrev was found.
4476 if (NULL == _DtCvContainerListOfSeg(titleSeg))
4478 titleList.cnt = origCnt;
4479 _DtCvContainerTypeOfSeg(titleSeg) = _DtCvDYNAMIC;
4483 * reset the title list
4485 cur_vars->my_list = titleList;
4488 result = _DtHelpCeSkipCcdfAbbrev (cur_vars->my_file, cur_vars->rd_buf,
4489 &(cur_vars->rd_ptr), cur_vars->rd_size,
4490 cur_vars->cur_mb_max);
4492 if (cur_vars->fmt_buf != NULL)
4493 cur_vars->fmt_buf[0] = '\0';
4494 cur_vars->fmt_size = 0;
4497 * remove the newline from the lists and
4498 * change all the newlines on the segments into a space.
4500 for (list = _DtCvContainerListOfSeg(titleSeg);
4501 NULL != list; list = list->next_seg)
4503 if (_DtCvIsSegNewLine(list))
4506 * clear the newline flag.
4508 list->type &= ~(_DtCvNEW_LINE);
4511 * check to see if the last character of this segment or
4512 * the first character of the next segment is a space.
4515 if (NULL != list->next_disp && _DtCvIsSegString(list)
4516 && _DtCvIsSegRegChar(list))
4519 * is the last character of the string a space?
4522 len = strlen((char *) _DtCvStringOfStringSeg(list)) - 1;
4523 if (' ' != ((char *) _DtCvStringOfStringSeg(list))[len])
4526 * is the next segment a one byte string?
4527 * and if so, is the first character a space?
4528 * if so, do nothing.
4530 if (_DtCvIsSegString(list->next_disp)
4531 && _DtCvIsSegRegChar(list->next_disp)
4532 && ' ' != *((char *)_DtCvStringOfStringSeg(list->next_disp)))
4535 * need to add a space to one of these strings.
4538 _DtCvStringOfStringSeg(list) = (char *) realloc(
4539 (void *) _DtCvStringOfStringSeg(list),
4540 sizeof(char *) * len);
4541 if (NULL == _DtCvStringOfStringSeg(list))
4544 strPtr = (char *) _DtCvStrPtr(
4545 _DtCvStringOfStringSeg(list),
4556 _DtHelpCeBufFileClose (cur_vars->my_file, True);
4561 if (NULL != charSet)
4563 free(_DtHelpFontHintsLang(fontAttrs));
4564 free(_DtHelpFontHintsCharSet(fontAttrs));
4574 /******************************************************************************
4575 * Function: int FormatEntryInToc (
4579 * Returns: 0 if successful, -1 if errors
4585 ******************************************************************************/
4588 _DtHelpVolumeHdl volume,
4590 FormatVariables *cur_vars,
4591 _DtHelpFontHints font_attrs,
4598 char *strPtr = NULL;
4600 _DtCvSegment *titleSeg;
4604 * check to see that there is a segment for this title.
4606 if (0 != CheckSegList(cur_vars))
4610 * The next segment in the list will become the next title.
4611 * Get a pointer to it for later use.
4613 titleList = cur_vars->my_list;
4614 titleSeg = NextAvailSeg(titleList);
4615 titleSeg->handle.container = DefContainer;
4616 titleSeg->type = _DtCvSetTypeToContainer(titleSeg->type);
4617 _DtCvContainerBMarginOfSeg(titleSeg) = 0;
4618 _DtCvContainerLeadingOfSeg(titleSeg) = cur_vars->ui_info->leading;
4621 * Get the file and offset for the topic.
4622 * and process the topic's title, ignoring most font changes.
4624 if (True == _DtHelpCeFindId(volume, loc_id, -1, &strPtr, &offset) &&
4625 -1 != FormatCCDFTitle(cur_vars, font_attrs, strPtr, offset, level,
4626 ((1<<_CEFONT_SIZE)|(1<<_CEFONT_WEIGHT)|(1<<_CEFONT_ANGLE)|(1<<_CEFONT_TYPE)),
4630 * now create the hypertext link index for the ghostlink.
4632 num = _DtLinkDbAddLink(cur_vars->my_links, NULL, loc_id,
4633 _DtCvLinkType_SameVolume,
4634 _DtCvWindowHint_CurrentWindow,
4637 * if a link index was successfully created, process the item.
4644 * check to see if this title had any segments.
4646 pSeg = _DtCvContainerListOfSeg(titleSeg);
4649 while (NULL != pSeg)
4652 * If this segment has a hypertext link, remove it.
4654 if (pSeg->link_idx != -1)
4655 _DtLinkDbRemoveLink(cur_vars->my_links, pSeg->link_idx);
4658 * change the link index and flag to the ghost link.
4660 pSeg->link_idx = num;
4661 pSeg->type &= ~(_DtCvHYPER_TEXT);
4662 pSeg->type = _DtCvSetTypeToGhostLink(pSeg->type);
4665 * go to the next segment.
4667 pSeg = pSeg->next_seg;
4673 * no title or abbreviation, so use the location id.
4674 * allocate room for it and put it between parens.
4676 tocLen = strlen (loc_id) + 9;
4677 if (tocLen > cur_vars->fmt_buf_max)
4679 if (NULL == cur_vars->fmt_buf)
4680 cur_vars->fmt_buf = (char *) malloc (tocLen);
4682 cur_vars->fmt_buf = (char *) realloc(
4685 cur_vars->fmt_buf_max = tocLen;
4688 cur_vars->fmt_size = tocLen - 1;
4689 strcpy (cur_vars->fmt_buf, "...(");
4690 strcat (cur_vars->fmt_buf, loc_id);
4691 strcat (cur_vars->fmt_buf, ")...");
4694 * don't overwrite the title's
4696 cur_vars->my_list = InitList;
4699 * save the string off and then attach to the title
4702 result = SaveStringAsSegments(cur_vars, _DtCvGHOST_LINK,
4705 _DtCvContainerListOfSeg(titleSeg) = cur_vars->my_list.list;
4708 * restore the title list.
4710 cur_vars->my_list = titleList;
4720 } /* End FormatEntryInToc */
4722 /******************************************************************************
4723 * Function: int FormatExpandToc (
4724 * _DtHelpVolumeHdl volume,
4727 ******************************************************************************/
4730 _DtHelpVolumeHdl volume,
4733 FormatVariables *cur_vars,
4734 _DtHelpFontHints font_attrs,
4739 if (*path_lst != NULL)
4741 font_attrs.weight = _DtHelpFontWeightMedium;
4742 if (_DtCvStrCaseCmpLatin1(*path_lst, cur_id) == 0)
4743 font_attrs.weight = _DtHelpFontWeightBold;
4745 result = FormatEntryInToc(volume, *path_lst, cur_vars,
4752 int count = _DtHelpCeGetCcdfTopicChildren(volume,
4753 *path_lst, &children);
4756 * if there are children, format them
4760 childLst = children;
4761 font_attrs.weight = _DtHelpFontWeightMedium;
4762 while (result != -1 && count > 0)
4765 * found the next item in the list
4767 if (*path_lst != NULL &&
4768 _DtCvStrCaseCmpLatin1(*path_lst, *childLst) == 0)
4769 result = FormatExpandedToc(volume,
4771 cur_vars, font_attrs, level);
4773 result = FormatEntryInToc(volume, *childLst,
4774 cur_vars, font_attrs, level);
4780 if (children != NULL)
4781 _DtCvFreeArray((void **) children);
4788 /******************************************************************************
4790 * Semi-Public Functions
4792 *****************************************************************************/
4793 /******************************************************************************
4794 * Function: VarHandle *__DtHelpCeSetUpVars (char *rd_buf, grow_size)
4798 * Returns: NULL if unsuccessful.
4804 ******************************************************************************/
4806 __DtHelpCeSetUpVars(
4809 _FrmtUiInfo *ui_info)
4811 FormatVariables *newVars;
4813 newVars = (FormatVariables *) malloc (sizeof(FormatVariables));
4815 newVars->ui_info = ui_info;
4817 newVars->topic_mb_max = _DtHelpCeGetMbLen(lang, code_set);
4818 newVars->cur_mb_max = newVars->topic_mb_max;
4820 return ((VarHandle) newVars);
4822 } /* End __DtHelpCeSetUpVars */
4824 /******************************************************************************
4825 * Function: int __DtHelpCeProcessString (char *in_string, int seg_type,
4830 * Returns: 0 if successful, -1 if errors.
4836 ******************************************************************************/
4838 __DtHelpCeProcessString(
4839 VarHandle var_handle,
4841 _DtCvFrmtOption frmt_type,
4847 _DtHelpFontHints *font_attr )
4850 FormatVariables *myVars = (FormatVariables *) var_handle;
4851 SegList oldList = myVars->my_list;
4853 myVars->rd_buf = in_string;
4854 myVars->rd_size = in_size;
4855 myVars->rd_ptr = in_string;
4856 myVars->my_file = my_file;
4858 if (my_file == NULL)
4859 myVars->rd_flag = 0;
4861 myVars->rd_flag = strlen(in_string);
4865 if (True == ret_on_nl)
4866 myVars->my_list = InitList;
4868 done = Parse (CCDF_FONT_CMD, NormalState, myVars,
4871 -1, scan_string, (CCDF_FONT_CMD | CCDF_OCTAL_CMD), ret_on_nl,
4874 if (done != -1 && True == ret_on_nl)
4876 TerminateSegList (&(myVars->my_list), True);
4877 if (NULL != myVars->my_list.list)
4879 done = CheckList (&oldList, 1, GROW_SIZE);
4882 _DtCvSegment *newSeg = NextAvailSeg(oldList);
4884 newSeg->type = _DtCvSetTypeToContainer(newSeg->type);
4885 _DtCvContainerListOfSeg(newSeg) = myVars->my_list.list;
4886 _DtCvContainerTypeOfSeg(newSeg) = _DtCvDYNAMIC;
4890 TerminateSegList(&oldList, False);
4896 if (False == ret_on_nl)
4897 oldList = myVars->my_list;
4899 myVars->my_list = oldList;
4902 } /* End __DtHelpCeProcessString */
4904 /*****************************************************************************
4905 * Function: int __DtHelpCeGetParagraphList (
4909 * Returns: 0 if successful, -1 if errors.
4913 * Purpose: _DtHelpFormatGetParagraphList places a terminator on the
4914 * last segment in the current paragraph and returns the
4915 * segment list included in the topic information structure.
4917 * If make_cont is true, the segment list is first included
4918 * in a container with the specified type.
4920 *****************************************************************************/
4922 __DtHelpCeGetParagraphList (
4923 VarHandle var_handle,
4925 _DtCvFrmtOption type,
4926 _DtCvTopicPtr *ret_handle)
4929 FormatVariables *myVars = (FormatVariables *) var_handle;
4930 _DtCvTopicInfo *topicHandle;
4933 * check the parameters.
4935 if (ret_handle == NULL || myVars == NULL)
4941 TerminateSegList(&(myVars->my_list), True);
4943 topicHandle = (_DtCvTopicInfo *) malloc (sizeof(_DtCvTopicInfo));
4944 if (topicHandle != NULL)
4948 if (True == make_cont)
4950 _DtCvSegment *myCont = AllocateSegments(NULL, 0, 1);
4954 myCont->type = _DtCvSetTypeToContainer(myCont->type);
4955 _DtCvContainerTypeOfSeg(myCont) = type;
4956 _DtCvContainerListOfSeg(myCont) = myVars->my_list.list;
4958 myVars->my_list.list = myCont;
4959 myVars->my_list.cnt = 1;
4960 myVars->my_list.max = 1;
4966 topicHandle->id_str = NULL;
4967 topicHandle->seg_list = myVars->my_list.list;
4968 topicHandle->mark_list = NULL;
4969 topicHandle->link_data = myVars->my_links;
4971 *ret_handle = (_DtCvTopicPtr) topicHandle;
4974 if (myVars->fmt_buf != NULL)
4975 free(myVars->fmt_buf);
4980 /******************************************************************************
4981 * Function: int _DtHelpCeFrmtCcdfTopic (_DtHelpVolumeHdl volume, char *filename,
4982 * int offset, char *id_string,
4983 * _DtCvTopicPtr *ret_handle)
4986 * volume Specifies the Help Volume the information
4987 * is associated with.
4988 * filename Specifies the file containing the Help Topic
4990 * offset Specifies the offset into 'filename' to
4991 * the Help Topic desired.
4992 * id_string Specifies the location id to look for or NULL.
4993 * ret_handle Returns a handle to the topic information
4994 * including the number of paragraphs and the
4997 * Returns: 0 if successful, -1 if errors
5001 * Purpose: _DtHelpCeFrmtCcdfTopic formats Help Files with formatting
5002 * information into a Canvas Engine structure.
5004 ******************************************************************************/
5006 _DtHelpCeFrmtCcdfTopic(
5007 _DtHelpVolumeHdl volume,
5011 _FrmtUiInfo *ui_info,
5012 _DtCvTopicPtr *ret_handle )
5016 FormatVariables variables;
5019 * Check the parameters
5021 if (volume == NULL || filename == NULL || offset < 0 || ret_handle == NULL)
5028 * get the current file path.
5030 variables = DefVars;
5031 variables.topic_id = id_string;
5034 variables.vol_name = _DtHelpCeGetVolumeName(volume);
5035 variables.my_path = strdup (variables.vol_name);
5036 if (variables.my_path == NULL)
5039 result = _DtHelpCeStrrchr (variables.my_path, Slash, MB_CUR_MAX, &ptr);
5041 ptr = strrchr (variables.my_path, '/');
5048 * open the file and seek to the correct place.
5050 result = _DtHelpCeFileOpenAndSeek (filename, offset, -1,
5051 &(variables.my_file), NULL);
5055 * Initialize the X variables.
5057 result = Format (&variables, ui_info, id_string, ret_handle);
5059 _DtHelpCeBufFileClose (variables.my_file, True);
5062 if (variables.fmt_buf != NULL)
5063 free (variables.fmt_buf);
5065 if (variables.my_path != NULL)
5066 free (variables.my_path);
5070 } /* End _DtHelpCeFrmtCcdfTopic */
5072 /******************************************************************************
5073 * Function: int _DtHelpCeFrmtCcdfPathAndChildren (
5074 * _DtHelpVolumeHdl volume,
5075 * _DtCvTopicPtr *ret_handle)
5078 * ret_handle Returns a handle to the topic information
5079 * including the number of paragraphs and the
5082 * Returns: 0 if successful, -1 if errors, 1 if there the path is empty.
5086 * Purpose: _DtHelpCeFormatCcdfToc formats Table of Contents for
5089 ******************************************************************************/
5091 _DtHelpCeFrmtCcdfPathAndChildren(
5092 _DtHelpVolumeHdl volume,
5094 _FrmtUiInfo *ui_info,
5095 _DtCvTopicPtr *ret_handle )
5101 char readBuf[BUFF_SIZE];
5102 FormatVariables myVars;
5103 _DtHelpFontHints fontAttrs;
5105 _DtHelpCeCopyDefFontAttrList (&fontAttrs);
5106 fontAttrs.pointsz = 10;
5107 fontAttrs.weight = _DtHelpFontWeightMedium;
5108 fontAttrs.style = _DtHelpFontStyleSanSerif;
5111 * Check the parameters
5113 if (volume == NULL || ret_handle == NULL)
5121 if (InitStructure (&myVars, ui_info, readBuf, BUFF_SIZE) == -1)
5125 * get the list of topics in the volume.
5127 pathCnt = _DtHelpCeGetCcdfIdPath(volume, loc_id, &pathHead);
5132 * Check to see if this topic is in the topic list.
5133 * I.e. if a count of 1 is returned this should match the
5134 * top topic, otherwise this is an hidden topic.
5138 if (_DtHelpCeGetCcdfTopTopic(volume, &ptr) == -1)
5140 else if (_DtCvStrCaseCmpLatin1(ptr, *pathHead) != 0)
5145 * if result is non-zero, we had problems or this is a hidden topic
5149 fontAttrs.slant = _DtHelpFontSlantRoman;
5151 myVars.topic_id = loc_id;
5152 myVars.vol_name = _DtHelpCeGetVolumeName(volume);
5153 myVars.my_path = strdup (myVars.vol_name);
5154 if (myVars.my_path == NULL)
5157 if (-1 == _DtHelpCeStrrchr (myVars.my_path, Slash, MB_CUR_MAX, &ptr))
5158 ptr = strrchr (myVars.my_path, '/');
5163 result = FormatExpandedToc(volume, loc_id, pathHead,
5164 &myVars, fontAttrs, 0);
5165 _DtCvFreeArray((void **) pathHead);
5169 result = __DtHelpCeGetParagraphList (&myVars, False, _DtCvDYNAMIC,
5173 * check for an empty path.
5175 if (-1 != result && NULL == ((_DtCvTopicInfo *) *ret_handle)->seg_list)
5178 if (myVars.my_path != NULL)
5179 free(myVars.my_path);
5183 } /* End _DtHelpCeFrmtCcdfPathAndChildren */
5185 /******************************************************************************
5186 * Function: int _DtHelpCeGetCcdfTitleChunks (
5187 * _DtHelpVolumeHdl volume,
5188 * _DtCvTopicPtr *ret_handle)
5191 * ret_handle Returns a handle to the topic information
5192 * including the number of paragraphs and the
5195 * Returns: 0 if successful, -1 if errors
5199 * Purpose: _DtHelpCeFormatCcdfToc formats Table of Contents for
5202 ******************************************************************************/
5204 _DtHelpCeGetCcdfTitleChunks(
5205 _DtHelpVolumeHdl volume,
5207 _FrmtUiInfo *ui_info,
5215 char readBuf[BUFF_SIZE];
5216 _DtCvSegment *titleSeg;
5217 _DtCvSegment *list = NULL;
5218 FormatVariables myVars;
5219 _DtHelpFontHints fontAttrs;
5220 _DtHelpCeLockInfo lockInfo;
5223 * Check the parameters
5225 if (volume == NULL || ret_chunks == NULL)
5232 * init the return value
5237 * get the topic in the volume.
5239 if (_DtHelpCeLockVolume(volume, &lockInfo) != 0)
5242 if (_DtHelpCeFindId(volume, loc_id, -1, &fileName, &offset) == False)
5244 _DtHelpCeUnlockVolume(lockInfo);
5248 _DtHelpCeCopyDefFontAttrList (&fontAttrs);
5250 if (InitStructure (&myVars, ui_info, readBuf, BUFF_SIZE) == -1)
5252 _DtHelpCeUnlockVolume(lockInfo);
5257 * initialize my variables.
5259 myVars.topic_id = loc_id;
5260 myVars.vol_name = _DtHelpCeGetVolumeName(volume);
5261 myVars.my_path = strdup (myVars.vol_name);
5262 if (myVars.my_path == NULL)
5264 _DtHelpCeUnlockVolume(lockInfo);
5268 if (-1 == _DtHelpCeStrrchr (myVars.my_path, Slash, MB_CUR_MAX, &ptr))
5269 ptr = strrchr (myVars.my_path, '/');
5274 result = FormatCCDFTitle(&myVars, fontAttrs, fileName,
5275 offset, 0, (1 << _CEFONT_SIZE), True);
5278 if (-1 != result && 0 < myVars.my_list.cnt)
5280 titleSeg = &(myVars.my_list.list[myVars.my_list.cnt - 1]);
5281 list = _DtCvContainerListOfSeg(titleSeg);
5284 if (result != -1 && NULL != list)
5286 _DtCvSegment *pSeg = list;
5288 while (-1 != result && NULL != pSeg)
5291 * create the types and add the informatio to the array.
5293 type = DT_HELP_CE_FONT_PTR | DT_HELP_CE_STRING;
5294 if (_DtCvIsSegNewLine(pSeg))
5295 type |= DT_HELP_CE_NEWLINE;
5297 if (_DtCvIsSegString(pSeg))
5299 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5301 if (NULL != *ret_chunks)
5302 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5303 (void *) _DtCvFontOfStringSeg(pSeg));
5305 if (NULL != *ret_chunks)
5307 if (_DtCvIsSegWideChar(pSeg))
5309 offset = _DtCvStrLen(_DtCvStringOfStringSeg(pSeg), 1)
5311 ptr = (char *) malloc (sizeof(char) * offset);
5314 (wchar_t *)_DtCvStringOfStringSeg(pSeg),
5318 ptr = strdup((char *) _DtCvStringOfStringSeg(pSeg));
5321 *ret_chunks = (void **)_DtCvAddPtrToArray(
5322 *ret_chunks, (void *) ptr);
5325 if (NULL == *ret_chunks || NULL == ptr)
5330 * go to the next segment
5332 pSeg = pSeg->next_seg;
5339 int idLen = strlen (loc_id) + 9;
5342 * create the location id string.
5344 idStr = (char *) malloc (idLen);
5348 * format the location id
5350 strcpy (idStr, "...(");
5351 strcat (idStr, loc_id);
5352 strcat (idStr, ")...");
5355 * format the language and codeset
5357 strcpy(buf, _DtHelpFontHintsLang(fontAttrs));
5359 strcpy(buf, _DtHelpFontHintsCharSet(fontAttrs));
5362 * creat a chunk table
5364 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5365 (void *) (DT_HELP_CE_CHARSET | DT_HELP_CE_STRING));
5366 if (NULL != *ret_chunks)
5367 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5368 (void *) strdup(buf));
5369 if (NULL != *ret_chunks)
5370 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5375 if (NULL != *ret_chunks)
5376 *ret_chunks = (void **) _DtCvAddPtrToArray(*ret_chunks,
5377 (void *) DT_HELP_CE_END);
5382 if (0 < myVars.my_list.cnt)
5383 _DtHelpFreeSegments(myVars.my_list.list, _DtCvFALSE,
5384 ui_info->destroy_region,
5385 ui_info->client_data);
5388 * free the link database
5390 _DtLinkDbDestroy(myVars.my_links);
5395 if (myVars.my_path != NULL)
5396 free(myVars.my_path);
5397 if (myVars.fmt_buf != NULL)
5398 free(myVars.fmt_buf);
5400 _DtHelpCeUnlockVolume(lockInfo);
5403 * indicate an error if problems.
5406 if (NULL == *ret_chunks)
5411 } /* End _DtHelpCeGetCcdfTitleChunks */
5413 /******************************************************************************
5414 * Function: int _DtHelpCeGetCcdfVolTitleChunks (
5415 * _DtHelpVolumeHdl volume,
5416 * void ***ret_chunks)
5419 * ret_chunks Returns a ptr to the title information chunks
5420 * The title chunks are stored in allocated memory
5421 * that is owned by the caller and should be
5422 * freed when no longer needed.
5425 * Returns: 0 if successful, -1 if errors
5429 * Purpose: _DtHelpCeFormatCcdfVolTitleChunks formats volume title for
5432 ******************************************************************************/
5434 _DtHelpCeGetCcdfVolTitleChunks(
5435 _DtHelpVolumeHdl volume,
5436 _FrmtUiInfo *ui_info,
5443 * get the title of the volume (we own the memory).
5445 charSet = _DtHelpCeGetCcdfVolLocale(volume);
5446 if (charSet == NULL)
5447 charSet = strdup("C.ISO-8859-1");
5449 titleStr = _DtHelpCeGetCcdfVolTitle(volume);
5450 if (titleStr != NULL)
5452 *ret_chunks = (void **) malloc(sizeof(void *) * 4);
5453 if (*ret_chunks == NULL)
5456 (*ret_chunks)[0] = (void *) (DT_HELP_CE_CHARSET | DT_HELP_CE_STRING);
5457 (*ret_chunks)[1] = (void *) strdup(charSet);
5458 (*ret_chunks)[2] = (void *) strdup(titleStr);
5459 (*ret_chunks)[3] = (void *) DT_HELP_CE_END;
5464 if (_DtHelpCeGetCcdfTitleChunks(volume, "_title",
5465 ui_info, ret_chunks) != 0
5467 _DtHelpCeGetCcdfTitleChunks(volume, "_hometopic",
5468 ui_info, ret_chunks) != 0)
5474 } /* End _DtHelpCeGetCcdfVolTitleChunks */