FileUtils.c: fix CERT VU#575804
[oweals/cde.git] / cde / lib / DtHelp / FormatSDL.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
23 /* $TOG: FormatSDL.c /main/18 1999/10/14 13:18:42 mgreess $ */
24 /************************************<+>*************************************
25  ****************************************************************************
26  **
27  **   File:        FormatSDL.c
28  **
29  **   Project:     CDE Help System
30  **
31  **   Description: This code formats information in an SDL volume into
32  **                an into internal format.
33  **
34  **  (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
35  **
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.
40  **
41  ****************************************************************************
42  ************************************<+>*************************************/
43
44 /*
45  * system includes
46  */
47 #include <ctype.h>
48 #include <limits.h>
49 #include <string.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <sys/stat.h>
53
54 /*
55  * Core Engine includes
56  */
57 #include "CanvasP.h"
58 #include "CanvasSegP.h"
59 #include "LinkMgrP.h"
60
61 /*
62  * private includes
63  */
64 #include "bufioI.h"
65 #include "CanvasOsI.h"
66 #include "CleanUpI.h"
67 #include "CvStringI.h"
68 #include "CvtToArrayP.h"
69 #include "FontAttrI.h"
70 #include "Access.h"
71 #include "AccessI.h"
72 #include "AccessSDLP.h"
73 #include "AccessSDLI.h"
74 #include "FormatUtilI.h"
75 #include "FormatSDLI.h"
76 #include "StringFuncsI.h"
77 #include "SDLI.h"
78 #include "UtilSDLI.h"
79 #include "RegionI.h"
80
81 #ifdef NLS16
82 #endif
83
84 /******************************************************************************
85  * Private structures
86  ******************************************************************************/
87 typedef struct  _snbLinkInfo {
88         SDLCdata        xid;            /* also used for data & command */
89         SDLCdata        format;
90         SDLCdata        method;
91         SDLNumber       offset;
92 } SnbLinkInfo;
93
94 typedef struct  _elementInfo {
95         unsigned long           enum_values;
96         unsigned long           num_values;
97         unsigned long           str1_values;
98         unsigned long           str2_values;
99
100         enum SdlElement el_type;        /* the current element     */
101         SdlOption       timing;         /* the current timing type */
102         SdlOption       sdl_type;       /* dynamic, lined, literal, etc */
103         SdlOption       window;
104         SdlOption       interp;
105         union
106           {
107             SDLNumber   count;
108             SDLNumber   offset;
109           } nums;
110         SDLCdata        language;
111         SDLCdata        char_set;
112         SDLCdata        id;
113         SDLCdata        elstr1;
114         SDLCdata        elstr2;
115         union
116           {
117             SDLDocInfo  doc_info;       /* <sdldoc> */
118             SDLIdInfo   id_info;        /* <id>     */
119             SnbLinkInfo snb_info;       /* <callback>, <crossdoc>,
120                                            <man-page>, <textfile>, <sys-cmd> */
121             _DtCvSegment   *table_info;    /* <form>   */
122             SDLEntryInfo entry_info;    /* <entry */
123           } w;
124         SdlMatchData    match;
125 } ElementInfo, *ElementInfoPtr;
126
127 typedef struct _unresSnref {
128         int              cur_link;
129         char            *id;
130         _DtCvSegment    *seg;
131         _DtHelpFontHints fonts;
132 } UnresSnref;
133
134 typedef struct _formatStruct {
135         _DtCvValue       end_flag;
136         _DtCvValue       last_was_space;
137         _DtCvValue       last_was_mb;
138         _DtCvValue       last_was_nl;
139         _DtCvValue       snref_used;
140         _DtCvValue       faked_end;
141         _DtCvValue       save_snref;
142         _DtCvValue       save_blank;
143         _SdlFontMode     resolve_font;
144         enum SdlElement  parsed;
145         char            *remember;
146         char            *vol_name;
147         char            *id_string;
148         int              cur_link;
149         int              mb_len;
150         int              flags;
151         int              malloc_size;
152         int              alloc_size;
153         int              free_cnt;
154         int              free_max;
155         int              snref_cnt;
156         const _FrmtUiInfo *ui_info;
157         _DtCvSegment    *block_list;
158         _DtCvSegment       *add_seg;
159         _DtCvSegment       *last_seg;
160         _DtCvSegment       *seg_list;
161         _DtCvSegment       *prev_data;
162         _DtCvSegment       *toss;
163         _DtCvSegment       *async_blks;
164         _DtCvSegment       *snb;
165         _DtCvSegment       *else_prev;
166         _DtCvSegment       *then_prev;
167         _DtCvContainer  *active_frmt;
168         _DtCvLinkDb      my_links;
169         ElementInfo      el_info;
170         _DtHelpFontHints        *my_fonts;
171         _DtHelpFontHints        **free_fonts;
172         UnresSnref              *un_snrefs;
173         BufFilePtr       my_file;
174 } FormatStruct;
175
176 /******************************************************************************
177  * Private Function Declarations
178  ******************************************************************************/
179 static  int     AddRowToTable(
180                         FormatStruct    *my_struct,
181                         SDLMask         *element_types,
182                         enum SdlElement  sig_element,
183                         SDLMask         *exceptions,
184                         SDLMask         *process_mask);
185 static  int     AllocateBlock(
186                         FormatStruct    *my_struct,
187                         SDLMask         *element_types,
188                         enum SdlElement  sig_element,
189                         SDLMask         *exceptions,
190                         SDLMask         *process_mask);
191 static  int     Cdata(
192                         FormatStruct    *my_struct,
193                         SDLMask         *element_types,
194                         enum SdlElement  sig_element,
195                         SDLMask         *exceptions,
196                         SDLMask         *process_mask);
197 static  int     CheckForSnb(
198                         FormatStruct    *my_struct,
199                         SDLMask         *element_types,
200                         enum SdlElement  sig_element,
201                         SDLMask         *exceptions,
202                         SDLMask         *process_mask);
203 static  int     CheckType(
204                         FormatStruct    *my_struct,
205                         SDLMask         *element_types,
206                         enum SdlElement  sig_element,
207                         SDLMask         *exceptions,
208                         SDLMask         *process_mask);
209 static  int     CleanUpBlock(
210                         FormatStruct    *my_struct,
211                         SDLMask         *element_types,
212                         enum SdlElement  sig_element,
213                         SDLMask         *exceptions,
214                         SDLMask         *process_mask);
215 static  int     ClearAndCheckSnref(
216                         FormatStruct    *my_struct,
217                         SDLMask         *element_types,
218                         enum SdlElement  sig_element,
219                         SDLMask         *exceptions,
220                         SDLMask         *process_mask);
221 static  int     ColInfoToTableInfo(
222                         FormatStruct    *my_struct,
223                         SDLMask         *element_types,
224                         enum SdlElement  sig_element,
225                         SDLMask         *exceptions,
226                         SDLMask         *process_mask);
227 static  int     CopyAnchorId(
228                         FormatStruct    *my_struct,
229                         SDLMask         *element_types,
230                         enum SdlElement  sig_element,
231                         SDLMask         *exceptions,
232                         SDLMask         *process_mask);
233 static  int     CopyDocInfo(
234                         FormatStruct    *my_struct,
235                         SDLMask         *element_types,
236                         enum SdlElement  sig_element,
237                         SDLMask         *exceptions,
238                         SDLMask         *process_mask);
239 static  int     CopyIdInfo(
240                         FormatStruct    *my_struct,
241                         SDLMask         *element_types,
242                         enum SdlElement  sig_element,
243                         SDLMask         *exceptions,
244                         SDLMask         *process_mask);
245 static  int     ResolveSpcInfo(
246                         FormatStruct    *my_struct,
247                         SDLMask         *element_types,
248                         enum SdlElement  sig_element,
249                         SDLMask         *exceptions,
250                         SDLMask         *process_mask);
251 static  int     CopyEntryInfo(
252                         FormatStruct    *my_struct,
253                         SDLMask         *element_types,
254                         enum SdlElement  sig_element,
255                         SDLMask         *exceptions,
256                         SDLMask         *process_mask);
257 static  int     CopyTossInfo(
258                         FormatStruct    *my_struct,
259                         SDLMask         *element_types,
260                         enum SdlElement  sig_element,
261                         SDLMask         *exceptions,
262                         SDLMask         *process_mask);
263 static  int     FakeEnd(
264                         FormatStruct    *my_struct,
265                         SDLMask         *element_types,
266                         enum SdlElement  sig_element,
267                         SDLMask         *exceptions,
268                         SDLMask         *process_mask);
269 static  _DtCvSegment  *FindSnbEntry(
270                         _DtCvSegment     *snb,
271                         char             *target);
272 static  char    *GetInterpCmd(SdlOption interp_type);
273 static  int     IfInfo(
274                         FormatStruct    *my_struct,
275                         SDLMask         *element_types,
276                         enum SdlElement  sig_element,
277                         SDLMask         *exceptions,
278                         SDLMask         *process_mask);
279 static  int     InitLast(
280                         FormatStruct    *my_struct,
281                         SDLMask         *element_types,
282                         enum SdlElement  sig_element,
283                         SDLMask         *exceptions,
284                         SDLMask         *process_mask);
285 static  int     LoadGraphic(
286                         FormatStruct    *my_struct,
287                         SDLMask         *element_types,
288                         enum SdlElement  sig_element,
289                         SDLMask         *exceptions,
290                         SDLMask         *process_mask);
291 static  int     MarkFound(
292                         FormatStruct    *my_struct,
293                         SDLMask         *element_types,
294                         enum SdlElement  sig_element,
295                         SDLMask         *exceptions,
296                         SDLMask         *process_mask);
297 static  int     OnlyOne(
298                         FormatStruct    *my_struct,
299                         SDLMask         *element_types,
300                         enum SdlElement  sig_element,
301                         SDLMask         *exceptions,
302                         SDLMask         *process_mask);
303 static  int     OnlyOneEach(
304                         FormatStruct    *my_struct,
305                         SDLMask         *element_types,
306                         enum SdlElement  sig_element,
307                         SDLMask         *exceptions,
308                         SDLMask         *process_mask);
309 static  int     OneToN(
310                         FormatStruct    *my_struct,
311                         SDLMask         *element_types,
312                         enum SdlElement  sig_element,
313                         SDLMask         *exceptions,
314                         SDLMask         *process_mask);
315 static  int     ParseSDL(
316                         FormatStruct    *my_struct,
317                         enum SdlElement  cur_element,
318                         enum SdlElement  sig_element,
319                         SDLMask         *cur_except,
320                         SDLMask         *process_mask);
321 static  int     ProcessEnterAttr(
322                         FormatStruct    *my_struct,
323                         SDLMask         *element_types,
324                         enum SdlElement  sig_element,
325                         SDLMask         *cur_except,
326                         SDLMask         *process_mask);
327 static  int     ProcessExitAttr(
328                         FormatStruct    *my_struct,
329                         SDLMask         *element_types,
330                         enum SdlElement  sig_element,
331                         SDLMask         *cur_except,
332                         SDLMask         *process_mask);
333 static  int     ProcessSDLMarkup(
334                         FormatStruct    *my_struct,
335                         enum SdlElement  cur_element,
336                         enum SdlElement  sig_element,
337                         SDLMask         *cur_except,
338                         SDLMask         *process_mask);
339 static  int     RegisterLink(
340                         FormatStruct    *my_struct,
341                         SDLMask         *element_types,
342                         enum SdlElement  sig_element,
343                         SDLMask         *exceptions,
344                         SDLMask         *process_mask);
345 static  int     RegisterSnbLink(
346                         FormatStruct    *my_struct,
347                         SDLMask         *element_types,
348                         enum SdlElement  sig_element,
349                         SDLMask         *exceptions,
350                         SDLMask         *process_mask);
351 static  int     RegisterSwitch(
352                         FormatStruct    *my_struct,
353                         SDLMask         *element_types,
354                         enum SdlElement  sig_element,
355                         SDLMask         *exceptions,
356                         SDLMask         *process_mask);
357 static  int     ResolveIf(
358                         FormatStruct    *my_struct,
359                         _DtCvSegment    *prev_data);
360 static  int     SaveItemInfo(
361                         FormatStruct    *my_struct,
362                         SDLMask         *element_types,
363                         enum SdlElement  sig_element,
364                         SDLMask         *exceptions,
365                         SDLMask         *process_mask);
366 static  int     SaveLangCharSet(
367                         FormatStruct    *my_struct,
368                         SDLMask         *element_types,
369                         enum SdlElement  sig_element,
370                         SDLMask         *exceptions,
371                         SDLMask         *process_mask);
372 static  int     SetSaveSnref(
373                         FormatStruct    *my_struct,
374                         SDLMask         *element_types,
375                         enum SdlElement  sig_element,
376                         SDLMask         *exceptions,
377                         SDLMask         *process_mask);
378 static  int     SetTransit(
379                         FormatStruct    *my_struct,
380                         SDLMask         *element_types,
381                         enum SdlElement  sig_element,
382                         SDLMask         *exceptions,
383                         SDLMask         *process_mask);
384 static  int     SetType(
385                         FormatStruct    *my_struct,
386                         SDLMask         *element_types,
387                         enum SdlElement  sig_element,
388                         SDLMask         *exceptions,
389                         SDLMask         *process_mask);
390 static  int     ZeroOrOne(
391                         FormatStruct    *my_struct,
392                         SDLMask         *element_types,
393                         enum SdlElement  sig_element,
394                         SDLMask         *exceptions,
395                         SDLMask         *process_mask);
396 static  int     ZeroToN(
397                         FormatStruct    *my_struct,
398                         SDLMask         *element_types,
399                         enum SdlElement  sig_element,
400                         SDLMask         *exceptions,
401                         SDLMask         *process_mask);
402
403 /********    End Public Function Declarations    ********/
404
405 /******************************************************************************
406  * Private Defines
407  *****************************************************************************/
408 #define GROW_SIZE               5
409 #define MAX_ATTRIBUTE_LENGTH    30
410
411 /******************************************************************************
412  * Private Macros
413  *****************************************************************************/
414 #define DefPercent      10000
415
416 #define ElCharSet(x)    ((x)->el_info.char_set)
417 #define ElClan(x)       ((x)->el_info.match.clan)
418 #define ElCount(x)      ((x)->el_info.nums.count)
419 #define ElFlag1(x)      ((x)->el_info.enum_values)
420 #define ElFlag2(x)      ((x)->el_info.num_values)
421 #define ElFlag3(x)      ((x)->el_info.str1_values)
422 #define ElFlag4(x)      ((x)->el_info.str2_values)
423 #define ElFrmtType(x)   ((x)->el_info.sdl_type)
424 #define ElId(x)         ((x)->el_info.id)
425 #define ElInterp(x)     ((x)->el_info.interp)
426 #define ElLanguage(x)   ((x)->el_info.language)
427 #define ElLevel(x)      ((x)->el_info.match.level)
428 #define ElOffset(x)     ((x)->el_info.nums.offset)
429 #define ElSsi(x)        ((x)->el_info.match.ssi)
430 #define ElTiming(x)     ((x)->el_info.timing)
431 #define ElType(x)       ((x)->el_info.el_type)
432 #define ElWindow(x)     ((x)->el_info.window)
433
434 #define ElInfoClan(x)   ((x)->match.clan)
435
436 #define ElDocInfo(x)    ((x)->el_info.w.doc_info)
437 #define ElEntryInfo(x)  ((x)->el_info.w.entry_info)
438 #define ElIdInfo(x)     ((x)->el_info.w.id_info)
439 #define ElSnbXid(x)     ((x)->el_info.w.snb_info.xid)
440 #define ElSnbFormat(x)  ((x)->el_info.w.snb_info.format)
441 #define ElSnbMethod(x)  ((x)->el_info.w.snb_info.method)
442 #define ElSwitchBranches(x)     ((x)->el_info.elstr1)
443
444 #define ElTable(x)              ((x)->el_info.w.table_info)
445 #define ElTableCellIds(x) \
446                         _DtCvCellIdsOfTableSeg(((x)->el_info.w.table_info))
447 #define ElTableColNum(x) \
448                         _DtCvNumColsOfTableSeg(((x)->el_info.w.table_info))
449 #define ElTableColWidths(x) \
450                         _DtCvColWOfTableSeg(((x)->el_info.w.table_info))
451 #define ElTableColJust(x) \
452                         _DtCvColJustifyOfTableSeg(((x)->el_info.w.table_info))
453 #define ElTableList(x) \
454                         _DtCvCellsOfTableSeg(((x)->el_info.w.table_info))
455
456 #define ElString1(x)            ((x)->el_info.elstr1)
457 #define ElString2(x)            ((x)->el_info.elstr2)
458
459 #define ElAbbrev(x)             ((x)->el_info.elstr1)
460
461 #define ElEnter(x)              ((x)->el_info.elstr1)
462 #define ElExit(x)               ((x)->el_info.elstr2)
463
464 #define ElSpcName(x)            ((x)->el_info.elstr1)
465 #define ElTableCellId(x)        ((x)->el_info.elstr1)
466
467 #define ElTableColJStr(x)       ((x)->el_info.elstr1)
468 #define ElTableColWStr(x)       ((x)->el_info.elstr2)
469
470 #define SnbOffset(x)    ((x)->offset)
471
472 #define BMarginOfSeg(x)         _DtCvContainerBMarginOfSeg(x)
473 #define TMarginOfSeg(x)         _DtCvContainerTMarginOfSeg(x)
474
475 #define MySaveString(seg_list,my_struct,string,cur_link,multi_len,nl_flag)\
476         _DtHelpCeSaveString(my_struct->ui_info->client_data,    \
477                                 seg_list,                       \
478                                 &(my_struct->last_seg),         \
479                                 &(my_struct->prev_data),        \
480                                 string,                         \
481                                 my_struct->my_fonts,            \
482                                 cur_link,                       \
483                                 multi_len,                      \
484                                 my_struct->flags,               \
485                                 my_struct->ui_info->load_font,  \
486                                 my_struct->resolve_font,        \
487                                 nl_flag)
488
489 #define SDL_WRAPPER             _DtCvAPP_FLAG1
490 #define SetSdlWrapper(x)        _DtCvSetAppFlag1(x)
491 #define IsSdlWrapper(x)         ((x) & SDL_WRAPPER)
492
493 #define SetDupFlag(x) \
494                 (FrmtPrivInfoPtr(x)->dup_flag = True)
495 #define ClearDupFlag(x) \
496                 (FrmtPrivInfoPtr(x)->dup_flag = False)
497
498 #define AbbrevOfSeg(x)                  ((FrmtPrivInfoPtr(x))->abbrev)
499 #define ContainerPtrToType(x)           ((x)->type)
500 #define ContainerPtrToVJustify(x)       ((x)->vjustify)
501 #define ContainerPtrToJustify(x)        ((x)->justify)
502 #define ClearSegLinks(x) \
503                 (((x)->type) & ~(_DtCvHYPER_TEXT | _DtCvGHOST_LINK))
504 #define SegMatchData(x)                 ((FrmtPrivInfoPtr(x))->match_info)
505 #define SegMatchDataPtr(x)              ((SdlMatchData *) SegMatchData(x))
506
507 /******************************************************************************
508  * Private Strings
509  *****************************************************************************/
510 static const    char    AllStr[]          = "all";
511 static const    char    AnchorStr[]       = "<anchor";
512 static const    char    AnimateStr[]      = "<animate";
513 static const    char    ASyncStr[]        = "async";
514 static const    char    AudioStr[]        = "<audio";
515 static const    char    BlockStr[]        = "<block";
516 static const    char    ButtonStr[]       = "button";
517 static const    char    CallbackStr[]     = "<callback";
518 static const    char    CenterJustifyStr[]= "center-justify";
519 static const    char    CenterOrientStr[] = "center-orient";
520 static const    char    CParaStr[]        = "<cp";
521 static const    char    CrossdocStr[]     = "<crossdoc";
522 static const    char    DynamicStr[]      = "dynamic";
523 static const    char    GraphicStr[]      = "<graphic";
524 static const    char    FormStr[]         = "<form";
525 static const    char    HeadStr[]         = "<head";
526 static const    char    IsoStr[]          = "ISO-8859-1";
527 static const    char    LeftJustifyStr[]  = "left-justify";
528 static const    char    ManpageStr[]      = "<man-page";
529 static const    char    NameStr[]         = "name";
530 static const    char    NegativeOneStr[]  = "-1";
531 static const    char    NoBorderStr[]     = "no-border";
532 static const    char    OneStr[]          = "1";
533 static const    char    ProductStr[]      = "product";
534 static const    char    ParaStr[]         = "<p";
535 static const    char    ParentStr[]       = "parent";
536 static const    char    RightJustifyStr[] = "right-justify";
537 static const    char    ScriptStr[]       = "<script";
538 static const    char    SnrefStr[]        = "<snref";
539 static const    char    SubHeadStr[]      = "<subhead";
540 static const    char    SwitchStr[]       = "<switch";
541 static const    char    SyscmdStr[]       = "<sys-cmd";
542 static const    char    TenStr[]          = "10";
543 static const    char    TenThousandStr[]  = "10000";
544 static const    char    TextStr[]         = "<text";
545 static const    char    TextfileStr[]     = "<textfile";
546 static const    char    TopVJustStr[]     = "top-vjust";
547 static const    char    TopVOrientStr[]   = "top-vorient";
548 static const    char    UdefKeyStr[]      = "udefkey";
549 static const    char    VideoStr[]        = "<video";
550 static const    char    VirpageStr[]      = "<virpage";
551 static const    char    NoWrapStr[]       = "nowrap";
552 static const    char    ZeroStr[]         = "0";
553 static const    char    *NullOption       = "null_option";
554
555 static const    SDLMask AllMaskSet[SDL_MASK_LEN] = SDLSetAllBits;
556
557 static FormatStruct DefFormatStruct =
558     {
559         False,                  /* end_flag    */
560         True,                   /* last_was_space */
561         False,                  /* last_was_mb */
562         False,                  /* last_was_nl */
563         False,                  /* snref_used  */
564         False,                  /* faked_end   */
565         _DtCvFALSE,             /* save_snref  */
566         _DtCvFALSE,             /* save_blank  */
567         _SdlFontModeResolve,    /* resolve_font*/
568         SdlElementNone,         /* parsed      */
569         NULL,                   /* remember    */
570         NULL,                   /* vol_name    */
571         NULL,                   /* id_string   */
572         -1,                     /* cur_link    */
573          1,                     /* mb_len      */
574          0,                     /* flags       */
575          1,                     /* malloc_size */
576          0,                     /* alloc_size  */
577          0,                     /* free_cnt    */
578          0,                     /* free_max    */
579          0,                     /* snref_cnt   */
580         NULL,                   /* *ui_info    */
581         NULL,                   /* block_list  */
582         NULL,                   /* add_seg     */
583         NULL,                   /* last_seg    */
584         NULL,                   /* seg_list    */
585         NULL,                   /* prev_data   */
586         NULL,                   /* toss        */
587         NULL,                   /* snb         */
588         NULL,                   /* else_prev   */
589         NULL,                   /* then_prev   */
590         NULL,                   /* async_blks  */
591         NULL,                   /* active_frmt */
592         NULL,                   /* my_links    */
593           {                     /* ElementInfo   el_info; */
594             0,
595             0,
596             0,
597             0,
598             SdlElementNone,             /* enum SdlElement el_type    */
599             SdlTimingSync,              /* SdlOption       timing;    */
600             SdlTypeDynamic,             /* SdlOption       sdl_type   */
601             SdlWindowCurrent,           /* SdlOption       window;    */
602             SdlInterpKsh,               /* SdlOption       interp;    */
603             0,                          /* SDLNumber       count/offset; */
604             NULL,                       /* SDLCdata        language;  */
605             NULL,                       /* SDLCdata        char_set;  */
606             NULL,                       /* SDLCdata        id;        */
607             NULL,                       /* SDLCdata        elstr1;    */
608             NULL,                       /* SDLCdata        elstr2;    */
609               {                         /* SDLDocInfo      doc_info;  */
610                 NULL,                      /* SDLCdata     language;  */
611                 NULL,                      /* SDLCdata     char_set;  */
612                 NULL,                      /* SDLId        first_pg;  */
613                 NULL,                      /* SDLCdata     doc-id;    */
614                 NULL,                      /* SDLCdata     timestamp; */
615                 NULL,                      /* SDLCdata    sdldtd;    */
616               },
617               {                         /* SdlMatchData              */
618                 SdlClassText,               /* SdlOption   clan;  */
619                 -1,                         /* SDLNumber   level;     */
620                 NULL,                       /* SDLCdata    ssi;       */
621               },
622           },
623           NULL,                 /* _DtHelpFontHints      my_fonts;   */
624           NULL,                 /* _DtHelpFontHints      free_fonts; */
625           NULL,                 /* UnresSnref           *un_snregs;  */
626     };
627
628 static const    _DtHelpFontHints        DefFontInfo =
629   {
630         "C",                            /* char *language;  */
631         (char *)IsoStr,                 /* char *charset    */
632         10,                             /* int   pointsz;   */
633         10,                             /* int   set_width  */
634         NULL,                           /* char *color;     */
635         NULL,                           /* char *xlfd;      */
636         NULL,                           /* char *xlfdb;     */
637         NULL,                           /* char *xlfdi;     */
638         NULL,                           /* char *xlfdib;    */
639         NULL,                           /* char *typenam;   */
640         NULL,                           /* char *typenamb;  */
641         NULL,                           /* char *typenami;  */
642         NULL,                           /* char *typenamib; */
643         _DtHelpFontStyleSanSerif,       /* char *style;     */
644         _DtHelpFontSpacingMono,         /* char *spacing;   */
645         _DtHelpFontWeightMedium,        /* char *weight;    */
646         _DtHelpFontSlantRoman,          /* char *slant;     */
647         _DtHelpFontSpecialNone,         /* char *special;   */
648         NULL,               /* void     *expand;    */
649   };
650
651 static const    _DtCvContainer  DefFrmtSpecs =
652   {
653         NULL,                   /* char         *id       */
654         NULL,                   /* char         *justify_char */
655         _DtCvDYNAMIC,           /* _DtCvFrmtOption  type     */
656         _DtCvBORDER_NONE,       /* _DtCvFrmtOption  border   */
657         _DtCvINHERIT,           /* _DtCvFrmtOption  justify  */
658         _DtCvJUSTIFY_TOP,       /* _DtCvFrmtOption  vjustify */
659         _DtCvJUSTIFY_CENTER,    /* _DtCvFrmtOption  orient   */
660         _DtCvJUSTIFY_TOP,       /* _DtCvFrmtOption  vorient  */
661         _DtCvWRAP_NONE,         /* _DtCvFrmtOption  flow     */
662         DefPercent,             /* int           percent  */
663         0,                      /* _DtCvUnit        leading  */
664         0,                      /* _DtCvUnit        fmargin  */
665         0,                      /* _DtCvUnit        lmargin  */
666         0,                      /* _DtCvUnit        rmargin  */
667         0,                      /* _DtCvUnit        tmargin  */
668         0,                      /* _DtCvUnit        bmargin  */
669         {0, NULL},              /* _DtCvLine     bdr_info;      */
670         NULL,                   /* _DtCvSegment    *seg_list */
671   };
672
673 static  const   _FrmtUiInfo     DefUiInfo =
674   {
675         NULL,           /* load_graphic */
676         NULL,           /* resolve_spc  */
677         NULL,           /* load_font    */
678         NULL,           /* exec_filter  */
679         NULL,           /* destroy_region */
680         NULL,           /* client_data  */
681         0,              /* line_width   */
682         0,              /* line_height   */
683         0,              /* leading       */
684         0,              /* avg_char     */
685         True,           /* nl_to_space  */
686   };
687
688 /******************************************************************************
689  * Entity Defines
690  *****************************************************************************/
691 /*-----------------------------------------------------------------------------
692 <!ENTITY % system-notations "(graphic  | text     | audio    | video    |
693                               animate  | crossdoc | man-page | textfile |
694                               sys-cmd  | callback | script   | switch)" >
695 -----------------------------------------------------------------------------*/
696 #define SDL_ENTITY_SYSTEM_NOTATIONS \
697                 SDLInitMaskTwelve(SdlElementGraphic,   \
698                                         SdlElementText,     \
699                                         SdlElementAudio,    \
700                                         SdlElementVideo,    \
701                                         SdlElementAnimate,  \
702                                         SdlElementCrossDoc, \
703                                         SdlElementManPage,  \
704                                         SdlElementTextFile, \
705                                         SdlElementSysCmd,   \
706                                         SdlElementCallback, \
707                                         SdlElementScript,   \
708                                         SdlElementSwitch)
709
710 /*-----------------------------------------------------------------------------
711 <!ENTITY % generated-elements "(loids, toss?, lophrases?, index?, rel-docs?,
712                                 rel-file?, notes?)" >
713 -----------------------------------------------------------------------------*/
714 #define SDL_ENTITY_GENERATED_ELEMENTS \
715         { SDLInitMask(SdlElementLoids)    , OnlyOne   }, \
716         { SDLInitMask(SdlElementToss)     , ZeroOrOne }, \
717         { SDLInitMask(SdlElementLoPhrases), ZeroOrOne }, \
718         { SDLInitMask(SdlElementIndex)    , ZeroOrOne }, \
719         { SDLInitMask(SdlElementRelDocs)  , ZeroOrOne }, \
720         { SDLInitMask(SdlElementRelFile)  , ZeroOrOne }, \
721         { SDLInitMask(SdlElementNotes)    , ZeroOrOne },
722
723 /*-----------------------------------------------------------------------------
724 <!ENTITY % key-class    "acro       | book      | emph     | jargon     |
725                          l10n       | name      | quote    | product    |
726                          termdef    | term      | mach-in  | mach-out   |
727                          mach-cont  | pub-lit   | udefkey" >
728 -----------------------------------------------------------------------------*/
729 #define SDL_ENTITY_CLASSK \
730         { "acro"     , SdlClassAcro     }, \
731         { "book"     , SdlClassBook     }, \
732         { "emph"     , SdlClassEmph     }, \
733         { "jargon"   , SdlClassJargon   }, \
734         { "l10n"     , SdlClassL10n     }, \
735         { NameStr    , SdlClassName     }, \
736         { "quote"    , SdlClassQuote    }, \
737         { ProductStr , SdlClassProduct  }, \
738         { "termdef"  , SdlClassTermdef  }, \
739         { "term"     , SdlClassTerm     }, \
740         { "mach-in"  , SdlClassMachIn   }, \
741         { "mach-out" , SdlClassMachOut  }, \
742         { "mach-cont", SdlClassMachCont }, \
743         { "pub-lit"  , SdlClassPubLit   }, \
744         { UdefKeyStr , SdlClassUdefkey  }  
745 /*-----------------------------------------------------------------------------
746 <!ENTITY % head-class    "label     | head      | caption  | annotation |
747                           phead     | udefhead" >
748 -----------------------------------------------------------------------------*/
749 #define SDL_ENTITY_CLASSH \
750         { "label"     , SdlClassLabel      }, \
751         { (HeadStr+1) , SdlClassHead       }, \
752         { "caption"   , SdlClassCaption    }, \
753         { "annotation", SdlClassAnnotation }, \
754         { "phead"     , SdlClassPHead      }, \
755         { "udefhead"  , SdlClassUdefhead   }
756
757 /*-----------------------------------------------------------------------------
758 <!ENTITY % format-class  "table     | cell      | list     | item       |
759                           text      | udeffrmt" >
760 -----------------------------------------------------------------------------*/
761 #define SDL_ENTITY_CLASSF \
762         { "table"    , SdlClassTable    }, \
763         { "cell"     , SdlClassCell     }, \
764         { "list"     , SdlClassList     }, \
765         { "item"     , SdlClassItem     }, \
766         { (TextStr+1), SdlClassText     }, \
767         { "udeffrmt" , SdlClassUdeffrmt }
768
769 /*-----------------------------------------------------------------------------
770 <!ENTITY % graphic-class "figure    | in-line   | button   | icon       |
771                           udefgrph" >
772 -----------------------------------------------------------------------------*/
773 #define SDL_ENTITY_CLASSG \
774         { "figure"    , SdlClassFigure    }, \
775         { "in-line"   , SdlClassInLine    }, \
776         { ButtonStr   , SdlClassButton    }, \
777         { "icon"      , SdlClassIcon      }, \
778         { "udefgraph" , SdlClassUdefgraph }
779
780 /*-----------------------------------------------------------------------------
781 <!ENTITY % phrase-class  "( super   | sub )" >
782 -----------------------------------------------------------------------------*/
783 #define SDL_ENTITY_CLASSP \
784         { "super"   , SdlClassSuper }, \
785         { "sub"     , SdlClassSub   }
786
787 /*-----------------------------------------------------------------------------
788 <!ENTITY % font-styles
789            '-- height of font in points; main body is 10 point --
790             pointsz   NUMBER             #IMPLIED
791
792             -- width of font in points; defaults to point size --
793             -- similar to point size but refers to relative    --
794             -- width rather than height (e.g., an 8 point font --
795             -- based on a square would be 8 pt, 8 set)         --
796             set-width NUMBER             #IMPLIED
797
798             -- one of 42 CDE colors or "RGB:rrrr/gggg/bbbb"    --
799             color     CDATA              #IMPLIED
800
801             -- XLFD typeface name for use on X Window System   --
802             -- e.g., "-adobe-helvetica-bold-i-narrow-*-"       --
803             -- One each of normal, italic, bold and bold       --
804             -- italic must be specified.                       --
805             -- These should only be specified if the author is --
806             -- sure of exactly what font is desired.  In the   --
807             -- usual case, only the logical typeface spec.     --
808             -- defined below will be given.                    --
809             xlfd      CDATA              #IMPLIED
810             xlfdi     CDATA              #IMPLIED
811             xlfdb     CDATA              #IMPLIED
812             xlfdib    CDATA              #IMPLIED
813
814             -- MS-Windows typeface name (maximum of 32 chars)  --
815             -- One each of normal, italic, bold and bold       --
816             -- italic must be specified.                       --
817             -- As for the XLFD specification above, these      --
818             -- should only be provided if an author knows the  --
819             -- exact font desired.                             --
820             typenam   CDATA              #IMPLIED
821             typenami  CDATA              #IMPLIED
822             typenamb  CDATA              #IMPLIED
823             typenamib CDATA              #IMPLIED
824
825             -- Logical typeface spec (allows mapping into one  --
826             -- of the 13 PostScript typefaces).  This spec. is --
827             -- used if an exact match XLFD or Windows type-    --
828             -- face name attribute is missing or cannot be     --
829             -- found.  In the usual case, these will be        --
830             -- specified in preference to specifying an exact  --
831             -- font.                                           --
832
833             -- processor should default style to "sans-serif"  --
834             style     ( serif      |
835                         sans-serif |
836                         symbol     )     #IMPLIED
837
838             -- processor should deflt spacing to "monospace"   --
839             spacing   ( monospace  |
840                         propspace  )     #IMPLIED
841
842             -- processor should default weight to "medium"     --
843             weight    ( medium     |
844                         bold       )     #IMPLIED
845
846             -- processor should default slant to "roman"       --
847             slant     ( roman      |
848                         italic     |
849                         rev-italic )     #IMPLIED
850
851             -- processor should default special to "none"      --
852             special   ( underline  |
853                         strikeout  |
854                         none       )     #IMPLIED'             >
855
856 -----------------------------------------------------------------------------*/
857 #define font_stylesAttrList \
858         { SDL_ATTR_POINTSZ  , SdlAttrValueImplied , TenStr       }, \
859         { SDL_ATTR_SETWIDTH , SdlAttrValueImplied , TenStr       }, \
860         { SDL_ATTR_COLOR    , SdlAttrValueImpliedDef , NULL         }, \
861         { SDL_ATTR_XLFD     , SdlAttrValueImpliedDef , NULL         }, \
862         { SDL_ATTR_XLFDI    , SdlAttrValueImpliedDef , NULL         }, \
863         { SDL_ATTR_XLFDB    , SdlAttrValueImpliedDef , NULL         }, \
864         { SDL_ATTR_XLFDIB   , SdlAttrValueImpliedDef , NULL         }, \
865         { SDL_ATTR_TYPENAM  , SdlAttrValueImpliedDef , NULL         }, \
866         { SDL_ATTR_TYPENAMI , SdlAttrValueImpliedDef , NULL         }, \
867         { SDL_ATTR_TYPENAMB , SdlAttrValueImpliedDef , NULL         }, \
868         { SDL_ATTR_TYPENAMIB, SdlAttrValueImpliedDef , NULL         }, \
869         { SDL_ATTR_STYLE    , SdlAttrValueImplied , "sans-serif" }, \
870         { SDL_ATTR_SPACING  , SdlAttrValueImplied , "monospace"  }, \
871         { SDL_ATTR_WEIGHT   , SdlAttrValueImplied , "medium"     }, \
872         { SDL_ATTR_SLANT    , SdlAttrValueImplied , "roman"      }, \
873         { SDL_ATTR_SPECIAL  , SdlAttrValueImplied , "none"       }
874
875 /*-----------------------------------------------------------------------------
876 <!ENTITY % format-styles
877            '-- left and right margins are additive and measured    --
878             -- in character widths defaulting to "0"               --
879             l-margin  NUMBER             #IMPLIED
880             r-margin  NUMBER             #IMPLIED
881
882             -- top and bottom margins merely take the maximum and  --
883             -- are measured in lines defaulting to "0"             --
884             t-margin  NUMBER             #IMPLIED
885             b-margin  NUMBER             #IMPLIED
886
887             -- border specifies the decoration type                --
888             -- processor should default border to "no-border"      --
889             border   ( no-border         |
890                        full-border       |
891                        horizontal-border |
892                        vertical-border   |
893                        top-border        |
894                        bottom-border     |
895                        left-border       |
896                        right-border      ) #IMPLIED
897
898             -- applies to the text in the element, not the element --
899             -- itself.                                             --
900             -- processor should default vjust to "top-vjust"       --
901             vjust    ( top-vjust    |
902                        bottom-vjust |
903                        center-vjust )    #IMPLIED' >
904 -----------------------------------------------------------------------------*/
905 #define formt_stylesAttrList \
906         { SDL_ATTR_LMARGIN  , SdlAttrValueImplied , ZeroStr        }, \
907         { SDL_ATTR_RMARGIN  , SdlAttrValueImplied , ZeroStr        }, \
908         { SDL_ATTR_TMARGIN  , SdlAttrValueImplied , ZeroStr        }, \
909         { SDL_ATTR_BMARGIN  , SdlAttrValueImplied , ZeroStr        }, \
910         { SDL_ATTR_BORDER   , SdlAttrValueImplied , NoBorderStr    }, \
911         { SDL_ATTR_VJUST    , SdlAttrValueImplied , TopVJustStr    }
912
913 /*-----------------------------------------------------------------------------
914 <!ENTITY % linkage   "anchor | link" >
915 <!ENTITY % reference "snref"         >
916 <!ENTITY % simple    "key | sphrase | rev | if | spc | %reference;" >
917 -----------------------------------------------------------------------------*/
918 #define SDL_ENTITY_SIMPLE   \
919         SDLInitMaskSeven( \
920                         SdlElementKey   , SdlElementSphrase, SdlElementRev  , \
921                         SdlElementIf    , SdlElementSpc    , SdlElementSnRef, \
922                         SdlElementCdata)
923
924 /*-----------------------------------------------------------------------------
925 <!ENTITY % atomic    "( %simple; | %linkage; )" >
926 -----------------------------------------------------------------------------*/
927 #define SDL_ENTITY_ATOMIC \
928         SDLInitMaskNine( \
929                         SdlElementKey   , SdlElementSphrase, SdlElementRev   , \
930                         SdlElementIf    , SdlElementSpc    , SdlElementSnRef , \
931                         SdlElementAnchor, SdlElementLink   , SdlElementCdata)
932 /*-----------------------------------------------------------------------------
933 <!NOTATION tcl SYSTEM "embedded tcl interpreter">
934 <!NOTATION sh  SYSTEM "/bin/sh">
935 <!NOTATION csh SYSTEM "/bin/csh">
936 <!NOTATION ksh SYSTEM "/bin/ksh">
937 -----------------------------------------------------------------------------*/
938 typedef struct  _ceInterpData {
939         SdlOption        type;
940         char            *cmd;
941 } _CEInterpData;
942
943 static _CEInterpData    InterpData[] =
944     {
945         { SdlInterpKsh, "ksh" },
946         { SdlInterpCsh, "csh" },
947         { SdlInterpSh , "sh"  },
948         { SdlInterpTcl, "tcl" },
949         { _DtCvOPTION_BAD, NULL  },
950     };
951
952 /******************************************************************************
953  * Private Variables
954  *****************************************************************************/
955 static OptionList hclass[]  = { SDL_ENTITY_CLASSH, {NULL, _DtCvOPTION_BAD}};
956 static OptionList fclass[]  = { SDL_ENTITY_CLASSF, {NULL, _DtCvOPTION_BAD}};
957 static OptionList kclass[]  = { SDL_ENTITY_CLASSK, {NULL, _DtCvOPTION_BAD}};
958 static OptionList pclass[]  = { SDL_ENTITY_CLASSP, {NULL, _DtCvOPTION_BAD}};
959 static OptionList gclass[]  = { SDL_ENTITY_CLASSG, {NULL, _DtCvOPTION_BAD}};
960 static OptionList fgclass[] =
961         { SDL_ENTITY_CLASSF, SDL_ENTITY_CLASSG, {NULL, _DtCvOPTION_BAD}};
962
963 static OptionList apps[] =
964     {
965         { AllStr    , SdlAppAll      },
966         { "help"    , SdlAppHelp     },
967         { "tutorial", SdlAppTutorial },
968         { "ref"     , SdlAppRef      },
969         { "sys"     , SdlAppSys      },
970         {  NULL     , _DtCvOPTION_BAD   }
971     };
972 static OptionList timing[] =
973     {
974         { (ASyncStr+1), SdlTimingSync  },
975         { ASyncStr    , SdlTimingAsync },
976         {  NULL       , _DtCvOPTION_BAD   },
977     };
978
979 static OptionList frmtTypes[] =
980     {
981         { "literal" , SdlTypeLiteral },
982         { "lined"   , SdlTypeLined   },
983         { DynamicStr, SdlTypeDynamic },
984         {  NULL     , _DtCvOPTION_BAD   }
985     };
986
987 static OptionList idTypes[] =
988     {
989         { (VirpageStr+1) , SdlIdVirpage   },
990         { (BlockStr+1)   , SdlIdBlock     },
991         { (FormStr+1)    , SdlIdForm      },
992         { (ParaStr+1)    , SdlIdPara      },
993         { (CParaStr+1)   , SdlIdCPara     },
994         { (HeadStr+1)    , SdlIdHead      },
995         { (SubHeadStr+1) , SdlIdSubHead   },
996         { (AnchorStr+1)  , SdlIdAnchor    },
997         { (SwitchStr+1)  , SdlIdSwitch    },
998         { (SnrefStr+1)   , SdlIdSnRef     },
999         { (GraphicStr+1) , SdlIdGraphic   },
1000         { (TextStr+1)    , SdlIdText      },
1001         { (AudioStr+1)   , SdlIdAudio     },
1002         { (VideoStr+1)   , SdlIdVideo     },
1003         { (AnimateStr+1) , SdlIdAnimate   },
1004         { (CrossdocStr+1), SdlIdCrossDoc  },
1005         { (ManpageStr+1) , SdlIdManPage   },
1006         { (TextfileStr+1), SdlIdTextFile  },
1007         { (SyscmdStr+1)  , SdlIdSysCmd    },
1008         { (ScriptStr+1)  , SdlIdScript    },
1009         { (CallbackStr+1), SdlIdCallback  },
1010         { NULL           , _DtCvOPTION_BAD   },
1011     };
1012
1013 static OptionList bool_types[] =
1014     {
1015         { "YES", SdlBoolYes   },
1016         { "NO" , SdlBoolNo    },
1017         { NULL , _DtCvOPTION_BAD },
1018     };
1019
1020 static OptionList borders[] =
1021     {
1022         { NoBorderStr        , _DtCvBORDER_NONE   },
1023         { "full-border"      , _DtCvBORDER_FULL   },
1024         { "horizontal-border", _DtCvBORDER_HORZ   },
1025         { "vertical-border"  , _DtCvBORDER_VERT   },
1026         { "top-border"       , _DtCvBORDER_TOP    },
1027         { "bottom-border"    , _DtCvBORDER_BOTTOM },
1028         { "left-border"      , _DtCvBORDER_LEFT   },
1029         { "right-border"     , _DtCvBORDER_RIGHT  },
1030         { NULL               , _DtCvOPTION_BAD    },
1031     };
1032
1033 static OptionList justify1[] =
1034     {
1035         { LeftJustifyStr   , _DtCvJUSTIFY_LEFT   },
1036         { RightJustifyStr  , _DtCvJUSTIFY_RIGHT  },
1037         { CenterJustifyStr , _DtCvJUSTIFY_CENTER },
1038         { "numeric-justify", _DtCvJUSTIFY_NUM    },
1039         { NULL             , _DtCvOPTION_BAD    },
1040     };
1041
1042 static OptionList justify2[] =
1043     {
1044         { LeftJustifyStr   , _DtCvJUSTIFY_LEFT   },
1045         { RightJustifyStr  , _DtCvJUSTIFY_RIGHT  },
1046         { CenterJustifyStr , _DtCvJUSTIFY_CENTER },
1047         { NULL             , _DtCvOPTION_BAD    },
1048     };
1049
1050 static OptionList vjust[] =
1051     {
1052         { TopVJustStr   , _DtCvJUSTIFY_TOP    },
1053         { "bottom-vjust", _DtCvJUSTIFY_BOTTOM },
1054         { "center-vjust", _DtCvJUSTIFY_CENTER },
1055         { NULL          , _DtCvOPTION_BAD     },
1056     };
1057
1058 static OptionList orient[] =
1059     {
1060         { "left-orient"        , _DtCvJUSTIFY_LEFT        },
1061         { CenterOrientStr      , _DtCvJUSTIFY_CENTER      },
1062         { "right-orient"       , _DtCvJUSTIFY_RIGHT       },
1063         { "left-margin-orient" , _DtCvJUSTIFY_LEFT_MARGIN },
1064         { "right-margin-orient", _DtCvJUSTIFY_RIGHT_MARGIN},
1065         { "left-corner-orient" , _DtCvJUSTIFY_LEFT_CORNER },
1066         { "right-corner-orient", _DtCvJUSTIFY_RIGHT_CORNER},
1067         { NULL                 , _DtCvOPTION_BAD         },
1068     };
1069
1070 static OptionList vorient[] =
1071     {
1072         { TopVOrientStr   , _DtCvJUSTIFY_TOP    },
1073         { "bottom-vorient", _DtCvJUSTIFY_BOTTOM },
1074         { "center-vorient", _DtCvJUSTIFY_CENTER },
1075         { NULL            , _DtCvOPTION_BAD     },
1076     };
1077
1078 static OptionList placement[] =
1079     {
1080         { "object"     , SdlPlaceObject },
1081         { ParentStr    , SdlPlaceParent },
1082         {  NULL        , _DtCvOPTION_BAD   },
1083     };
1084
1085 static OptionList stacking[] =
1086     {
1087         { "horiz"  , SdlStackHoriz },
1088         { "vert"   , SdlStackVert  },
1089         {  NULL    , _DtCvOPTION_BAD  },
1090     };
1091
1092 static OptionList flow[] =
1093     {
1094         { (NoWrapStr+2), _DtCvWRAP       },
1095         {  NoWrapStr   , _DtCvWRAP_NONE  },
1096         {  "join"      , _DtCvWRAP_JOIN  },
1097         {  NULL        , _DtCvOPTION_BAD },
1098     };
1099
1100 static OptionList window[] =
1101     {
1102         { "current", SdlWindowCurrent },
1103         { "new"    , SdlWindowNew     },
1104         { "popup"  , SdlWindowPopup   },
1105         { NULL    , _DtCvOPTION_BAD },
1106     };
1107
1108 static OptionList traversal[] =
1109     {
1110         { "return"  , SdlTraversalReturn   },
1111         { "noreturn", SdlTraversalNoReturn },
1112         { NULL      , _DtCvOPTION_BAD         },
1113     };
1114
1115 static OptionList interpreters[] =
1116     {
1117         { "ksh"     , SdlInterpKsh },
1118         { "tcl"     , SdlInterpTcl },
1119         { "csh"     , SdlInterpCsh },
1120         { "sh"      , SdlInterpSh  },
1121         { NULL      , _DtCvOPTION_BAD },
1122     };
1123
1124 static  SDLAttributeOptions SDLOptionsList[] =
1125     {
1126         {SDL_ATTR_CLASSH   , hclass     },
1127         {SDL_ATTR_CLASSF   , fclass     },
1128         {SDL_ATTR_CLASSK   , kclass     },
1129         {SDL_ATTR_CLASSFG  , fgclass    },
1130         {SDL_ATTR_CLASSP   , pclass     },
1131         {SDL_ATTR_CLASSG   , gclass     },
1132         {SDL_ATTR_HDR      , bool_types },
1133         {SDL_ATTR_APP      , apps       },
1134         {SDL_ATTR_TIMING   , timing     },
1135         {SDL_ATTR_TYPEFRMT , frmtTypes  },
1136         {SDL_ATTR_BORDER   , borders    },
1137         {SDL_ATTR_JUSTIFY1 , justify1   },
1138         {SDL_ATTR_JUSTIFY2 , justify2   },
1139         {SDL_ATTR_VJUST    , vjust      },
1140         {SDL_ATTR_ORIENT   , orient     },
1141         {SDL_ATTR_VORIENT  , vorient    },
1142         {SDL_ATTR_PLACEMENT, placement  },
1143         {SDL_ATTR_STACK    , stacking   },
1144         {SDL_ATTR_FLOW     , flow       },
1145         {SDL_ATTR_WINDOW   , window     },
1146         {SDL_ATTR_TRAVERSAL, traversal  },
1147         {SDL_ATTR_TYPEID   , idTypes    },
1148         {SDL_ATTR_INTERP   , interpreters },
1149         {(unsigned long) -1, NULL       }
1150     };
1151
1152 static FontSpecOption styles[] =
1153     {
1154         { "serif"     , _DtHelpFontStyleSerif    },
1155         { "sans-serif", _DtHelpFontStyleSanSerif },
1156         { "symbol"    , _DtHelpFontStyleSymbol   },
1157         { NULL        , _DtHelpFontValueBad   },
1158     };
1159
1160 static FontSpecOption spacing[] =
1161     {
1162         { "monospace" , _DtHelpFontSpacingMono},
1163         { "propspace" , _DtHelpFontSpacingProp},
1164         { NULL        , _DtHelpFontValueBad   },
1165     };
1166
1167 static FontSpecOption weights[] =
1168     {
1169         { "medium"    , _DtHelpFontWeightMedium },
1170         { "bold"      , _DtHelpFontWeightBold   },
1171         { NULL        , _DtHelpFontValueBad  },
1172     };
1173
1174 static FontSpecOption slants[] =
1175     {
1176         { "roman"     , _DtHelpFontSlantRoman    },
1177         { "italic"    , _DtHelpFontSlantItalic   },
1178         { "rev-italic", _DtHelpFontSlantRevItalic},
1179         { NULL        , _DtHelpFontValueBad   },
1180     };
1181
1182 static FontSpecOption special[] =
1183     {
1184         { "none"      , _DtHelpFontSpecialNone      },
1185         { "underline" , _DtHelpFontSpecialUnderLine },
1186         { "strikeout" , _DtHelpFontSpecialStrikeOut },
1187         { NULL        , _DtHelpFontValueBad      },
1188     };
1189
1190 static  SDLFontSpecList SDLFontList[] =
1191     {
1192         {SDL_ATTR_STYLE    , styles     },
1193         {SDL_ATTR_SPACING  , spacing    },
1194         {SDL_ATTR_WEIGHT   , weights    },
1195         {SDL_ATTR_SLANT    , slants     },
1196         {SDL_ATTR_SPECIAL  , special    },
1197         {(unsigned long) -1, NULL       }
1198     };
1199
1200 /*
1201  * Make sure the attribute names are in lower case.
1202  * The read routine to find an attribute automatically changes it to lower
1203  * case.
1204  */
1205
1206 #ifndef _DtCvContainerPtr
1207 typedef _DtCvContainer *        _DtCvContainerPtr;
1208 #endif
1209
1210 #ifndef _DtCvSegmentPtr
1211 typedef _DtCvSegment *  _DtCvSegmentPtr;
1212 #endif
1213
1214 static  SDLAttribute  SDLAttributeList[] =
1215   {
1216     { "abbrev"        , SdlAttrDataTypeCdata , SdlElementSpecific,
1217                         SDL_ATTR_ABBREV   ,
1218                         SDLAttrOffset(ElementInfoPtr,elstr1)          },
1219
1220     { "app"           , SdlAttrDataTypeEnum  , SdlIgnore         ,
1221                         SDL_ATTR_APP    ,
1222                         NULL },
1223     { "author"        , SdlAttrDataTypeCdata , SdlIgnore         ,
1224                         SDL_ATTR_AUTHOR ,
1225                         NULL },
1226
1227     { "b-margin"      , SdlAttrDataTypeNumber, SdlContainerSpecific ,
1228                         SDL_ATTR_BMARGIN,
1229                         SDLAttrOffset(_DtCvContainerPtr,bmargin) },
1230     { "border"        , SdlAttrDataTypeEnum  , SdlContainerSpecific ,
1231                         SDL_ATTR_BORDER,
1232                         SDLAttrOffset(_DtCvContainerPtr,border)  },
1233     { "branches"      , SdlAttrDataTypeCdata , SdlElementSpecific,
1234                         SDL_ATTR_BRANCHES ,
1235                         SDLAttrOffset(ElementInfoPtr,elstr1)          },
1236
1237     { ButtonStr       , SdlAttrDataTypeId    , SdlIgnore         ,
1238                         SDL_ATTR_BUTTON,
1239                         NULL },
1240
1241     { "cells"         , SdlAttrDataTypeId    , SdlElementSpecific,
1242                         SDL_ATTR_CELLS,
1243                         SDLAttrOffset(ElementInfoPtr,elstr1)          },
1244     { "charset"       , SdlAttrDataTypeCdata , SdlElementSpecific,
1245                         SDL_ATTR_CHARSET,
1246                         SDLAttrOffset(ElementInfoPtr,char_set) },
1247     { "class"         , SdlAttrDataTypeEnum  , SdlElementSpecific,
1248                         SDL_ATTR_CLASS ,
1249                         SDLAttrOffset(ElementInfoPtr,match.clan)      },
1250     { "colj"          , SdlAttrDataTypeCdata , SdlElementSpecific,
1251                         SDL_ATTR_COLJ   ,
1252                         SDLAttrOffset(ElementInfoPtr,elstr1)          },
1253     { "color"         , SdlAttrDataTypeCdata , SdlFontSpecific,
1254                         SDL_ATTR_COLOR  ,
1255                         SDLAttrOffset(_DtHelpFontHintPtr,color) },
1256     { "colw"          , SdlAttrDataTypeCdata , SdlElementSpecific,
1257                         SDL_ATTR_COLW   ,
1258                         SDLAttrOffset(ElementInfoPtr,elstr2)          },
1259     { "command"       , SdlAttrDataTypeCdata , SdlElementSpecific,
1260                         SDL_ATTR_COMMAND ,
1261                         SDLAttrOffset(ElementInfoPtr,w.snb_info.xid)  },
1262     { "count"         , SdlAttrDataTypeNumber, SdlElementSpecific,
1263                         SDL_ATTR_COUNT   ,
1264                         SDLAttrOffset(ElementInfoPtr,nums.count) },
1265     { "data"          , SdlAttrDataTypeCdata , SdlElementSpecific,
1266                         SDL_ATTR_DATA   ,
1267                         SDLAttrOffset(ElementInfoPtr,w.snb_info.xid) },
1268
1269     { "descript"      , SdlAttrDataTypeCdata , SdlIgnore         ,
1270                         SDL_ATTR_DESCRIPT,
1271                         NULL },
1272
1273     { "doc-id"        , SdlAttrDataTypeCdata , SdlElementSpecific,
1274                         SDL_ATTR_DOCID  ,
1275                         SDLAttrOffset(ElementInfoPtr,w.doc_info.doc_id) },
1276     { "enter"         , SdlAttrDataTypeCdata , SdlElementSpecific,
1277                         SDL_ATTR_ENTER  ,
1278                         SDLAttrOffset(ElementInfoPtr,elstr1)          },
1279     { "exit"          , SdlAttrDataTypeCdata , SdlElementSpecific,
1280                         SDL_ATTR_EXIT   ,
1281                         SDLAttrOffset(ElementInfoPtr,elstr2)          },
1282     { "first-page"    , SdlAttrDataTypeId    , SdlElementSpecific,
1283                         SDL_ATTR_FRST_PG,
1284                         SDLAttrOffset(ElementInfoPtr,w.doc_info.first_pg) },
1285     { "flow"          , SdlAttrDataTypeEnum  , SdlContainerSpecific ,
1286                         SDL_ATTR_FLOW   ,
1287                         SDLAttrOffset(_DtCvContainerPtr,flow) },
1288     { "f-margin"      , SdlAttrDataTypeNumber, SdlContainerSpecific ,
1289                         SDL_ATTR_FMARGIN,
1290                         SDLAttrOffset(_DtCvContainerPtr,fmargin) },
1291     { "format"        , SdlAttrDataTypeCdata , SdlElementSpecific,
1292                         SDL_ATTR_FORMAT ,
1293                         SDLAttrOffset(ElementInfoPtr,w.snb_info.format) },
1294
1295     { "hdr"           , SdlAttrDataTypeEnum  , SdlIgnore         ,
1296                         SDL_ATTR_HDR    ,
1297                         NULL },
1298
1299     { "headw"         , SdlAttrDataTypeNumber , SdlContainerSpecific ,
1300                         SDL_ATTR_HEADWDTH,
1301                         SDLAttrOffset(_DtCvContainerPtr,percent) },
1302     { "id"            , SdlAttrDataTypeId    , SdlElementSpecific,
1303                         SDL_ATTR_ID     ,
1304                         SDLAttrOffset(ElementInfoPtr,id) },
1305
1306     { "interp"        , SdlAttrDataTypeEnum  , SdlElementSpecific,
1307                         SDL_ATTR_INTERP ,
1308                         SDLAttrOffset(ElementInfoPtr,interp) },
1309     { "justify"       , SdlAttrDataTypeEnum  , SdlContainerSpecific ,
1310                         SDL_ATTR_JUSTIFY,
1311                         SDLAttrOffset(_DtCvContainerPtr,justify) },
1312     { "l-margin"      , SdlAttrDataTypeNumber, SdlContainerSpecific ,
1313                         SDL_ATTR_LMARGIN,
1314                         SDLAttrOffset(_DtCvContainerPtr,lmargin) },
1315     { "language"      , SdlAttrDataTypeCdata , SdlElementSpecific,
1316                         SDL_ATTR_LANGUAGE   ,
1317                         SDLAttrOffset(ElementInfoPtr,language) },
1318     { "length"        , SdlAttrDataTypeNumber, SdlIgnore         ,
1319                         SDL_ATTR_LENGTH ,
1320                         NULL },
1321
1322     { "level"         , SdlAttrDataTypeNumber, SdlElementSpecific,
1323                         SDL_ATTR_LEVEL  ,
1324                         SDLAttrOffset(ElementInfoPtr,match.level) },
1325
1326     { "license"       , SdlAttrDataTypeCdata , SdlIgnore         ,
1327                         SDL_ATTR_LICENSE  ,
1328                         NULL },
1329     { "linkinfo"      , SdlAttrDataTypeCdata , SdlIgnore         ,
1330                         SDL_ATTR_LINKINFO,
1331                         NULL },
1332
1333     { "locs"          , SdlAttrDataTypeCdata , SdlElementSpecific,
1334                         SDL_ATTR_LOCS   ,
1335                         SDLAttrOffset(ElementInfoPtr,w.entry_info.locs)    },
1336     { "main"          , SdlAttrDataTypeCdata , SdlElementSpecific,
1337                         SDL_ATTR_MAIN   ,
1338                         SDLAttrOffset(ElementInfoPtr,w.entry_info.main)    },
1339     { "method"        , SdlAttrDataTypeCdata , SdlElementSpecific,
1340                         SDL_ATTR_METHOD ,
1341                         SDLAttrOffset(ElementInfoPtr,w.snb_info.method)    },
1342     { NameStr         , SdlAttrDataTypeCdata , SdlElementSpecific,
1343                         SDL_ATTR_NAME   ,
1344                         SDLAttrOffset(ElementInfoPtr,elstr1)               },
1345     { "ncols"         , SdlAttrDataTypeNumber, SdlTableSpecific,
1346                         SDL_ATTR_NCOLS  ,
1347                         SDLAttrOffset(_DtCvSegmentPtr, handle.table.num_cols) },
1348     { "offset"        , SdlAttrDataTypeNumber, SdlElementSpecific,
1349                         SDL_ATTR_OFFSET ,
1350                         SDLAttrOffset(ElementInfoPtr,nums.offset)          },
1351     {(TopVOrientStr+5), SdlAttrDataTypeEnum  , SdlContainerSpecific ,
1352                         SDL_ATTR_ORIENT ,
1353                         SDLAttrOffset(_DtCvContainerPtr,orient) },
1354
1355     { "placement"     , SdlAttrDataTypeEnum  , SdlIgnore         ,
1356                         SDL_ATTR_PLACEMENT,
1357                         NULL },
1358     { "phrase"        , SdlAttrDataTypeCdata , SdlIgnore         ,
1359                         SDL_ATTR_PHRASE ,
1360                         NULL },
1361
1362     { "pointsz"       , SdlAttrDataTypeNumber, SdlFontSpecific,
1363                         SDL_ATTR_POINTSZ ,
1364                         SDLAttrOffset(_DtHelpFontHintPtr,pointsz) },
1365
1366     { "pub-id"        , SdlAttrDataTypeCdata , SdlIgnore         ,
1367                         SDL_ATTR_PUBID  ,
1368                         NULL },
1369     { "prodpn"        , SdlAttrDataTypeCdata , SdlIgnore         ,
1370                         SDL_ATTR_PRODPN ,
1371                         NULL },
1372     { ProductStr      , SdlAttrDataTypeCdata , SdlIgnore         ,
1373                         SDL_ATTR_PRODUCT,
1374                         NULL },
1375     { "prodver"       , SdlAttrDataTypeCdata , SdlIgnore         ,
1376                         SDL_ATTR_PRODVER,
1377                         NULL },
1378
1379     { "r-margin"      , SdlAttrDataTypeNumber, SdlContainerSpecific ,
1380                         SDL_ATTR_RMARGIN,
1381                         SDLAttrOffset(_DtCvContainerPtr,rmargin) },
1382     { "rid"           , SdlAttrDataTypeId    , SdlElementSpecific   ,
1383                         SDL_ATTR_RID    ,
1384                         SDLAttrOffset(ElementInfoPtr,id) },
1385     { "rlevel"        , SdlAttrDataTypeNumber, SdlElementSpecific,
1386                         SDL_ATTR_RLEVEL ,
1387                         SDLAttrOffset(ElementInfoPtr,match.level) },
1388     { "rssi"          , SdlAttrDataTypeCdata , SdlElementSpecific,
1389                         SDL_ATTR_RSSI   ,
1390                         SDLAttrOffset(ElementInfoPtr,match.ssi) },
1391
1392     { "sdldtd"        , SdlAttrDataTypeCdata , SdlElementSpecific,
1393                         SDL_ATTR_SDLDTD   ,
1394                         SDLAttrOffset(ElementInfoPtr,w.doc_info.sdldtd) },
1395
1396     { "set-width"     , SdlAttrDataTypeNumber, SdlFontSpecific,
1397                         SDL_ATTR_SETWIDTH,
1398                         SDLAttrOffset(_DtHelpFontHintPtr,set_width)},
1399     { "slant"         , SdlAttrDataTypeFont  , SdlFontSpecific   ,
1400                         SDL_ATTR_SLANT,
1401                         SDLAttrOffset(_DtHelpFontHintPtr,slant) },
1402     { "sort"          , SdlAttrDataTypeCdata , SdlElementSpecific,
1403                         SDL_ATTR_SORT   ,
1404                         SDLAttrOffset(ElementInfoPtr,w.entry_info.sort)    },
1405     { "spacing"       , SdlAttrDataTypeFont  , SdlFontSpecific   ,
1406                         SDL_ATTR_SPACING,
1407                         SDLAttrOffset(_DtHelpFontHintPtr,spacing) },
1408     { "special"       , SdlAttrDataTypeFont  , SdlFontSpecific   ,
1409                         SDL_ATTR_SPECIAL,
1410                         SDLAttrOffset(_DtHelpFontHintPtr,special) },
1411
1412     { "srcdtd"        , SdlAttrDataTypeCdata , SdlIgnore         ,
1413                         SDL_ATTR_SRCDTD   ,
1414                         NULL },
1415     { "srch-wt"       , SdlAttrDataTypeNumber, SdlIgnore         ,
1416                         SDL_ATTR_SRCHWT ,
1417                         NULL },
1418
1419     { "ssi"           , SdlAttrDataTypeCdata , SdlElementSpecific,
1420                         SDL_ATTR_SSI    ,
1421                         SDLAttrOffset(ElementInfoPtr,match.ssi) },
1422
1423     { "stack"         , SdlAttrDataTypeEnum  , SdlIgnore         ,
1424                         SDL_ATTR_STACK,
1425                         NULL },
1426
1427     { "style"         , SdlAttrDataTypeFont  , SdlFontSpecific   ,
1428                         SDL_ATTR_STYLE,
1429                         SDLAttrOffset(_DtHelpFontHintPtr,style) },
1430     { "syns"          , SdlAttrDataTypeCdata , SdlElementSpecific,
1431                         SDL_ATTR_SYNS   ,
1432                         SDLAttrOffset(ElementInfoPtr,w.entry_info.syns)    },
1433     { "t-margin"      , SdlAttrDataTypeNumber, SdlContainerSpecific ,
1434                         SDL_ATTR_TMARGIN,
1435                         SDLAttrOffset(_DtCvContainerPtr,tmargin) },
1436
1437     { (TextStr+1)     , SdlAttrDataTypeCdata , SdlIgnore,
1438                         SDL_ATTR_TEXT     ,
1439                         NULL },
1440
1441     { "timestmp"      , SdlAttrDataTypeCdata , SdlElementSpecific,
1442                         SDL_ATTR_TIMESTAMP,
1443                         SDLAttrOffset(ElementInfoPtr,w.doc_info.timestamp) },
1444     { "timing"        , SdlAttrDataTypeEnum  , SdlElementSpecific,
1445                         SDL_ATTR_TIMING ,
1446                         SDLAttrOffset(ElementInfoPtr,timing) },
1447     { "type"          , SdlAttrDataTypeEnum  , SdlElementSpecific,
1448                         SDL_ATTR_TYPE   ,
1449                         SDLAttrOffset(ElementInfoPtr,sdl_type) },
1450
1451     { "traversal"     , SdlAttrDataTypeEnum  , SdlIgnore         ,
1452                         SDL_ATTR_TRAVERSAL,
1453                         NULL },
1454
1455     { "typenam"       , SdlAttrDataTypeCdata , SdlFontSpecific   ,
1456                         SDL_ATTR_TYPENAM,
1457                         SDLAttrOffset(_DtHelpFontHintPtr,typenam) },
1458     { "typenamb"      , SdlAttrDataTypeCdata , SdlFontSpecific   ,
1459                         SDL_ATTR_TYPENAMB,
1460                         SDLAttrOffset(_DtHelpFontHintPtr,typenamb) },
1461     { "typenami"      , SdlAttrDataTypeCdata , SdlFontSpecific   ,
1462                         SDL_ATTR_TYPENAMI,
1463                         SDLAttrOffset(_DtHelpFontHintPtr,typenami) },
1464     { "typenamib"     , SdlAttrDataTypeCdata , SdlFontSpecific   ,
1465                         SDL_ATTR_TYPENAMIB,
1466                         SDLAttrOffset(_DtHelpFontHintPtr,typenamib) },
1467
1468     { "version"       , SdlAttrDataTypeCdata , SdlIgnore         ,
1469                         SDL_ATTR_VERSION,
1470                         NULL },
1471
1472     {(TopVJustStr+4)  , SdlAttrDataTypeEnum  , SdlContainerSpecific ,
1473                         SDL_ATTR_VJUST,
1474                         SDLAttrOffset(_DtCvContainerPtr,vjustify) },
1475
1476     {(TopVOrientStr+4), SdlAttrDataTypeEnum  , SdlContainerSpecific ,
1477                         SDL_ATTR_VORIENT ,
1478                         SDLAttrOffset(_DtCvContainerPtr,vorient) },
1479
1480     { "weight"        , SdlAttrDataTypeFont  , SdlFontSpecific   ,
1481                         SDL_ATTR_WEIGHT,
1482                         SDLAttrOffset(_DtHelpFontHintPtr,weight) },
1483     { "window"        , SdlAttrDataTypeEnum  , SdlElementSpecific,
1484                         SDL_ATTR_WINDOW,
1485                         SDLAttrOffset(ElementInfoPtr,window) },
1486
1487     { "xid"           , SdlAttrDataTypeCdata , SdlElementSpecific,
1488                         SDL_ATTR_XID    ,
1489                         SDLAttrOffset(ElementInfoPtr,w.snb_info.xid) },
1490
1491     { "xlfd"          , SdlAttrDataTypeCdata , SdlFontSpecific   ,
1492                         SDL_ATTR_XLFD   ,
1493                         SDLAttrOffset(_DtHelpFontHintPtr,xlfd) },
1494     { "xlfdb"         , SdlAttrDataTypeCdata , SdlFontSpecific   ,
1495                         SDL_ATTR_XLFDB  ,
1496                         SDLAttrOffset(_DtHelpFontHintPtr,xlfdb) },
1497     { "xlfdi"         , SdlAttrDataTypeCdata , SdlFontSpecific   ,
1498                         SDL_ATTR_XLFDI  ,
1499                         SDLAttrOffset(_DtHelpFontHintPtr,xlfdi) },
1500     { "xlfdib"        , SdlAttrDataTypeCdata , SdlFontSpecific   ,
1501                         SDL_ATTR_XLFDIB ,
1502                         SDLAttrOffset(_DtHelpFontHintPtr,xlfdib) },
1503     { NULL            , SdlAttrDataTypeInvalid, -1,  NULL                    },
1504   };
1505
1506 /******************************************************************************
1507  * Element Content
1508  *****************************************************************************/
1509 /*-----------------------------------------------------------------------------
1510 <!-- Document Hierarchy  _____________________________________________-->
1511
1512 <!-- The root element is a pageless document, sdldoc.
1513    -   A sdldoc contains one or more virtual pages.
1514    -   A Virtual page is the smallest display unit.
1515    -   A Block is a unit of a given style.
1516    -   A Paragraph is a unit of character formatting.
1517   -->
1518
1519 <!ELEMENT sdldoc     - - (vstruct, head*, snb?, virpage+)>
1520 <!ATTLIST sdldoc         pub-id     CDATA    #REQUIRED
1521                          doc-id     CDATA    #REQUIRED
1522                          timestmp   CDATA    #REQUIRED
1523                          first-page IDREF    #IMPLIED
1524                          product    CDATA    #IMPLIED
1525                          prodpn     CDATA    #IMPLIED
1526                          prodver    CDATA    #IMPLIED
1527                          license    CDATA    #IMPLIED
1528                          language   CDATA    #IMPLIED
1529                          charset    CDATA    #IMPLIED
1530                          author     CDATA    #IMPLIED
1531                          version    CDATA    #IMPLIED
1532                          sdldtd     CDATA    #REQUIRED
1533                          srcdtd     CDATA    #IMPLIED >
1534
1535 -----------------------------------------------------------------------------*/
1536 static SDLContent SdlDocContent[] =
1537     {
1538 /*
1539         { SDLInitMask(SdlElementVStruct), OnlyOne   },
1540  * Do not want to parse the entire document.
1541  * Want to only read enought to work with.
1542  */
1543         { SDLInitMask(SdlElementSdlDoc) , FakeEnd     },
1544         { SDLInitMask(SdlElementSdlDoc) , CopyDocInfo },
1545         { SDLInitMask(SdlElementNone)   , NULL        },
1546     };
1547 static SDLElementAttrList  SdlDocAttrList[] =
1548     {
1549         { SDL_ATTR_PUBID    , SdlAttrValueRequired, NULL   },
1550         { SDL_ATTR_DOCID    , SdlAttrValueRequired, NULL   },
1551         { SDL_ATTR_TIMESTAMP, SdlAttrValueRequired, NULL   },
1552         { SDL_ATTR_PRODUCT  , SdlAttrValueImplied , NULL   },
1553         { SDL_ATTR_PRODPN   , SdlAttrValueImplied , NULL   },
1554         { SDL_ATTR_PRODVER  , SdlAttrValueImplied , NULL   },
1555         { SDL_ATTR_LICENSE  , SdlAttrValueImplied , NULL   },
1556         { SDL_ATTR_LANGUAGE , SdlAttrValueImplied , "C"    },
1557         { SDL_ATTR_CHARSET  , SdlAttrValueImplied , IsoStr },
1558         { SDL_ATTR_AUTHOR   , SdlAttrValueImplied , NULL   },
1559         { SDL_ATTR_VERSION  , SdlAttrValueImplied , NULL   },
1560         { SDL_ATTR_FRST_PG  , SdlAttrValueImplied , NULL   },
1561         { SDL_ATTR_SDLDTD   , SdlAttrValueRequired, NULL   },
1562         { SDL_ATTR_SRCDTD   , SdlAttrValueImplied , NULL   },
1563         { -1                , SdlAttrValueBad     , NULL   }
1564     };
1565
1566 /*-----------------------------------------------------------------------------
1567 <!ELEMENT vstruct   - - (%generated-elements;) >
1568 <!ATTLIST vstruct       version   CDATA              #IMPLIED
1569                         doc-id    CDATA              #REQUIRED >
1570 -----------------------------------------------------------------------------*/
1571 static SDLContent VStructContent[] =
1572     {
1573         SDL_ENTITY_GENERATED_ELEMENTS
1574         { SDLInitMask(SdlElementNone)   , NULL      },
1575     };
1576 static SDLElementAttrList  VStructAttrList[] =
1577     {
1578         { SDL_ATTR_DOCID   , SdlAttrValueImplied , NULL },
1579         { SDL_ATTR_VERSION , SdlAttrValueImplied , NULL },
1580         { -1               , SdlAttrValueBad     , NULL }
1581     };
1582
1583 /*-----------------------------------------------------------------------------
1584
1585 <!ELEMENT virpage   - - (head*, snb?, (block | form)*) >
1586 <!ATTLIST virpage       id        ID                 #REQUIRED
1587                         level     NUMBER             #REQUIRED
1588                         version   CDATA              #IMPLIED
1589                         language  CDATA              #IMPLIED
1590                         charset   CDATA              #IMPLIED
1591                         doc-id    CDATA              #REQUIRED
1592                         ssi       CDATA              #IMPLIED >
1593 -----------------------------------------------------------------------------*/
1594 static SDLContent VirpageContent[] =
1595     {
1596         { SDLInitMask(SdlElementHead)     , SetSaveSnref      },
1597         { SDLInitMask(SdlElementHead)     , ZeroToN           },
1598         { SDLInitMask(SdlElementSnb)      , ZeroOrOne         },
1599         { SDLInitMask(SdlElementHead)     , ClearAndCheckSnref},
1600         { SDLInitMaskTwo(SdlElementBlock, \
1601                                 SdlElementForm), ZeroToN   },
1602         { SDLInitMask(SdlElementNone)     , NULL      },
1603     };
1604 static SDLContent VirpageHeadContent[] =
1605     {
1606         { SDLInitMask(SdlElementHead)     , SetSaveSnref},
1607         { SDLInitMask(SdlElementHead)     , ZeroToN     },
1608         { SDLInitMask(SdlElementVirpage)  , CheckForSnb },
1609         { SDLInitMask(SdlElementTitle)    , FakeEnd     },
1610         { SDLInitMask(SdlElementNone)     , NULL        },
1611     };
1612
1613 static SDLContent HeadAndSnb[] =
1614     {
1615         { SDLInitMask(SdlElementHead)     , SetSaveSnref},
1616         { SDLInitMask(SdlElementHead)     , ZeroToN     },
1617         { SDLInitMask(SdlElementHead)     , CheckForSnb },
1618         { SDLInitMask(SdlElementNone)     , NULL        },
1619     };
1620
1621 static SDLElementAttrList  VirpageAttrList[] =
1622     {
1623         { SDL_ATTR_ID      , SdlAttrValueRequired  , NULL   },
1624         { SDL_ATTR_LEVEL   , SdlAttrValueRequired  , NULL   },
1625         { SDL_ATTR_VERSION , SdlAttrValueImplied   , NULL   },
1626         { SDL_ATTR_LANGUAGE, SdlAttrValueImplied   , NULL   },
1627         { SDL_ATTR_CHARSET , SdlAttrValueImplied   , NULL   },
1628         { SDL_ATTR_DOCID   , SdlAttrValueRequired  , NULL   },
1629         { SDL_ATTR_SSI     , SdlAttrValueImpliedDef, NULL   },
1630         { -1               , SdlAttrValueBad       , NULL   }
1631     };
1632
1633 /*-----------------------------------------------------------------------------
1634 <!ELEMENT snb       - - (head?, (%system-notations;)+) >
1635 <!ATTLIST snb           version   CDATA              #IMPLIED >
1636 -----------------------------------------------------------------------------*/
1637 static SDLContent SnbContent[] =
1638     {
1639         { SDLInitMask(SdlElementHead)  , ZeroOrOne },
1640         { SDL_ENTITY_SYSTEM_NOTATIONS       , OneToN    },
1641         { SDLInitMask(SdlElementNone)  , NULL      },
1642     };
1643 static SDLElementAttrList  SnbAttrList[] =
1644     {
1645         { SDL_ATTR_VERSION, SdlAttrValueImplied , NULL },
1646         { -1               ,SdlAttrValueBad        , NULL }
1647     };
1648
1649 /*-----------------------------------------------------------------------------
1650 <!ELEMENT block     - - (head*, (p | cp)*) >
1651 <!ATTLIST block         id        ID                 #IMPLIED
1652
1653                         -- processor should default level to "1"      --
1654                         level     NUMBER             #IMPLIED
1655                         version   CDATA              #IMPLIED
1656                         class     (%format-class;)   #IMPLIED
1657                         language  CDATA              #IMPLIED
1658
1659                         -- processor shld deflt charset to "ISO-8859-1" --
1660                         charset   CDATA              #IMPLIED
1661
1662                         length    NUMBER             #IMPLIED
1663
1664                         -- processor should default app to "all"      --
1665                         app      ( all      |
1666                                    help     |
1667                                    tutorial |
1668                                    ref      |
1669                                    sys      )        #IMPLIED
1670
1671                         -- processor should default timing to "sync"  --
1672                         timing   ( sync | async )    #IMPLIED
1673                         ssi       CDATA              #IMPLIED >
1674 -----------------------------------------------------------------------------*/
1675 static SDLContent BlockContent[] =
1676     {
1677         { SDLInitMask(SdlElementBlock)                   , SetTransit},
1678         { SDLInitMask(SdlElementHead)                    , ZeroToN   },
1679         { SDLInitMaskTwo(SdlElementPara, SdlElementCPara), ZeroToN   },
1680         { SDLInitMask(SdlElementNone)                    , NULL      },
1681     };
1682 static SDLElementAttrList  BlockAttrList[] =
1683     {
1684         { SDL_ATTR_ID      , SdlAttrValueImpliedDef , NULL           },
1685         { SDL_ATTR_LEVEL   , SdlAttrValueImpliedDef , OneStr         },
1686         { SDL_ATTR_VERSION , SdlAttrValueImplied    , NULL           },
1687         { SDL_ATTR_CLASSF  , SdlAttrValueImplied    , (TextStr+1)    },
1688         { SDL_ATTR_LANGUAGE, SdlAttrValueImplied    , NULL           },
1689         { SDL_ATTR_CHARSET , SdlAttrValueImplied    , NULL           },
1690         { SDL_ATTR_LENGTH  , SdlAttrValueImplied    , NegativeOneStr },
1691         { SDL_ATTR_APP     , SdlAttrValueImplied    , AllStr         },
1692         { SDL_ATTR_TIMING  , SdlAttrValueImplied    , (ASyncStr+1)   },
1693         { SDL_ATTR_SSI     , SdlAttrValueImpliedDef , NULL           },
1694         { -1               , SdlAttrValueBad        , NULL           }
1695     };
1696
1697 /*-----------------------------------------------------------------------------
1698 <!ELEMENT form      - - (head*, ((fstyle, fdata) | (fdata, fstyle))) >
1699 <!ATTLIST form          id        ID                 #IMPLIED
1700
1701                         -- processor shld deflt level to nest of form --
1702                         level     NUMBER             #IMPLIED
1703                         version   CDATA              #IMPLIED
1704                         class     (%format-class;)   #IMPLIED
1705                         language  CDATA              #IMPLIED
1706
1707                         -- processor shld deflt charset to "ISO-8859-1" --
1708                         charset   CDATA              #IMPLIED
1709                         length    NUMBER             #IMPLIED
1710
1711                         -- processor should default app to "all"      --
1712                         app      ( all      |
1713                                    help     |
1714                                    tutorial |
1715                                    ref      |
1716                                    sys      )        #IMPLIED
1717                         ssi       CDATA              #IMPLIED >
1718
1719 -----------------------------------------------------------------------------*/
1720 static SDLContent FormContent[] =
1721     {
1722         { SDLInitMask(SdlElementHead)  , ZeroToN            },
1723         { SDLInitMaskTwo(SdlElementFstyle, SdlElementFdata),
1724                                                 OnlyOneEach },
1725         { SDLInitMask(SdlElementForm)  , ColInfoToTableInfo },
1726         { SDLInitMask(SdlElementNone)  , NULL      },
1727     };
1728 static SDLElementAttrList  FormAttrList[] =
1729     {
1730         { SDL_ATTR_ID      , SdlAttrValueImpliedDef, NULL           },
1731         { SDL_ATTR_LEVEL   , SdlAttrValueImplied   , OneStr         },
1732         { SDL_ATTR_VERSION , SdlAttrValueImplied   , NULL           },
1733         { SDL_ATTR_CLASSF  , SdlAttrValueImplied   , (TextStr+1)    },
1734         { SDL_ATTR_LANGUAGE, SdlAttrValueImplied   , NULL           },
1735         { SDL_ATTR_CHARSET , SdlAttrValueImplied   , NULL           },
1736         { SDL_ATTR_LENGTH  , SdlAttrValueImplied   , NegativeOneStr },
1737         { SDL_ATTR_APP     , SdlAttrValueImplied   , AllStr         },
1738         { SDL_ATTR_SSI     , SdlAttrValueImpliedDef, NULL           },
1739         { -1               ,SdlAttrValueBad        , NULL           }
1740     };
1741
1742 /*-----------------------------------------------------------------------------
1743 <!ELEMENT fstyle    - - (frowvec+) >
1744 <!ATTLIST fstyle        -- The number of columns in this form, ncols, --
1745                         -- should be a number greater than zero.      --
1746                         -- Unless overridden by a "colw" (column      --
1747                         -- width) specification in a formstyle, the   --
1748                         -- available space is divided evenly among    --
1749                         -- the columns.  Unless overriden by a "colj" --
1750                         -- specification in a formstyle, the columns  --
1751                         -- are all left justified.                    --
1752                         -- processor should default ncols to 1        --
1753                         ncols     NUMBER             #IMPLIED >
1754
1755 -----------------------------------------------------------------------------*/
1756 static SDLContent FstyleContent[] =
1757     {
1758         { SDLInitMask(SdlElementFrowvec), OneToN  },
1759         { SDLInitMask(SdlElementNone)   , NULL    },
1760     };
1761 static SDLElementAttrList  FstyleAttrList[] =
1762     {
1763         { SDL_ATTR_NCOLS  , SdlAttrValueImpliedDef , OneStr },
1764         { -1              , SdlAttrValueBad        , NULL }
1765     };
1766
1767 /*-----------------------------------------------------------------------------
1768 <!ELEMENT frowvec   - O EMPTY >
1769 <!ATTLIST frowvec       -- processor should default hdr to "NO"       --
1770                         hdr       (YES | NO)         #IMPLIED
1771
1772                         -- Ids of cell contents.  One id per cell.    --
1773                         -- Each id must refer to either a block or a  --
1774                         -- form.                                      --
1775                         cells     IDREFS             #REQUIRED >
1776 -----------------------------------------------------------------------------*/
1777 static SDLContent FrowvecContent[] =
1778     {
1779         { SDLInitMask(SdlElementFrowvec), AddRowToTable},
1780         { SDLInitMask(SdlElementNone)   , NULL    },
1781     };
1782
1783 static SDLElementAttrList  FrowvecAttrList[] =
1784     {
1785         { SDL_ATTR_HDR    , SdlAttrValueImplied , "NO"      },
1786         { SDL_ATTR_CELLS  , SdlAttrValueRequired, NULL      },
1787         { -1              , SdlAttrValueBad     , NULL }
1788     };
1789
1790 /*-----------------------------------------------------------------------------
1791 <!ELEMENT fdata     - - ((block | form)*) >
1792 -----------------------------------------------------------------------------*/
1793 static SDLContent FdataContent[] =
1794     {
1795         { SDLInitMaskTwo(SdlElementBlock, SdlElementForm), ZeroToN },
1796         { SDLInitMask(SdlElementNone)                    , NULL    },
1797     };
1798
1799 /*-----------------------------------------------------------------------------
1800 <!-- Containers ______________________________________________________-->
1801
1802 <!ELEMENT p         - - (head*, (%atomic | #PCDATA)+) >
1803 <!ATTLIST p             id        ID                 #IMPLIED
1804                         version   CDATA              #IMPLIED
1805
1806                         -- processor should default type to "dynamic" --
1807                         type      (literal |
1808                                    lined   |
1809                                    dynamic )         #IMPLIED
1810                         ssi       CDATA              #IMPLIED >
1811 -----------------------------------------------------------------------------*/
1812 static SDLContent ParaContent[] =
1813     {
1814 /*
1815  * This is optional and followed by potential PCDATA, therefore include
1816  * the SdlElementCdata & SdlPcDataFollows flag.
1817  */
1818         { SDLInitMaskThree(SdlElementHead, SdlPcDataFollows, SdlElementCdata),
1819                                                         ZeroToN   },
1820         { SDLInitMask(SdlElementPara), InitLast  },
1821 /*
1822  * PCDATA is described as 0 to n characters,
1823  * therefore, while the content says 'one to n' of (%atomic | #PCDATA)
1824  * we need to specify ZeroToN to work for PCDATA
1825         { SDL_ENTITY_ATOMIC               , OneToN    },
1826  */
1827         { SDL_ENTITY_ATOMIC               , ZeroToN   },
1828         { SDLInitMask(SdlElementNone), NULL      },
1829     };
1830 static SDLElementAttrList  ParaAttrList[] =
1831     {
1832         { SDL_ATTR_ID      , SdlAttrValueImpliedDef, NULL      },
1833         { SDL_ATTR_VERSION , SdlAttrValueImplied   , NULL      },
1834         { SDL_ATTR_TYPEFRMT, SdlAttrValueImplied   , DynamicStr},
1835         { SDL_ATTR_SSI     , SdlAttrValueImpliedDef, NULL      },
1836         { -1               , SdlAttrValueBad       , NULL }
1837     };
1838
1839 /*-----------------------------------------------------------------------------
1840 <!ELEMENT cp        - - CDATA >
1841 <!ATTLIST cp            id        ID                 #IMPLIED
1842                         version   CDATA              #IMPLIED
1843
1844                         -- processor should default type to "dynamic" --
1845                         type      (literal |
1846                                    lined   |
1847                                    dynamic )         #IMPLIED
1848                         ssi       CDATA              #IMPLIED >
1849 -----------------------------------------------------------------------------*/
1850 static SDLContent CParaContent[] =
1851     {
1852         { SDLInitMask(SdlElementCPara), InitLast  },
1853         { SDLInitMask(SdlElementCdata), ZeroOrOne },
1854         { SDLInitMask(SdlElementNone) , NULL  },
1855     };
1856 /* uses the same attributes as <p> */
1857
1858 /*-----------------------------------------------------------------------------
1859 <!-- Heads may have multiple sub-heads -->
1860 <!ELEMENT head      - - ((%atomic; | #PCDATA)*, subhead*) >
1861 <!ELEMENT subhead   - - ((%atomic | #PCDATA)*) >
1862 <!ATTLIST (head | subhead)
1863                         id        ID                 #IMPLIED
1864                         version   CDATA              #IMPLIED
1865
1866                         -- processor should default class to "head"   --
1867                         class     (%head-class;)     #IMPLIED
1868                         language  CDATA              #IMPLIED
1869
1870                         -- processor shld deflt charset to "ISO-8859-1" --
1871                         charset   CDATA              #IMPLIED
1872
1873                         -- processor should default type to "dynamic" --
1874                         type      (literal |
1875                                    lined   |
1876                                    dynamic )         #IMPLIED
1877                         abbrev    CDATA              #IMPLIED
1878
1879                         ssi       CDATA              #IMPLIED >
1880 -----------------------------------------------------------------------------*/
1881 static SDLContent HeadContent[] =
1882     {
1883         { SDLInitMask(SdlElementHead)   , InitLast  },
1884         { SDL_ENTITY_ATOMIC             , ZeroToN   },
1885         { SDLInitMask(SdlElementSubHead), ZeroToN   },
1886         { SDLInitMask(SdlElementNone)   , NULL      },
1887     };
1888 static SDLContent SubHeadContent[] =
1889     {
1890         { SDLInitMask(SdlElementSubHead), InitLast  },
1891         { SDL_ENTITY_ATOMIC             , ZeroToN   },
1892         { SDLInitMask(SdlElementNone)   , NULL      },
1893     };
1894 static SDLElementAttrList  HeadAttrList[] =
1895     {
1896         { SDL_ATTR_ID      , SdlAttrValueImpliedDef, NULL       },
1897         { SDL_ATTR_VERSION , SdlAttrValueImplied   , NULL       },
1898         { SDL_ATTR_CLASSH  , SdlAttrValueImplied   , (HeadStr+1)},
1899         { SDL_ATTR_LANGUAGE, SdlAttrValueImplied   , NULL       },
1900         { SDL_ATTR_CHARSET , SdlAttrValueImplied   , NULL       },
1901         { SDL_ATTR_TYPEFRMT, SdlAttrValueImplied   , DynamicStr },
1902         { SDL_ATTR_ABBREV  , SdlAttrValueImplied   , NULL       },
1903         { SDL_ATTR_SSI     , SdlAttrValueImpliedDef, NULL       },
1904         { -1               , SdlAttrValueBad       , NULL       }
1905     };
1906
1907 /*-----------------------------------------------------------------------------
1908 <!-- Atomic Link Elements ____________________________________________-->
1909
1910 <!ELEMENT anchor    - O EMPTY     -- Just marks the spot to jump to   -->
1911 <!ATTLIST anchor        id        ID                 #REQUIRED >
1912 -----------------------------------------------------------------------------*/
1913 static SDLElementAttrList  AnchorAttrList[] =
1914     {
1915         { SDL_ATTR_ID       , SdlAttrValueRequired, NULL      },
1916         { -1                , SdlAttrValueBad     , NULL }
1917     };
1918
1919 static SDLContent AnchorContent[] =
1920     {
1921         { SDLInitMask(SdlElementAnchor) , CopyAnchorId },
1922         { SDLInitMask(SdlElementNone)   , NULL         },
1923     };
1924
1925 /*-----------------------------------------------------------------------------
1926 <!ELEMENT link      - - ((%atomic; | #PCDATA)+) -(link)>
1927 <!ATTLIST link          -- rid is to id in this document or to a link --
1928                         -- type element such as crossdoc in the snb   --
1929                         -- of the current virpage                     --
1930                         rid       IDREF              #REQUIRED
1931
1932                         -- button should be a graphic in the snb      --
1933                         button    IDREF              #IMPLIED
1934
1935                         linkinfo  CDATA              #IMPLIED
1936                         descript  CDATA              #IMPLIED
1937
1938                         -- processor shld default window to "current" --
1939                         window    (current  |
1940                                    new      |
1941                                    popup    )        #IMPLIED
1942
1943                         -- procssr shld dflt traversal to "noreturn"  --
1944                         traversal (return   |
1945                                    noreturn )        #IMPLIED >
1946 -----------------------------------------------------------------------------*/
1947 static SDLContent LinkContent[] =
1948     {
1949         { SDLInitMask(SdlElementLink) , RegisterLink },
1950 /*
1951  * PCDATA is described as 0 to n characters,
1952  * therefore, while the content says 'one to n' of (%atomic | #PCDATA)
1953  * we need to specify ZeroToN to work for PCDATA
1954         { SDL_ENTITY_ATOMIC                , OneToN       },
1955  */
1956         { SDL_ENTITY_ATOMIC                , ZeroToN      },
1957         { SDLInitMask(SdlElementNone) , NULL         },
1958     };
1959 static SDLElementAttrList  LinkAttrList[] =
1960     {
1961         { SDL_ATTR_RID      , SdlAttrValueRequired  , NULL      },
1962         { SDL_ATTR_BUTTON   , SdlAttrValueImpliedDef, NULL      },
1963         { SDL_ATTR_WINDOW   , SdlAttrValueImplied   , "current" },
1964         { SDL_ATTR_TRAVERSAL, SdlAttrValueImplied   , "noreturn"},
1965         { SDL_ATTR_DESCRIPT , SdlAttrValueImpliedDef, NULL      },
1966         { SDL_ATTR_LINKINFO , SdlAttrValueImpliedDef, NULL      },
1967         { -1                , SdlAttrValueBad       , NULL      }
1968     };
1969
1970 /*-----------------------------------------------------------------------------
1971 <!-- reference to an element or alternates in the system notation block -->
1972 <!ELEMENT snref     - - (refitem+, alttext?) >
1973 <!ATTLIST snref         id       ID          #IMPLIED >
1974 -----------------------------------------------------------------------------*/
1975 static SDLContent SnrefContent[] =
1976     {
1977         { SDLInitMask(SdlElementSnRef)  , MarkFound  },
1978         { SDLInitMask(SdlElementRefItem), OneToN     },
1979         { SDLInitMask(SdlElementAltText), ZeroOrOne  },
1980         { SDLInitMask(SdlElementNone)   , NULL       },
1981     };
1982 static SDLElementAttrList  SnrefAttrList[] =
1983     {
1984         { SDL_ATTR_ID, SdlAttrValueImpliedDef, NULL      },
1985         { -1         , SdlAttrValueBad       , NULL }
1986     };
1987
1988 /*-----------------------------------------------------------------------------
1989 <!-- Each refitem is tried in turn until one can be  successfully
1990    - formatted.  The button is used to request display of the refitem
1991    - on systems where display of the item would be slow or expensive
1992    - in some other way, i.e., the button is displayed and the refitem
1993    - is only displayed on activiation of the button.
1994   -->
1995 <!ELEMENT refitem   - - (head*) >
1996 <!ATTLIST refitem       -- rid should point to a representational    --
1997                         -- element in the system notation block      --
1998                         rid      IDREF               #REQUIRED
1999                         class    (%graphic-class; |
2000                                   %format-class;  )  #REQUIRED
2001
2002                         -- button should be a graphic in the snb      --
2003                         button    IDREF              #IMPLIED
2004                         ssi       CDATA              #IMPLIED   >
2005 -----------------------------------------------------------------------------*/
2006 static SDLContent RefItemContent[] =
2007     {
2008         { SDLInitMask(SdlElementHead)    , ZeroOrOne    },
2009         { SDLInitMask(SdlElementRefItem) , SaveItemInfo },
2010         { SDLInitMask(SdlElementNone)    , NULL         },
2011     };
2012 static SDLElementAttrList  RefItemAttrList[] =
2013     {
2014         { SDL_ATTR_RID    , SdlAttrValueRequired  , NULL      },
2015         { SDL_ATTR_CLASSFG, SdlAttrValueRequired  , NULL      },
2016         { SDL_ATTR_BUTTON , SdlAttrValueImplied   , NULL      },
2017         { SDL_ATTR_SSI    , SdlAttrValueImpliedDef, NULL      },
2018         { -1              , SdlAttrValueBad       , NULL }
2019     };
2020 /*-----------------------------------------------------------------------------
2021 <!-- simple text to use if all else fails -->
2022 <!ELEMENT alttext   - - CDATA >
2023 -----------------------------------------------------------------------------*/
2024 static SDLContent AltTextContent[] =
2025     {
2026         { SDLInitMask(SdlElementCdata), ZeroOrOne },
2027         { SDLInitMask(SdlElementNone) , NULL    },
2028     };
2029
2030 /*-----------------------------------------------------------------------------
2031 <!-- Atomic Text Elements ____________________________________________-->
2032
2033 <!-- empty rev implies delete -->
2034 <!ELEMENT rev       - - ((%atomic; | #PCDATA)*) -(rev) >
2035 -----------------------------------------------------------------------------*/
2036 static SDLContent RevContent[] =
2037     {
2038         { SDL_ENTITY_ATOMIC               , ZeroToN },
2039         { SDLInitMask(SdlElementNone), NULL    },
2040     };
2041
2042 /*-----------------------------------------------------------------------------
2043 <!-- font changes -->
2044 <!ELEMENT key       - - ((%atomic; | #PCDATA)*) -(link) >
2045 <!ATTLIST key           -- processor shld deflt charset to "ISO-8859-1" --
2046                         charset   CDATA              #IMPLIED
2047                         class     (%key-class;)      #REQUIRED
2048                         ssi       CDATA              #IMPLIED >
2049 -----------------------------------------------------------------------------*/
2050 static SDLContent KeyContent[] =
2051     {
2052         { SDLInitMask(SdlElementKey) , ProcessEnterAttr },
2053         { SDL_ENTITY_ATOMIC          , ZeroToN          },
2054         { SDLInitMask(SdlElementKey) , ProcessExitAttr  },
2055         { SDLInitMask(SdlElementNone), NULL             },
2056     };
2057 static SDLElementAttrList  KeyAttrList[] =
2058     {
2059         { SDL_ATTR_CHARSET , SdlAttrValueImplied   , NULL      },
2060         { SDL_ATTR_CLASSK  , SdlAttrValueRequired  , NULL      },
2061         { SDL_ATTR_SSI     , SdlAttrValueImpliedDef, NULL      },
2062         { -1               , SdlAttrValueBad       , NULL }
2063     };
2064
2065 /*-----------------------------------------------------------------------------
2066 <!-- super or subscripted phrase -->
2067 <!ELEMENT sphrase   - - (spc | #PCDATA)* >
2068 <!ATTLIST sphrase       class     %phrase-class      #REQUIRED
2069                         ssi       CDATA              #IMPLIED >
2070 -----------------------------------------------------------------------------*/
2071 static SDLContent SphraseContent[] =
2072     {
2073         { SDLInitMask(SdlElementSphrase), CheckType },
2074         { SDLInitMaskTwo(SdlElementSpc, SdlElementCdata), ZeroToN   },
2075         { SDLInitMask(SdlElementSphrase), SetType   },
2076         { SDLInitMask(SdlElementNone)   , NULL      },
2077     };
2078 static SDLElementAttrList  SphraseAttrList[] =
2079     {
2080         { SDL_ATTR_CLASSP  , SdlAttrValueRequired  , NULL      },
2081         { SDL_ATTR_SSI     , SdlAttrValueImpliedDef, NULL      },
2082         { -1               , SdlAttrValueBad       , NULL }
2083     };
2084
2085 /*-----------------------------------------------------------------------------
2086 <!-- conditional inclusion of text -->
2087 <!ELEMENT if        - - (cond, then, else?) >
2088 -----------------------------------------------------------------------------*/
2089 static SDLContent IfContent[] =
2090     {
2091         { SDLInitMask(SdlElementIf)  , IfInfo    },
2092         { SDLInitMask(SdlElementCond), OnlyOne   },
2093         { SDLInitMask(SdlElementThen), OnlyOne   },
2094         { SDLInitMask(SdlElementElse), ZeroOrOne },
2095         { SDLInitMask(SdlElementNone), NULL      },
2096     };
2097
2098 /*-----------------------------------------------------------------------------
2099 <!-- call "interp" passing CDATA -->
2100 <!ELEMENT cond      - - CDATA >
2101 <!ATTLIST cond          -- processor should default interp to "ksh"   --
2102                         interp    NOTATION
2103                                   (tcl |
2104                                    sh  |
2105                                    ksh |
2106                                    csh )             #IMPLIED >
2107 -----------------------------------------------------------------------------*/
2108 static SDLContent CondContent[] =
2109     {
2110         { SDLInitMask(SdlElementCond) , SetType     },
2111         { SDLInitMask(SdlElementCdata), ZeroOrOne   },
2112         { SDLInitMask(SdlElementNone) , NULL        },
2113     };
2114 static SDLElementAttrList  CondAttrList[] =
2115     {
2116         { SDL_ATTR_INTERP  , SdlAttrValueImplied    , "ksh"     },
2117         { -1               , SdlAttrValueBad        , NULL      }
2118     };
2119
2120 /*-----------------------------------------------------------------------------
2121 <!-- include this text if "cond" returns non-zero -->
2122 <!ELEMENT then      - - ((%atomic; | #PCDATA)*) >
2123
2124 <!-- include this text if "cond" returns zero -->
2125 <!ELEMENT else      - - ((%atomic; | #PCDATA)*) >
2126 -----------------------------------------------------------------------------*/
2127 static SDLContent ThenElseContent[] =
2128     {
2129         { SDLInitMask(SdlElementIf)  , IfInfo    },
2130         { SDL_ENTITY_ATOMIC               , ZeroToN   },
2131         { SDLInitMask(SdlElementNone), NULL      },
2132     };
2133
2134 /*-----------------------------------------------------------------------------
2135 <!-- special characters: the "name" attribute must be one of the special
2136    - character names, e.g., [bull  ] (bullet), defined in the public
2137    - character entities such as ISOpub, "ISO 8879:1986//ENTITIES
2138    - Publishing//EN";  these entities are defined in sections D.4.2.1
2139    - through D.4.5.6 of The SGML Handbook (Goldfarb).
2140    -->
2141 <!ELEMENT spc       - O EMPTY >
2142 <!ATTLIST spc           name      CDATA              #REQUIRED >
2143 -----------------------------------------------------------------------------*/
2144 static SDLContent SpcContent[] =
2145     {
2146         { SDLInitMask(SdlElementSpc) , ResolveSpcInfo },
2147         { SDLInitMask(SdlElementNone), NULL        },
2148     };
2149
2150 static SDLElementAttrList  SpcAttrList[] =
2151     {
2152         { SDL_ATTR_NAME, SdlAttrValueRequired, NULL        },
2153         { -1               ,SdlAttrValueBad        , NULL }
2154     };
2155 /*-----------------------------------------------------------------------------
2156 <!-- Notation Elements _______________________________________________-->
2157 <!-- The first group are representaional - referenced via <snref>     -->
2158
2159 <!-- Only one graphic element is declared.  The "class" attribute in
2160    - the refitem of the referring snref is used to distinguish between
2161    - figure, in-line or button.
2162   -->
2163 <!ELEMENT graphic   - O EMPTY    >
2164 <!ATTLIST graphic       id       ID                  #REQUIRED
2165                         format   CDATA               #IMPLIED
2166                         method   IDREF               #IMPLIED
2167                         xid      CDATA               #REQUIRED >
2168 -----------------------------------------------------------------------------*/
2169 static SDLContent GraphicContent[] =
2170     {
2171         { SDLInitMask(SdlElementGraphic), LoadGraphic     },
2172         { SDLInitMask(SdlElementNone)   , NULL            },
2173     };
2174
2175 static SDLElementAttrList  NotationAttrList[] =
2176     {
2177         { SDL_ATTR_ID    , SdlAttrValueRequired, NULL        },
2178         { SDL_ATTR_FORMAT, SdlAttrValueImplied , NULL        },
2179         { SDL_ATTR_METHOD, SdlAttrValueImplied , NULL        },
2180         { SDL_ATTR_XID   , SdlAttrValueRequired, NULL        },
2181         { -1               ,SdlAttrValueBad        , NULL }
2182     };
2183
2184 /*-----------------------------------------------------------------------------
2185 <!-- alternate rich text for use in a list of refitems in snref -->
2186 <!ELEMENT text      - - ((p | cp)*) >
2187 <!ATTLIST text          id       ID          #REQUIRED
2188                         language CDATA       #IMPLIED
2189
2190                         -- processor shld dflt charset to "ISO-8859-1"  --
2191                         charset  CDATA       #IMPLIED   >
2192 -----------------------------------------------------------------------------*/
2193 static SDLContent TextContent[] =
2194     {
2195         { SDLInitMask(SdlElementText)  , SaveLangCharSet             },
2196         { SDLInitMaskTwo(SdlElementPara, SdlElementCPara), ZeroToN   },
2197         { SDLInitMask(SdlElementNone)                    , NULL      },
2198     };
2199 static SDLElementAttrList  TextAttrList[] =
2200     {
2201         { SDL_ATTR_ID      , SdlAttrValueRequired, NULL      },
2202         { SDL_ATTR_LANGUAGE, SdlAttrValueImplied , NULL      },
2203         { SDL_ATTR_CHARSET , SdlAttrValueImplied , NULL      },
2204         { -1               , SdlAttrValueBad     , NULL      }
2205     };
2206
2207 /*-----------------------------------------------------------------------------
2208 <!ELEMENT audio     - O EMPTY >
2209 <!ATTLIST audio         id        ID                 #REQUIRED
2210                         format    CDATA              #IMPLIED
2211                         method    IDREF              #IMPLIED
2212                         xid       CDATA              #REQUIRED >
2213
2214 <!ELEMENT video     - O EMPTY >
2215 <!ATTLIST video         id        ID                 #REQUIRED
2216                         format    CDATA              #IMPLIED
2217                         method    IDREF              #IMPLIED
2218                         xid       CDATA              #REQUIRED >
2219
2220 <!ELEMENT animate   - O EMPTY >
2221 <!ATTLIST animate       id        ID                 #REQUIRED
2222                         format    CDATA              #IMPLIED
2223                         method    IDREF              #IMPLIED
2224                         xid       CDATA              #REQUIRED >
2225
2226 /----
2227 /- The audio, video, and animate use the NotationAttrList
2228 /- structure defined under graphic.
2229 /---
2230 -----------------------------------------------------------------------------*/
2231 /*-----------------------------------------------------------------------------
2232 <!-- Execute the content of this element using the specified "interp"
2233    - whenever the script element is referenced via an snref.  If the
2234    - script returns a value, that value effectively becomes the CDATA
2235    - content of the script element and is interpolated into the document
2236    - at the point of the snref.
2237   -->
2238 <!ELEMENT script    - - CDATA >
2239 <!ATTLIST script        id        ID                 #REQUIRED
2240                         -- processor should default interp to "ksh"   --
2241                         interp    NOTATION
2242                                   (tcl |
2243                                    sh  |
2244                                    ksh |
2245                                    csh )             #IMPLIED >
2246 -----------------------------------------------------------------------------*/
2247 static SDLContent ScriptContent[] =
2248     {
2249         { SDLInitMask(SdlElementScript)    , SetType   },
2250         { SDLInitMask(SdlElementCdata)     , ZeroOrOne },
2251         { SDLInitMask(SdlElementNone)      , NULL      },
2252     };
2253 static SDLElementAttrList  ScriptAttrList[] =
2254     {
2255         { SDL_ATTR_ID      , SdlAttrValueRequired, NULL      },
2256         { SDL_ATTR_INTERP  , SdlAttrValueImplied , "ksh"     },
2257         { -1               ,SdlAttrValueBad        , NULL }
2258     };
2259
2260
2261 /*-----------------------------------------------------------------------------
2262 <!-- The second group in the snb is linkage - referenced via <link>   -->
2263 <!ELEMENT crossdoc  - O EMPTY >
2264 <!ATTLIST crossdoc      id        ID                 #REQUIRED
2265
2266                         -- cross document link - doc & id   --
2267                         xid       CDATA              #REQUIRED >
2268
2269 <!ELEMENT man-page  - O EMPTY >
2270 <!ATTLIST man-page      id        ID                 #REQUIRED
2271                         xid       CDATA              #REQUIRED >
2272 -----------------------------------------------------------------------------*/
2273 static SDLContent CrossDocContent[] =
2274     {
2275         { SDLInitMask(SdlElementCrossDoc)  , RegisterSnbLink },
2276         { SDLInitMask(SdlElementNone)      , NULL         },
2277     };
2278
2279 static SDLContent ManPageContent[] =
2280     {
2281         { SDLInitMask(SdlElementManPage)   , RegisterSnbLink },
2282         { SDLInitMask(SdlElementNone)      , NULL         },
2283     };
2284
2285 static SDLElementAttrList  IdAndXidAttrList[] =
2286     {
2287         { SDL_ATTR_ID      , SdlAttrValueRequired, NULL      },
2288         { SDL_ATTR_XID     , SdlAttrValueRequired, NULL      },
2289         { -1               ,SdlAttrValueBad        , NULL }
2290     };
2291
2292 /*-----------------------------------------------------------------------------
2293 <!ELEMENT textfile  - O EMPTY >
2294 <!ATTLIST textfile      id        ID                 #REQUIRED
2295                         xid       CDATA              #REQUIRED
2296                         offset    CDATA              #IMPLIED
2297                         format    CDATA              #IMPLIED  >
2298 -----------------------------------------------------------------------------*/
2299 static SDLContent TextFileContent[] =
2300     {
2301         { SDLInitMask(SdlElementTextFile)  , RegisterSnbLink },
2302         { SDLInitMask(SdlElementNone)      , NULL         },
2303     };
2304
2305 static SDLElementAttrList  TextFileAttrList[] =
2306     {
2307         { SDL_ATTR_ID      , SdlAttrValueRequired, NULL      },
2308         { SDL_ATTR_XID     , SdlAttrValueRequired, NULL      },
2309         { SDL_ATTR_OFFSET  , SdlAttrValueImplied , ZeroStr   },
2310         { SDL_ATTR_FORMAT  , SdlAttrValueImplied , NULL      },
2311         { -1               ,SdlAttrValueBad        , NULL }
2312     };
2313
2314 /*-----------------------------------------------------------------------------
2315 <!ELEMENT sys-cmd   - O EMPTY >
2316 <!ATTLIST sys-cmd       id        ID                 #REQUIRED
2317                         command   CDATA              #REQUIRED >
2318 -----------------------------------------------------------------------------*/
2319 static SDLContent SysCmdContent[] =
2320     {
2321         { SDLInitMask(SdlElementSysCmd)    , RegisterSnbLink },
2322         { SDLInitMask(SdlElementNone)      , NULL         },
2323     };
2324
2325 static SDLElementAttrList  SysCmdAttrList[] =
2326     {
2327         { SDL_ATTR_ID      , SdlAttrValueRequired, NULL      },
2328         { SDL_ATTR_COMMAND , SdlAttrValueRequired, NULL      },
2329         { -1               ,SdlAttrValueBad        , NULL }
2330     };
2331
2332 /*-----------------------------------------------------------------------------
2333 <!ELEMENT callback  - O EMPTY >
2334 <!ATTLIST callback     id         ID                 #REQUIRED
2335                        data       CDATA              #IMPLIED  >
2336 -----------------------------------------------------------------------------*/
2337 static SDLContent CallbackContent[] =
2338     {
2339         { SDLInitMask(SdlElementCallback)  , RegisterSnbLink },
2340         { SDLInitMask(SdlElementNone)      , NULL         },
2341     };
2342
2343 static SDLElementAttrList  CallbackAttrList[] =
2344     {
2345         { SDL_ATTR_ID      , SdlAttrValueRequired, NULL      },
2346         { SDL_ATTR_DATA    , SdlAttrValueImplied , NULL      },
2347         { -1               ,SdlAttrValueBad        , NULL }
2348     };
2349
2350 /*-----------------------------------------------------------------------------
2351 <!-- The switch element is always hyperlinked to.  The interpreter,
2352    - interp, is called passing the CDATA content and returning a number
2353    - 0 to n.  The return value of the interpreter is used to index into
2354    - the list of branches and the hyperlink is continued to that ID.  A
2355    - return value less than zero or greater than the number of IDs minus
2356    - 1 causes the hyperlink to continue to branch 0.
2357   -->
2358 <!ELEMENT switch    - - CDATA >
2359 <!ATTLIST switch        id       ID          #REQUIRED
2360                         -- processor should default interp to "ksh"   --
2361                         interp   NOTATION
2362                                  (tcl |
2363                                   sh  |
2364                                   ksh |
2365                                   csh )      #IMPLIED
2366                         branches IDREFS      #REQUIRED >
2367 -----------------------------------------------------------------------------*/
2368 static SDLContent SwitchContent[] =
2369     {
2370         { SDLInitMask(SdlElementSwitch), SetType        },
2371         { SDLInitMask(SdlElementCdata) , ZeroOrOne      },
2372         { SDLInitMask(SdlElementSwitch), RegisterSwitch },
2373         { SDLInitMask(SdlElementNone)  , NULL           },
2374     };
2375 static SDLElementAttrList SwitchAttrList[] =
2376     {
2377         { SDL_ATTR_ID       , SdlAttrValueRequired, NULL      },
2378         { SDL_ATTR_INTERP   , SdlAttrValueImplied , "ksh"     },
2379         { SDL_ATTR_BRANCHES , SdlAttrValueRequired, NULL      },
2380         { -1                , SdlAttrValueBad     , NULL      }
2381     };
2382
2383 /*-----------------------------------------------------------------------------
2384 <!-- Generated Elements ______________________________________________-->
2385
2386 <!ELEMENT rel-docs  - O EMPTY >
2387 <!ELEMENT rel-file  - O EMPTY >
2388 <!ELEMENT notes     - O EMPTY >
2389
2390 <!-- The list of identifiers, loids, element is a list of ids in this
2391      document in the order they are defined.  The "count" attribute of
2392      loids is the number of ids it contains.  The higher level DTD to
2393      SDL translator may precompute "count" to enable the processor to
2394      preallocate space for the ids.  If "count" is not present, the
2395      processor must compute the number itself from the document.  The
2396      "type" attribute of id is the name of the element to which the
2397      id belongs.  The "rid" (referenced identifier) attribute is the
2398      identifier being listed.  The "rssi" (referenced source semantic
2399      identifier) is the "ssi" of the element to which the identifier
2400      belongs.  Similarly, the "rlevel" (referenced level) attribute
2401      is the "level" of the element to which the identifier belongs.
2402      Finally, the "offset" attribute is the byte offset in the document
2403      to the start of the virtual page containing the identifier. -->
2404 <!ELEMENT loids     - - (id*) >
2405 <!ATTLIST loids         count     NUMBER             #IMPLIED   >
2406 -----------------------------------------------------------------------------*/
2407 static SDLContent LoidsContent[] = {
2408         { SDLInitMask(SdlElementLoids), AllocateBlock },
2409         { SDLInitMask(SdlElementId)   , ZeroToN       },
2410         { SDLInitMask(SdlElementLoids), CleanUpBlock  },
2411         { SDLInitMask(SdlElementNone) , NULL          },
2412     };
2413
2414 static SDLElementAttrList  LoidsAttrList[] =
2415     {
2416         { SDL_ATTR_COUNT, SdlAttrValueImplied, NULL },
2417         { -1            , SdlAttrValueBad    , NULL }
2418     };
2419
2420 /*-----------------------------------------------------------------------------
2421 <!ELEMENT id        - O EMPTY >
2422 <!ATTLIST id            type     (virpage  |
2423                                   block    |
2424                                   form     |
2425                                   p        |
2426                                   cp       |
2427                                   head     |
2428                                   subhead  |
2429                                   anchor   |
2430                                   switch   |
2431                                   snref    |
2432                                   graphic  |
2433                                   text     |
2434                                   audio    |
2435                                   video    |
2436                                   animate  |
2437                                   crossdoc |
2438                                   man-page |
2439                                   textfile |
2440                                   sys-cmd  |
2441                                   script   |
2442                                   callback )         #REQUIRED
2443                         rid       IDREF              #REQUIRED
2444                         rssi      CDATA              #IMPLIED
2445                         rlevel    NUMBER             #IMPLIED
2446                         offset    NUMBER             #REQUIRED  >
2447 -----------------------------------------------------------------------------*/
2448 static SDLContent IdContent[] = {
2449         { SDLInitMask(SdlElementId)   , CopyIdInfo },
2450         { SDLInitMask(SdlElementNone) , NULL       },
2451     };
2452
2453 static SDLElementAttrList  IdAttrList[] =
2454     {
2455         { SDL_ATTR_TYPEID  , SdlAttrValueRequired, NULL },
2456         { SDL_ATTR_RID     , SdlAttrValueRequired, NULL },
2457         { SDL_ATTR_RLEVEL  , SdlAttrValueImplied , NegativeOneStr },
2458         { SDL_ATTR_RSSI    , SdlAttrValueImpliedDef, NULL },
2459         { SDL_ATTR_OFFSET  , SdlAttrValueRequired, NULL },
2460         { -1               , SdlAttrValueBad     , NULL }
2461     };
2462
2463 /*-----------------------------------------------------------------------------
2464 <!-- An index consists of zero or more entries.  Each entry contains
2465      the indexed (rich) text.  The "count" attribute of index is the
2466      number of entries (recursively) it contains.  The higher level
2467      DTD to SDL translator may precompute "count" to enable the
2468      processor to preallocate space for the entries.  If "count" is
2469      not present, the processor must compute the number itself from
2470      the document.  The "locs" and "main" attributes of an entry are
2471      lists of ids where the entry may be found.  Those ids found on
2472      the "main" list may be highlighted or emphasized in some way to
2473      indicate a greater importance than the ids found on the "locs"
2474      list - a definition, for example.  Otherwise, ids found on the
2475      "locs" list and the "main" list behave identically.  The "syns"
2476      attribute of an entry is another list of ids that refer to other
2477      entry elements and correspond to a "See also" or synonym type
2478      reference in an index.  The "sort" attribute is an optional sort
2479      key to be used if the indexed entry is to be sorted other than
2480      by its content.  The index should be pre-sorted although the
2481      optional sort keys are preserved in case multiple indexes need
2482      to be merged at some later date.  An entry element may also
2483      contain other entries to allow a hierarchical index to be
2484      generated. -->
2485 <!ELEMENT index     - - (entry*)                              >
2486 <!ATTLIST index         head      CDATA  #IMPLIED
2487                         count     NUMBER #IMPLIED              >
2488 -----------------------------------------------------------------------------*/
2489 static SDLContent IndexContent[] = {
2490         { SDLInitMask(SdlElementEntry), ZeroToN       },
2491         { SDLInitMask(SdlElementNone) , NULL          },
2492     };
2493
2494 static SDLElementAttrList  IndexAttrList[] =
2495     {
2496         { SDL_ATTR_COUNT, SdlAttrValueImplied, NULL },
2497         { -1            , SdlAttrValueBad    , NULL }
2498     };
2499
2500 /*-----------------------------------------------------------------------------
2501 <!ELEMENT entry     - - ((%simple; | #PCDATA)*, entry*)       >
2502 <!ATTLIST entry         id      ID     #IMPLIED
2503                         main    IDREFS #IMPLIED
2504                         locs    IDREFS #IMPLIED
2505                         syns    IDREFS #IMPLIED
2506                         sort    CDATA  #IMPLIED               >
2507 -----------------------------------------------------------------------------*/
2508 static SDLContent EntryContent[] = {
2509         { SDLInitMask(SdlElementEntry), CopyEntryInfo },
2510         { SDL_ENTITY_SIMPLE           , ZeroToN       },
2511         { SDLInitMask(SdlElementEntry), ZeroToN       },
2512         { SDLInitMask(SdlElementNone) , NULL          },
2513     };
2514
2515 static SDLElementAttrList  EntryAttrList[] =
2516     {
2517         { SDL_ATTR_ID      ,SdlAttrValueImpliedDef , NULL },
2518         { SDL_ATTR_MAIN    ,SdlAttrValueImpliedDef , NULL },
2519         { SDL_ATTR_LOCS    ,SdlAttrValueImpliedDef , NULL },
2520         { SDL_ATTR_SYNS    ,SdlAttrValueImpliedDef , NULL },
2521         { SDL_ATTR_SORT    ,SdlAttrValueImpliedDef , NULL },
2522         { -1               ,SdlAttrValueBad        , NULL }
2523     };
2524
2525 /*-----------------------------------------------------------------------------
2526 <!-- The lophrases (list of phrases) element is generated by the
2527      higher level DTD to SDL translator.  It is a list of phrases used
2528      from the toss element content in this document.  The phrases are
2529      used to map the users knowledge domain into the constructs used
2530      in SDL.  This information can be used to to pass the phrases
2531      available for structured/semantic searches to a browser or viewer
2532      to allow that browser or viewer to offer that information to the
2533      user.  The "count" attribute of lophrases is the number of phrases
2534      it contains.  The higher level DTD to SDL translator may precompute
2535      "count" to enable the processor to preallocate space for the
2536      phrases.  If "count" is not present, the processor must compute
2537      the number itself from the document.  -->
2538 <!ELEMENT lophrases - - (phrase+) >
2539 <!ATTLIST lophrases     count     NUMBER             #IMPLIED  >
2540 -----------------------------------------------------------------------------*/
2541 static SDLContent LoPhraseContent[] =
2542     {
2543         { SDLInitMask(SdlElementPhrase)                  , OneToN },
2544         { SDLInitMask(SdlElementNone)                    , NULL   },
2545     };
2546
2547 static SDLElementAttrList  LoPhraseAttrList[] =
2548     {
2549         { SDL_ATTR_COUNT, SdlAttrValueImplied, NULL },
2550         { -1            , SdlAttrValueBad    , NULL }
2551     };
2552 /*-----------------------------------------------------------------------------
2553 <!ELEMENT phrase    - O EMPTY     >
2554 <!ATTLIST phrase        text      CDATA              #REQUIRED >
2555 -----------------------------------------------------------------------------*/
2556 static SDLElementAttrList  PhraseAttrList[] =
2557     {
2558         { SDL_ATTR_TEXT    , SdlAttrValueRequired, NULL },
2559         { -1               ,SdlAttrValueBad        , NULL }
2560     };
2561
2562 /*-----------------------------------------------------------------------------
2563 <!-- The following element, toss (table of semantics and styles), is
2564      generated by the higher level DTD to SDL translator.  The "count"
2565      attribute of toss is the number of styles it contains.  The
2566      translator may precompute "count" to enable the processor to
2567      preallocate space for the styles.  If "count" is not present, the
2568      processor must compute the number itself from the document.  The
2569      first three attributes of each sub-element are used for lookup in
2570      the toss.  When formatting an element, the toss is searched for a
2571
2572      With the exception of the XLFD and Windows typeface name, an
2573      unspecified attribute implies inheritance.
2574
2575      The "phrase" attribute is an English (or natural language) phrase
2576      describing the intended use (semantics) of an element of this
2577      style.  -->
2578 <!ELEMENT toss      - - (keystyle*,
2579                         headstyle*,
2580                         formstyle*,
2581                         frmtstyle*,
2582                         grphstyle*) >
2583 <!ATTLIST toss          count     NUMBER             #IMPLIED   >
2584 -----------------------------------------------------------------------------*/
2585 static SDLContent TossContent[] = {
2586         { SDLInitMask(SdlElementToss)     , AllocateBlock },
2587         { SDLInitMask(SdlElementKeyStyle) , ZeroToN       },
2588         { SDLInitMask(SdlElementHeadStyle), ZeroToN       },
2589         { SDLInitMask(SdlElementFormStyle), ZeroToN       },
2590         { SDLInitMask(SdlElementFrmtStyle), ZeroToN       },
2591         { SDLInitMask(SdlElementGrphStyle), ZeroToN       },
2592         { SDLInitMask(SdlElementToss)     , CleanUpBlock  },
2593         { SDLInitMask(SdlElementNone)     , NULL          },
2594     };
2595
2596 static SDLElementAttrList  TossAttrList[] =
2597     {
2598         { SDL_ATTR_COUNT, SdlAttrValueImplied, NULL },
2599         { -1            , SdlAttrValueBad    , NULL }
2600     };
2601
2602 /*-----------------------------------------------------------------------------
2603 <!ELEMENT keystyle  - O EMPTY    >
2604 <!ATTLIST keystyle      class     (%key-class;)      #REQUIRED
2605                         ssi       CDATA              #IMPLIED
2606
2607                         -- the level of the element being described   --
2608                         rlevel    NUMBER             #IMPLIED
2609
2610                         phrase    CDATA              #IMPLIED
2611
2612                         -- likelihood that this element contains an   --
2613                         -- actual hit when doing a full text search   --
2614                         srch-wt   NUMBER             #IMPLIED
2615
2616                         -- strings to emit on entry and exit from key --
2617                         enter     CDATA              #IMPLIED
2618                         exit      CDATA              #IMPLIED
2619
2620                         %font-styles; >
2621 -----------------------------------------------------------------------------*/
2622 static SDLContent KeyStyleContent[] = {
2623         { SDLInitMask(SdlElementKeyStyle) , CopyTossInfo  },
2624         { SDLInitMask(SdlElementNone)     , NULL          },
2625     };
2626 static SDLElementAttrList  KeyStyleAttrList[] =
2627     {
2628         { SDL_ATTR_CLASSK  , SdlAttrValueRequired  , NULL },
2629         { SDL_ATTR_SSI     , SdlAttrValueImpliedDef, NULL },
2630         { SDL_ATTR_RLEVEL  , SdlAttrValueImplied   , NegativeOneStr },
2631         { SDL_ATTR_PHRASE  , SdlAttrValueImpliedDef, NULL },
2632         { SDL_ATTR_SRCHWT  , SdlAttrValueImplied   , NegativeOneStr },
2633         { SDL_ATTR_ENTER   , SdlAttrValueImpliedDef, NULL },
2634         { SDL_ATTR_EXIT    , SdlAttrValueImpliedDef, NULL },
2635         font_stylesAttrList,
2636         { -1               , SdlAttrValueBad       , NULL }
2637     };
2638
2639 /*-----------------------------------------------------------------------------
2640 <!ELEMENT headstyle - O EMPTY    >
2641 <!ATTLIST headstyle     class     (%head-class;)     #REQUIRED
2642                         ssi       CDATA              #IMPLIED
2643
2644                         -- the level of the element being described   --
2645                         rlevel    NUMBER             #IMPLIED
2646
2647                         phrase    CDATA              #IMPLIED
2648
2649                         -- likelihood that this element contains an   --
2650                         -- actual hit when doing a full text search   --
2651                         srch-wt   NUMBER             #IMPLIED
2652
2653                         -- horizontal orientation of the head with    --
2654                         -- respect to its associated document,        --
2655                         -- vstruct, virpage, snb, block, form, or p;  --
2656                         -- or of the subhead with respect to its      --
2657                         -- head.                                      --
2658                         -- procsr shld dflt orient to "center-orient" --
2659                         orient    (left-orient         |
2660                                    center-orient       |
2661                                    right-orient        |
2662                                    left-margin-orient  |
2663                                    right-margin-orient |
2664                                    left-corner-orient  |
2665                                    right-corner-orient )
2666                                                      #IMPLIED
2667
2668                         -- vertical orientation of the head or        --
2669                         -- subhead with respect to its parent.        --
2670                         -- procsor shld dflt vorient to "top-vorient" --
2671                         vorient   (top-vorient    |
2672                                    bottom-vorient |
2673                                    center-vorient )  #IMPLIED
2674
2675                         -- This attribute applies to head elements    --
2676                         -- only, since subheads cannot contain more   --
2677                         -- subheads.  The attribute determines        --
2678                         -- whether the vorient attribute applies to   --
2679                         -- the head only or to the entire head object --
2680                         -- including its subheads.                    --
2681                         -- processor shld deflt placement to "parent" --
2682                         placement (object | parent)  #IMPLIED
2683
2684                         -- Head width is the percent of the           --
2685                         -- available space for this element that      --
2686                         -- should be given to its head or the percent --
2687                         -- of the head that should be given to a      --
2688                         -- subhead.  It is expressed as a fixed point --
2689                         -- number 1 to 10000 with an implied decimal  --
2690                         -- point two places to the left of the right  --
2691                         -- side.                                      --
2692                         -- processor should default headw to "10000"  --
2693                         headw      CDATA             #IMPLIED
2694
2695                         -- where to put this head or subhead if it    --
2696                         -- collides with one already placed.          --
2697                         -- Horizontal stacking means place this one   --
2698                         -- under the other.  Vertical stacking means  --
2699                         -- place this one to the right of the other.  --
2700                         -- processor should default stack to "vert"   --
2701                         stack     (horiz | vert)     #IMPLIED
2702
2703                         -- does the body wrap around the head text?   --
2704                         -- "join" implies starting the content of the --
2705                         -- surrounding element immediatly after this  --
2706                         -- head (i.e., on the same line as the bottom --
2707                         -- of this head).
2708                         -- processor should default flow to "nowrap"  --
2709                         flow       (wrap   |
2710                                     nowrap |
2711                                     join)           #IMPLIED
2712
2713                         %font-styles;
2714                         %format-styles;
2715
2716                         -- applies to the text in the element, not   --
2717                         -- the element itself.                       --
2718                         -- prcsr shld dflt justify to "left-justify" --
2719                         justify  ( left-justify    |
2720                                    right-justify   |
2721                                    center-justify  |
2722                                    numeric-justify ) #IMPLIED >
2723
2724 -----------------------------------------------------------------------------*/
2725 static SDLContent HeadStyleContent[] = {
2726         { SDLInitMask(SdlElementHeadStyle), CopyTossInfo  },
2727         { SDLInitMask(SdlElementNone)     , NULL          },
2728     };
2729 static SDLElementAttrList  HeadStyleAttrList[] =
2730     {
2731         { SDL_ATTR_CLASSH   , SdlAttrValueRequired  , NULL           },
2732         { SDL_ATTR_SSI      , SdlAttrValueImpliedDef, NULL           },
2733         { SDL_ATTR_RLEVEL   , SdlAttrValueImplied   , NegativeOneStr },
2734         { SDL_ATTR_PHRASE   , SdlAttrValueImplied   , NULL           },
2735         { SDL_ATTR_SRCHWT   , SdlAttrValueImplied   , NegativeOneStr },
2736         { SDL_ATTR_ORIENT   , SdlAttrValueImplied   , CenterOrientStr},
2737         { SDL_ATTR_VORIENT  , SdlAttrValueImplied   , TopVOrientStr  },
2738         { SDL_ATTR_HEADWDTH , SdlAttrValueImplied   , TenThousandStr },
2739         { SDL_ATTR_PLACEMENT, SdlAttrValueImpliedDef, ParentStr      },
2740         { SDL_ATTR_STACK    , SdlAttrValueImpliedDef, "vert"         },
2741         { SDL_ATTR_FLOW     , SdlAttrValueImplied   , NoWrapStr      },
2742         font_stylesAttrList ,
2743         formt_stylesAttrList,
2744         { SDL_ATTR_JUSTIFY1 , SdlAttrValueImplied   , LeftJustifyStr }, 
2745         { -1                , SdlAttrValueBad       , NULL           }
2746     };
2747
2748 /*-----------------------------------------------------------------------------
2749 <!ELEMENT formstyle - O EMPTY    >
2750 <!ATTLIST formstyle     class     (%format-class;)   #REQUIRED
2751                         ssi       CDATA              #IMPLIED
2752
2753                         -- the level of the element being described   --
2754                         rlevel    NUMBER             #IMPLIED
2755
2756                         phrase    CDATA              #IMPLIED
2757
2758                         -- likelihood that this element contains an   --
2759                         -- actual hit when doing a full text search   --
2760                         srch-wt   NUMBER             #IMPLIED
2761
2762                         -- The widths of the columns in this form,    --
2763                         -- colw, is a space separated list of comma   --
2764                         -- separated integral triples.  If only two   --
2765                         -- comma separated numbers in a triple are    --
2766                         -- given, the second is replicated to make    --
2767                         -- three.  If only one number is given, the   --
2768                         -- other two are assumed to be 0. The first   --
2769                         -- number of a triple is the optimally        --
2770                         -- desired width.  The second number is how   --
2771                         -- much the column is willing to grow         --
2772                         -- relative to the other columns.  The third  --
2773                         -- number is how much the column is willing   --
2774                         -- to shrink relative to the other columns.   --
2775                         -- The numbers are summed and the total is    --
2776                         -- taken as 100 percent of available space.   --
2777                         -- That space is then divided among the       --
2778                         -- columns.  The process of summing and       --
2779                         -- dividing is repeated until all the         --
2780                         -- desired/shrink/grow constraints are met or --
2781                         -- it is known to be impossible to meet them. --
2782                         -- If meeting the constraints is impossible,  --
2783                         -- the column is handled similarly to a       --
2784                         -- graphic that will not fit, e.g., a scroll- --
2785                         -- bar may be added to allow the form to be   --
2786                         -- larger than the size of the viewing area.  --
2787                         -- There should be as many triples as given   --
2788                         -- in the value "ncols" in the "fstyle" sub-  --
2789                         -- element of the form element to which this  --
2790                         -- "formstyle" is being applied.  Extra       --
2791                         -- triples are ignored.  If less than "ncols" --
2792                         -- triples are provided, the last triple is   --
2793                         -- replicated.                                --
2794                         colw      CDATA               #IMPLIED
2795
2796                         -- Column justification, taken from one of    --
2797                         -- l | r | c | d (left, right, centered and   --
2798                         -- decimal), separated by spaces, for each    --
2799                         -- column of the form.  Extras are ignored.   --
2800                         -- If there are fewer than the number of      --
2801                         -- columns specified by the "ncols" attribute --
2802                         -- of the "fstyle" subelement of the "form"   --
2803                         -- to which this "formstyle" is being         --
2804                         -- applied, the last value is replicated.     --
2805                         -- The value defaults to "l" (left justified) --
2806                         colj      CDATA               #IMPLIED
2807
2808                         %font-styles;
2809                         %format-styles; >
2810
2811 -----------------------------------------------------------------------------*/
2812 static SDLContent FormStyleContent[] = {
2813         { SDLInitMask(SdlElementFormStyle), CopyTossInfo  },
2814         { SDLInitMask(SdlElementNone)     , NULL          },
2815     };
2816 static SDLElementAttrList  FormStyleAttrList[] =
2817     {
2818         { SDL_ATTR_CLASSF  , SdlAttrValueRequired  , NULL           },
2819         { SDL_ATTR_SSI     , SdlAttrValueImpliedDef, NULL           },
2820         { SDL_ATTR_RLEVEL  , SdlAttrValueImplied   , NegativeOneStr },
2821         { SDL_ATTR_PHRASE  , SdlAttrValueImplied   , NULL           },
2822         { SDL_ATTR_SRCHWT  , SdlAttrValueImplied   , NegativeOneStr },
2823         { SDL_ATTR_COLW    , SdlAttrValueImpliedDef, NULL           },
2824         { SDL_ATTR_COLJ    , SdlAttrValueImpliedDef, NULL           },
2825         font_stylesAttrList,
2826         formt_stylesAttrList,
2827         { -1               , SdlAttrValueBad       , NULL }
2828     };
2829 /*-----------------------------------------------------------------------------
2830 <!ELEMENT frmtstyle - O EMPTY    >
2831 <!ATTLIST frmtstyle     class     (%format-class;)   #REQUIRED
2832                         ssi       CDATA              #IMPLIED
2833
2834                         -- the level of the element being described   --
2835                         rlevel    NUMBER             #IMPLIED
2836
2837                         phrase    CDATA              #IMPLIED
2838
2839                         -- first line lmargin may be negative but     --
2840                         -- it's a number used to indicate extension   --
2841                         -- or indentation at start                    --
2842                         -- processor should default f-margin to "0"   --
2843                         f-margin  CDATA              #IMPLIED
2844
2845                         -- likelihood that this element contains an   --
2846                         -- actual hit when doing a full text search   --
2847                         srch-wt   NUMBER             #IMPLIED
2848
2849                         %font-styles;
2850                         %format-styles;
2851
2852                         -- applies to the text in the element, not   --
2853                         -- the element itself.                       --
2854                         -- prcsr shld dflt justify to "left-justify" --
2855                         justify  ( left-justify    |
2856                                    right-justify   |
2857                                    center-justify  |
2858                                    numeric-justify ) #IMPLIED >
2859 -----------------------------------------------------------------------------*/
2860 static SDLContent FrmtStyleContent[] = {
2861         { SDLInitMask(SdlElementFrmtStyle), CopyTossInfo  },
2862         { SDLInitMask(SdlElementNone)     , NULL          },
2863     };
2864 static SDLElementAttrList  FrmtStyleAttrList[] =
2865     {
2866         { SDL_ATTR_CLASSF   , SdlAttrValueRequired  , NULL           },
2867         { SDL_ATTR_SSI      , SdlAttrValueImpliedDef, NULL           },
2868         { SDL_ATTR_RLEVEL   , SdlAttrValueImplied   , NegativeOneStr },
2869         { SDL_ATTR_PHRASE   , SdlAttrValueImplied   , NULL           },
2870         { SDL_ATTR_SRCHWT   , SdlAttrValueImplied   , NegativeOneStr },
2871         { SDL_ATTR_FMARGIN  , SdlAttrValueImplied   , ZeroStr        },
2872         font_stylesAttrList ,
2873         formt_stylesAttrList,
2874         { SDL_ATTR_JUSTIFY1 , SdlAttrValueImplied   , LeftJustifyStr }, 
2875         { -1                , SdlAttrValueBad       , NULL           }
2876     };
2877 /*----------------------------------------------------------------------------- <!ELEMENT grphstyle - O EMPTY    >
2878 <!ATTLIST grphstyle     class     (%graphic-class;)  #REQUIRED
2879                         ssi       CDATA              #IMPLIED
2880
2881                         -- the level of the element being described   --
2882                         rlevel    NUMBER             #IMPLIED
2883
2884                         phrase    CDATA              #IMPLIED
2885
2886                         %format-styles;
2887
2888                         -- applies to the text in the element, not   --
2889                         -- the element itself.                       --
2890                         -- prcsr shld dflt justify to "left-justify" --
2891                         justify  ( left-justify    |
2892                                    right-justify   |
2893                                    center-justify ) #IMPLIED >
2894
2895 ] >
2896 -----------------------------------------------------------------------------*/
2897 static SDLContent GrphStyleContent[] = {
2898         { SDLInitMask(SdlElementGrphStyle), CopyTossInfo  },
2899         { SDLInitMask(SdlElementNone)     , NULL          },
2900     };
2901 static SDLElementAttrList  GrphStyleAttrList[] =
2902     {
2903         { SDL_ATTR_CLASSG   , SdlAttrValueRequired  , NULL           },
2904         { SDL_ATTR_SSI      , SdlAttrValueImpliedDef, NULL           },
2905         { SDL_ATTR_RLEVEL   , SdlAttrValueImplied   , NegativeOneStr },
2906         { SDL_ATTR_PHRASE   , SdlAttrValueImplied   , NULL           },
2907         formt_stylesAttrList,
2908         { SDL_ATTR_JUSTIFY2 , SdlAttrValueImplied   , LeftJustifyStr }, 
2909         { -1                , SdlAttrValueBad       , NULL           }
2910     };
2911
2912 static SDLContent CdataContent[] = {
2913         { SDLInitMask(SdlElementCdata), Cdata },
2914         { SDLInitMask(SdlElementNone) , NULL  },
2915     };
2916
2917 static SDLContent SDLDocumentContent[] = {
2918         { SDLInitMask(SdlElementSgml)   , ZeroOrOne },
2919         { SDLInitMask(SdlElementDocType), ZeroOrOne },
2920         { SDLInitMask(SdlElementSdlDoc) , OnlyOne   },
2921         { SDLInitMask(SdlElementNone)   , NULL      },
2922     };
2923
2924 /*
2925  * entries in this structure:
2926  *    all 'element strings'      must start with '<'
2927  *    all 'element end strings' must start with '</'
2928  *
2929  * If they don't, _DtHelpCeReturnSdlElement will fail
2930  */
2931 static  SDLElementInfo  SdlElementList[] =
2932   {
2933     {"<alttext"  , "</alttext" , 3, 3,
2934                         SdlElementAltText     ,
2935                         SDLInitMask(SdlElementNone),
2936                         NULL                  , AltTextContent  ,
2937                         False, False, False   , False, SdlToSnb          },
2938
2939     {AnchorStr   , NULL        , 4, 0,
2940                         SdlElementAnchor      ,
2941                         SDLInitMask(SdlElementNone),
2942                         AnchorAttrList        , AnchorContent   ,
2943                         False, True , False   , False, SdlToMarker       },
2944
2945     {AnimateStr  , NULL        , 4, 0,
2946                         SdlElementAnimate     ,
2947                         SDLInitMask(SdlElementNone),
2948                         NotationAttrList      , NULL            ,
2949                         False, True , False   , False, SdlToNone         },
2950
2951     {AudioStr    , NULL        , 3, 0,
2952                         SdlElementAudio       ,
2953                         SDLInitMask(SdlElementNone),
2954                         NotationAttrList      , NULL            ,
2955                         False, True , False   , False, SdlToNone         },
2956
2957     {BlockStr    , "</block"   , 2, 3,
2958                         SdlElementBlock       ,
2959                         SDLInitMask(SdlElementNone),
2960                         BlockAttrList         , BlockContent    ,
2961                         False, True, True     , True , SdlToContainer    },
2962
2963     {CallbackStr , NULL        , 3, 0,
2964                         SdlElementCallback    ,
2965                         SDLInitMask(SdlElementNone),
2966                         CallbackAttrList      , CallbackContent ,
2967                         True , False, False   , False, SdlToContainer    },
2968
2969     {"<cond"     , "</cond"    , 3, 4,
2970                         SdlElementCond        ,
2971                         SDLInitMask(SdlElementNone),
2972                         CondAttrList          , CondContent     ,
2973                         False, True , False   , False, SdlToContainer    },
2974
2975     {CParaStr    , "</cp"      , 3, 3,
2976                         SdlElementCPara       ,
2977                         SDLInitMask(SdlElementNone),
2978                         ParaAttrList          , CParaContent    ,
2979                         True , True, True     , True , SdlToContainer    },
2980
2981     {CrossdocStr , NULL        , 3, 0,
2982                         SdlElementCrossDoc    ,
2983                         SDLInitMask(SdlElementNone),
2984                         IdAndXidAttrList      , CrossDocContent ,
2985                         True , True , False   , False, SdlToContainer    },
2986
2987     {"<else"     , "</else"    , 3, 4,
2988                         SdlElementElse        ,
2989                         SDLInitMask(SdlElementNone),
2990                         NULL                  , ThenElseContent ,
2991                         False, False, False   , False, SdlToContainer    },
2992
2993     {"<entry"    , "</entry"   , 3, 4,
2994                         SdlElementEntry       ,
2995                         SDLInitMask(SdlElementNone),
2996                         EntryAttrList         , EntryContent    ,
2997                         False, True , False   , False, SdlToContainer    },
2998
2999     {"<fdata"    , "</fdata"   , 3, 4,
3000                         SdlElementFdata       ,
3001                         SDLInitMask(SdlElementNone),
3002                         NULL                  , FdataContent    ,
3003                         False, False, False   , False, SdlToNone         },
3004
3005 /*
3006  * when one element is a short version of another, put the longer element
3007  * before the short element so that tests will check it first.
3008  */
3009     {"<formstyle", NULL        , 6, 0,
3010                         SdlElementFormStyle   ,
3011                         SDLInitMask(SdlElementNone),
3012                         FormStyleAttrList     , FormStyleContent,
3013                         False, True , False   , False, SdlToContainer    },
3014
3015     {FormStr     , "</form"    , 5, 4,
3016                         SdlElementForm        ,
3017                         SDLInitMask(SdlElementNone),
3018                         FormAttrList          , FormContent     ,
3019                         False, True , False   , True , SdlToContainer    },
3020
3021     {"<frmtstyle", NULL        , 4, 0,
3022                         SdlElementFrmtStyle   ,
3023                         SDLInitMask(SdlElementNone),
3024                         FrmtStyleAttrList     , FrmtStyleContent,
3025                         False, True , False   , False, SdlToContainer    },
3026
3027     {"<frowvec"  , NULL        , 4, 0,
3028                         SdlElementFrowvec     ,
3029                         SDLInitMask(SdlElementNone),
3030                         FrowvecAttrList       , FrowvecContent  ,
3031                         False, True , False   , False, SdlToNone         },
3032
3033     {"<fstyle"   , "</fstyle"  , 3, 4,
3034                         SdlElementFstyle      ,
3035                         SDLInitMask(SdlElementNone),
3036                         FstyleAttrList        , FstyleContent   ,
3037                         False, True , False   , False, SdlToNone         },
3038
3039     { GraphicStr , NULL        , 4, 0,
3040                         SdlElementGraphic     ,
3041                         SDLInitMask(SdlElementNone),
3042                         NotationAttrList      , GraphicContent ,
3043                         True , True , False   , False, SdlToSnb          },
3044
3045     {"<grphstyle", NULL        , 4, 0,
3046                         SdlElementGrphStyle   ,
3047                         SDLInitMask(SdlElementNone),
3048                         GrphStyleAttrList     , GrphStyleContent,
3049                         False, True , False   , False, SdlToContainer    },
3050
3051 /*
3052  * when one element is a short version of another, put the longer element
3053  * before the short element so that tests will check it first.
3054  */
3055     {"<headstyle", NULL        , 6, 0,
3056                         SdlElementHeadStyle   ,
3057                         SDLInitMask(SdlElementNone),
3058                         HeadStyleAttrList     , HeadStyleContent,
3059                         False, True , True    , False, SdlToContainer    },
3060
3061     { HeadStr    , "</head"    , 5, 6,
3062                         SdlElementHead        ,
3063                         SDLInitMask(SdlElementNone),
3064                         HeadAttrList          , HeadContent     ,
3065                         False, True , True    , True , SdlToContainer    },
3066
3067     {"<id"       , NULL        , 3, 0,
3068                         SdlElementId          ,
3069                         SDLInitMask(SdlElementNone),
3070                         IdAttrList            , IdContent       ,
3071                         False, True , False   , False, SdlToContainer    },
3072
3073     {"<if"       , "</if"      , 3, 4,
3074                         SdlElementIf          ,
3075                         SDLInitMask(SdlElementNone),
3076                         NULL                  , IfContent       ,
3077                         False, False, False   , False, SdlToContainer    },
3078
3079     {"<index"    , "</index"    , 3, 4,
3080                         SdlElementIndex       ,
3081                         SDLInitMask(SdlElementNone),
3082                         IndexAttrList         , IndexContent    ,
3083                         False, True , False   , False, SdlToContainer    },
3084
3085     {"<keystyle" , NULL        , 6, 0,
3086                         SdlElementKeyStyle    ,
3087                         SDLInitMask(SdlElementNone),
3088                         KeyStyleAttrList      , KeyStyleContent ,
3089                         False, True , False   , False, SdlToContainer    },
3090
3091     {"<key"      , "</key"     , 4, 3,
3092                         SdlElementKey         ,
3093                         SDLInitMask(SdlElementLink),
3094                         KeyAttrList           , KeyContent      ,
3095                         True , True , False   , True , SdlToContainer    },
3096
3097     {"<link"     , "</link"    , 3, 4,
3098                         SdlElementLink        ,
3099                         SDLInitMask(SdlElementLink),
3100                         LinkAttrList          , LinkContent,
3101                         False, True , False   , False, SdlToContainer    },
3102
3103     {"<loids"    , "</loids"   , 4, 5,
3104                         SdlElementLoids       ,
3105                         SDLInitMask(SdlElementNone),
3106                         LoidsAttrList         , LoidsContent,
3107                         False, True , False   , False, SdlToContainer    },
3108
3109     {"<lophrases", "</lophrases", 4, 5,
3110                         SdlElementLoPhrases   ,
3111                         SDLInitMask(SdlElementNone),
3112                         LoPhraseAttrList      , LoPhraseContent,
3113                         False, True , False   , False, SdlToNone         },
3114
3115     {ManpageStr  , NULL        , 2, 0,
3116                         SdlElementManPage     ,
3117                         SDLInitMask(SdlElementNone),
3118                         IdAndXidAttrList      , ManPageContent,
3119                         True , True , False   , False, SdlToContainer    },
3120
3121     {"<notes"    , NULL        , 2, 0,
3122                         SdlElementNotes       ,
3123                         SDLInitMask(SdlElementNone),
3124                         NULL                  , NULL          ,
3125                         False, True , False   , False, SdlToNone         },
3126
3127     {"<phrase"   , NULL        , 3, 0,
3128                         SdlElementPhrase      ,
3129                         SDLInitMask(SdlElementNone),
3130                         PhraseAttrList        , NULL       ,
3131                         False, True , False   , False, SdlToNone         },
3132
3133     {ParaStr     , "</p"       , 2, 3,
3134                         SdlElementPara        ,
3135                         SDLInitMask(SdlElementNone),
3136                         ParaAttrList          , ParaContent,
3137                         True , True , False   , True , SdlToContainer    },
3138
3139     {"<refitem"  , "</refitem" , 4, 5,
3140                         SdlElementRefItem     ,
3141                         SDLInitMask(SdlElementNone),
3142                         RefItemAttrList       , RefItemContent,
3143                         False, True , False   , True , SdlToSnb          },
3144
3145     {"<rel-docs" , NULL        , 6, 0,
3146                         SdlElementRelDocs     ,
3147                         SDLInitMask(SdlElementNone),
3148                         NULL                  , NULL          ,
3149                         False, False, False   , False, SdlToNone         },
3150
3151     {"<rel-file" , NULL        , 6, 0,
3152                         SdlElementRelFile     ,
3153                         SDLInitMask(SdlElementNone),
3154                         NULL                  , NULL          ,
3155                         False, False, False   , False, SdlToNone         },
3156
3157     {"<rev"      , "</rev"     , 4, 5,
3158                         SdlElementRev         ,
3159                         SDLInitMask(SdlElementRev),
3160                         NULL                  , RevContent    ,
3161                         True , False, False   , False, SdlToNone         },
3162
3163     {ScriptStr   , "</script"  , 3, 4,
3164                         SdlElementScript      ,
3165                         SDLInitMask(SdlElementNone),
3166                         ScriptAttrList        , ScriptContent ,
3167                         False, True , False   , False, SdlToSnb          },
3168
3169     {"<sdldoc"   , "</sdldoc"  , 3, 4,
3170                         SdlElementSdlDoc      ,
3171                         SDLInitMask(SdlElementNone),
3172                         SdlDocAttrList        , SdlDocContent ,
3173                         False, True , False   , False, SdlToContainer    },
3174
3175     {"<snb"      , "</snb"     , 4, 5,
3176                         SdlElementSnb         ,
3177                         SDLInitMask(SdlElementNone),
3178                         SnbAttrList           , SnbContent    ,
3179                         False, True , False   , False, SdlToContainer    },
3180
3181     {SnrefStr    , "</snref"   , 4, 5,
3182                         SdlElementSnRef       ,
3183                         SDLInitMask(SdlElementNone),
3184                         SnrefAttrList         , SnrefContent  ,
3185                         False, True , False   , False, SdlToContainer    },
3186
3187     {"<spc"      , NULL        , 4, 0,
3188                         SdlElementSpc         ,
3189                         SDLInitMask(SdlElementNone),
3190                         SpcAttrList           , SpcContent    ,
3191                         False, True , False   , False, SdlToSpc          },
3192
3193     {"<sphrase"  , "</sphrase>", 4, 4,
3194                         SdlElementSphrase     ,
3195                         SDLInitMask(SdlElementNone),
3196                         SphraseAttrList       , SphraseContent ,
3197                         False, True , False   , True , SdlToContainer    },
3198
3199     { SubHeadStr , "</subhead" , 3, 4,
3200                         SdlElementSubHead     ,
3201                         SDLInitMask(SdlElementNone),
3202                         HeadAttrList          , SubHeadContent,
3203                         False, True , True    , True , SdlToContainer    },
3204
3205     { SwitchStr  , "</switch"  , 3, 4,
3206                         SdlElementSwitch      ,
3207                         SDLInitMask(SdlElementNone),
3208                         SwitchAttrList        , SwitchContent ,
3209                         True , True , False   , False, SdlToContainer    },
3210
3211     {SyscmdStr   , NULL        , 3, 0,
3212                         SdlElementSysCmd      ,
3213                         SDLInitMask(SdlElementNone),
3214                         SysCmdAttrList        , SysCmdContent ,
3215                         True , True , False   , False, SdlToContainer    },
3216
3217     {TextfileStr , NULL        , 6, 0,
3218                         SdlElementTextFile    ,
3219                         SDLInitMask(SdlElementNone),
3220                         TextFileAttrList      , TextFileContent,
3221                         True , True , False   , False, SdlToContainer    },
3222
3223     {TextStr     , "</text"    , 4, 4,
3224                         SdlElementText        ,
3225                         SDLInitMask(SdlElementNone),
3226                         TextAttrList          , TextContent   ,
3227                         True , False, False   , False, SdlToSnb          },
3228
3229     {"<then"     , "</then"    , 3, 4,
3230                         SdlElementThen        ,
3231                         SDLInitMask(SdlElementNone),
3232                         NULL                  , ThenElseContent,
3233                         False, False, False   , False, SdlToContainer    },
3234
3235     {"<toss"     , "</toss"    , 3, 4,
3236                         SdlElementToss        ,
3237                         SDLInitMask(SdlElementNone),
3238                         TossAttrList          , TossContent   ,
3239                         False, True , False   , False, SdlToContainer    },
3240
3241     {VideoStr    , NULL        , 4, 0,
3242                         SdlElementVideo       ,
3243                         SDLInitMask(SdlElementNone),
3244                         NotationAttrList      , NULL          ,
3245                         False, True , False   , False, SdlToNone         },
3246
3247     {VirpageStr  , "</virpage" , 4, 4,
3248                         SdlElementVirpage     ,
3249                         SDLInitMask(SdlElementNone),
3250                         VirpageAttrList       , VirpageContent,
3251                         False, True , False   , True , SdlToContainer    },
3252
3253     {VirpageStr  , "</virpage" , 4, 4,
3254                         SdlElementTitle     ,
3255                         SDLInitMask(SdlElementNone),
3256                         VirpageAttrList       , VirpageHeadContent,
3257                         False, True , False   , True , SdlToContainer    },
3258
3259     {"<vstruct"  , "</vstruct" , 3, 4,
3260                         SdlElementVStruct     ,
3261                         SDLInitMask(SdlElementNone),
3262                         VStructAttrList       , VStructContent,
3263                         False, True , False   , False, SdlToNone         },
3264
3265     {"<!--"      , NULL        , 3, 0,
3266                         SdlElementComment     ,
3267                         SDLInitMask(SdlElementNone),
3268                         NULL                  , NULL          ,
3269                         False, True , False   , False, SdlToNone         },
3270
3271     {"<!doctype" , NULL        , 3, 0,
3272                         SdlElementDocType     ,
3273                         SDLInitMask(SdlElementNone),
3274                         NULL                  , NULL          ,
3275                         False, True , False   , False, SdlToNone         },
3276
3277     {"<!sgml"    , NULL        , 3, 0,
3278                         SdlElementSgml        ,
3279                         SDLInitMask(SdlElementNone),
3280                         NULL                  , NULL          ,
3281                         False, True , False   , False, SdlToNone         },
3282
3283     { NULL       , NULL        , 0, 0,
3284                         SdlElementCdata       ,
3285                         SDLInitMask(SdlElementNone),
3286                         NULL                  , CdataContent  ,
3287                         False, False, False   , False, SdlToNone         },
3288   };
3289
3290 static  int MaxSDLElements = sizeof (SdlElementList) / sizeof (SDLElementInfo);
3291
3292 \f
3293 /******************************************************************************
3294  * Private Macros
3295  *****************************************************************************/
3296 #define MyFree(x)       if ((char *)(x) != NULL) free(x)
3297 #define SaveRestoreMask(x,y) \
3298                 { register int myI;\
3299                   for (myI = 0; myI < SDL_MASK_LEN; myI++) \
3300                       x[myI] = y[myI]; \
3301                 }
3302 #define MergeMasks(x,y) \
3303                 { register int myI;\
3304                   for (myI = 0; myI < SDL_MASK_LEN; myI++) \
3305                       x[myI] |= y[myI]; \
3306                 }
3307 #define RemoveMasks(x,y) \
3308                 { register int myI;\
3309                   for (myI = 0; myI < SDL_MASK_LEN; myI++) \
3310                       x[myI] &= (~(y[myI])); \
3311                 }
3312 #define MaskToValue(x,y) \
3313                 { register int myI;\
3314                   register SDLMask myMask;\
3315                   for (myI = 0, y = 0; myI < SDL_MASK_LEN; myI++) \
3316                       if (x[myI] == 0) \
3317                           y += SDL_MASK_SIZE; \
3318                       else \
3319                         { \
3320                           myMask = x[myI]; \
3321                           while (myMask > 1) \
3322                             { \
3323                                 myMask = myMask >> 1; y++; \
3324                             } \
3325                           myI = SDL_MASK_LEN; \
3326                         } \
3327                 }
3328 #define ClearAttrFlag(pa, attr) \
3329                 { \
3330                   int  mask = attr & VALUE_MASK; \
3331                   int  flag = ~(attr & (~VALUE_MASK)); \
3332  \
3333                   if (mask == ENUM_VALUE) \
3334                       (pa).enum_values = (pa).enum_values & flag; \
3335                   else if (mask == NUMBER_VALUE) \
3336                       (pa).num_values = (pa).num_values & flag; \
3337                   else if (mask == STRING1_VALUE) \
3338                       (pa).str1_values = (pa).str1_values & flag; \
3339                   else if (mask == STRING2_VALUE) \
3340                       (pa).str2_values = (pa).str2_values & flag; \
3341                 }
3342
3343 /******************************************************************************
3344  *
3345  * Private Functions
3346  *
3347  *****************************************************************************/
3348 /******************************************************************************
3349  * Function: CompressTable
3350  *
3351  *****************************************************************************/
3352 static _DtCvSegment *
3353 CompressTable(
3354     FormatStruct        *my_struct,
3355     _DtCvSegment        *seg)
3356 {
3357     _DtCvSegment  *retSeg = seg;
3358     _DtCvSegment **tableSegs;
3359     char         **rowIds;
3360
3361     /*
3362      * make sure we're working with a non-null segment.
3363      */
3364     if (NULL != seg)
3365       {
3366         /*
3367          * get the row ids.
3368          */
3369         rowIds = _DtCvCellIdsOfTableSeg(seg);
3370
3371         /*
3372          * if there is only one column and zero to one rows,
3373          * compress out the table
3374          */
3375         if (1 == _DtCvNumColsOfTableSeg(seg) &&
3376                 (NULL == rowIds || NULL == *rowIds || NULL == rowIds[1]))
3377           {
3378             /*
3379              * get the list of table segments.
3380              */
3381             tableSegs = _DtCvCellsOfTableSeg(seg);
3382
3383             /*
3384              * now find the correct segment. Start out with a null return.
3385              */
3386             retSeg = NULL;
3387             if (NULL != rowIds && NULL != *rowIds)
3388               {
3389                 _DtCvSegment *prevSeg = NULL;
3390
3391                 /*
3392                  * look through the table's list for the one segment
3393                  * to fill the one column/row table.
3394                  */
3395                 while (NULL != tableSegs && NULL != *tableSegs &&
3396                    _DtCvStrCaseCmpLatin1(*rowIds, _DtCvContainerIdOfSeg(*tableSegs)))
3397                   {
3398                     prevSeg = *tableSegs;
3399                     tableSegs++;
3400                   }
3401
3402                 /*
3403                  * does the segment exist in the table's list?
3404                  */
3405                 if (NULL != tableSegs && NULL != *tableSegs)
3406                   {
3407                     /*
3408                      * set the return value.
3409                      */
3410                     retSeg = *tableSegs;
3411
3412                     /*
3413                      * now propagate the justification.
3414                      */
3415                     if (_DtCvINHERIT == _DtCvContainerJustifyOfSeg(retSeg)
3416                                 && NULL != _DtCvColJustifyOfTableSeg(seg))
3417                         _DtCvContainerJustifyOfSeg(retSeg) =
3418                                         *(_DtCvColJustifyOfTableSeg(seg));
3419
3420                     /*
3421                      * now move up any other table segments, whereby
3422                      * eliminating this segment from the list so it
3423                      * won't be freed via _DtHelpFreeSegments().
3424                      */
3425                     while (NULL != *tableSegs)
3426                       {
3427                         *tableSegs = tableSegs[1];
3428                         tableSegs++;
3429                       }
3430                   }
3431               }
3432
3433             /*
3434              * Now free the table segment
3435              */
3436             _DtHelpFreeSegments(seg, _DtCvFALSE,
3437                                 my_struct->ui_info->destroy_region,
3438                                         my_struct->ui_info->client_data);
3439           }
3440       }
3441
3442     return retSeg;
3443 }
3444
3445 /******************************************************************************
3446  * Function: PropagateJustification
3447  *
3448  *****************************************************************************/
3449 static void
3450 PropagateJustification(
3451     _DtCvSegment         *seg,
3452     _DtCvFrmtOption       justify)
3453 {
3454     if (NULL != seg && _DtCvIsSegContainer(seg) &&
3455                         _DtCvINHERIT == _DtCvContainerJustifyOfSeg(seg))
3456         _DtCvContainerJustifyOfSeg(seg) = justify;
3457 }
3458
3459 /******************************************************************************
3460  * Function:    void FreeAttributes (enum SdlElement element,
3461  *                              CESDLAttrStruct *attributes)
3462  *
3463  * Parameters:
3464  *
3465  * Returns:     
3466  *
3467  * Purpose:
3468  *
3469  ******************************************************************************/
3470 static void
3471 FreeAttributes(
3472     enum SdlElement      element,
3473     ElementInfo         *cur_info,
3474     _DtHelpFontHints    *font_specs)
3475 {
3476     register int i = 0;
3477     const SDLElementAttrList *myList;
3478     const SDLAttribute  *attrib;
3479     char                *varOffset;
3480     char                **strPtr;
3481
3482     while (i < MaxSDLElements && SdlElementList[i].sdl_element != element)
3483         i++;
3484
3485     myList = SdlElementList[i].attrib_list;
3486
3487     if (myList != NULL &&
3488                 (cur_info->str1_values != 0 || cur_info->str2_values != 0))
3489       {
3490         while (myList->sdl_attr_define != -1)
3491           {
3492             if (SDLIsStrAttrSet(*cur_info, myList->sdl_attr_define) &&
3493                 SDLIsAttrSet(*cur_info, myList->sdl_attr_define))
3494               {
3495                 attrib = SDLAttributeList;
3496                 while (attrib->sdl_attr_define != -1 &&
3497                         !ATTRS_EQUAL(attrib->data_type,
3498                                         myList->sdl_attr_define,
3499                                         attrib->sdl_attr_define))
3500                     attrib++;
3501
3502                 if (attrib->struct_type == SdlFontSpecific ||
3503                                 attrib->struct_type == SdlElementSpecific)
3504                   {
3505                     if (attrib->struct_type == SdlFontSpecific)
3506                         varOffset = ((char *) font_specs);
3507                     else if (attrib->struct_type == SdlElementSpecific)
3508                         varOffset = ((char *) cur_info);
3509
3510                     varOffset = varOffset + attrib->field_ptr;
3511                     strPtr    = (char **) varOffset;
3512
3513                     if (NULL != *strPtr)
3514                         free (*strPtr);
3515                   }
3516               }
3517             myList++;
3518           }
3519       }
3520 }
3521 /******************************************************************************
3522  * Function: DuplicateElement
3523  *
3524  *****************************************************************************/
3525 static _DtCvSegment *
3526 DuplicateElement(
3527     _DtCvPointer          client_data,
3528     _DtCvSegment         *toss,
3529     _DtCvSegment         *src_seg,
3530     _DtCvSegment        **prev_data,
3531     _DtCvSegment        **last_seg,
3532     void                (*load_font)(),
3533     _DtCvValue          (*resolve_spc)(),
3534     _DtCvUnit             line_height,
3535     int                   ave_char,
3536     _DtHelpFontHints      srcFonts,
3537     int                   link_idx,
3538     _DtCvValue            vis_link)
3539 {
3540     int                  oldIndex = link_idx;
3541     _DtCvSegment        *topSeg   = NULL;
3542     _DtCvSegment        *prevData = NULL;
3543     _DtCvSegment        *lastSeg  = NULL;
3544     _DtCvSegment        *newSeg;
3545     _DtHelpFontHints     curFonts;
3546     SdlMatchData        *match;
3547     _DtHelpDARegion     *region;
3548     FrmtPrivateInfo     *priv;
3549
3550     if (NULL != prev_data)
3551         prevData = *prev_data;
3552
3553     if (NULL != last_seg)
3554         lastSeg = *last_seg;
3555
3556     while (src_seg != NULL)
3557       {
3558         curFonts   = srcFonts;
3559         link_idx = oldIndex;
3560         if (_DtCvIsSegHyperText(src_seg) || _DtCvIsSegGhostLink(src_seg))
3561           {
3562             link_idx = src_seg->link_idx;
3563             if (_DtCvIsSegHyperText(src_seg))
3564                 vis_link = True;
3565           }
3566
3567         if (_DtHelpCeAllocSegment(1, NULL, NULL, &newSeg) != 0)
3568             return NULL;
3569
3570         /*
3571          * copy over the information. (But don't blow away the private
3572          * information, except - keep the dup flag.)
3573          */
3574         priv    = FrmtPrivInfoPtr(newSeg);
3575         *newSeg = *src_seg;
3576         newSeg->client_use = priv;
3577         priv->dup_flag     = FrmtPrivInfoPtr(src_seg)->dup_flag;
3578
3579         /*
3580          * set the duplicate on the source seg. That way, allocated memory
3581          * now belongs to the new segment.
3582          */
3583         SetDupFlag(src_seg);
3584
3585         /*
3586          * now re-set some information pertinent to this flow of control
3587          */
3588         newSeg->link_idx = link_idx;
3589         newSeg->type       = ClearSegLinks(newSeg);
3590         if (link_idx != -1)
3591           {
3592             if (vis_link == True)
3593                 newSeg->type = _DtCvSetTypeToHyperText(newSeg->type);
3594             else
3595                 newSeg->type = _DtCvSetTypeToGhostLink(newSeg->type);
3596           }
3597         _DtCvNextSeg(newSeg) = NULL;
3598         newSeg->next_disp  = NULL;
3599
3600         /*
3601          * put this segment into the list.
3602          */
3603         if (NULL != lastSeg)
3604             _DtCvNextSeg(lastSeg) = newSeg;
3605
3606         /*
3607          * type cast the internal structure to a match data struct
3608          * now, since more than one element may use it.
3609          */
3610         match = SegMatchDataPtr(src_seg);
3611
3612         switch (_DtCvPrimaryTypeOfSeg(newSeg))
3613           {
3614             case _DtCvCONTAINER:
3615                 /*
3616                  * merge the attributes into the new elements.
3617                  */
3618                 if (NULL != match)
3619                   {
3620                     if (NULL != toss)
3621                       {
3622                         _DtHelpCeMergeSdlAttribInfo(
3623                                                 _DtHelpCeMatchSemanticStyle(
3624                                                         toss,
3625                                                         match->clan,
3626                                                         match->level,
3627                                                         match->ssi),
3628                                                 newSeg,
3629                                                 &curFonts,
3630                                                 NULL,
3631                                                 NULL,
3632                                                 NULL);
3633                         /*
3634                          * set the margins to absolute values
3635                          */
3636                         if (ave_char > 0)
3637                           {
3638                             _DtCvContainerLMarginOfSeg(newSeg) =
3639                                 _DtCvContainerLMarginOfSeg(newSeg) * ave_char;
3640                             _DtCvContainerRMarginOfSeg(newSeg) =
3641                                 _DtCvContainerRMarginOfSeg(newSeg) * ave_char;
3642                             _DtCvContainerFMarginOfSeg(newSeg) =
3643                                 _DtCvContainerFMarginOfSeg(newSeg) * ave_char;
3644                           }
3645                         /*
3646                          * set the top and bottom margins to absolute values
3647                          */
3648                         if (line_height > 0)
3649                           {
3650                             TMarginOfSeg(newSeg) = 
3651                                         TMarginOfSeg(newSeg) * line_height;
3652                             BMarginOfSeg(newSeg) =
3653                                         BMarginOfSeg(newSeg) * line_height;
3654                           }
3655                       }
3656                   }
3657                 _DtCvContainerListOfSeg(newSeg) = DuplicateElement(
3658                                         client_data,
3659                                         toss,
3660                                         _DtCvContainerListOfSeg(src_seg),
3661                                         &prevData,
3662                                         &lastSeg,
3663                                         load_font,
3664                                         resolve_spc,
3665                                         line_height,
3666                                         ave_char,
3667                                         curFonts,
3668                                         link_idx,
3669                                         vis_link);
3670
3671                 if (NULL == _DtCvContainerListOfSeg(newSeg))
3672                   {
3673                     free(newSeg);
3674                     return NULL;
3675                   }
3676
3677                 /*
3678                  * if this is a wrapper, throw it away
3679                  */
3680                 if (IsSdlWrapper(newSeg->type))
3681                   {
3682                     _DtCvSegment *tmpSeg = newSeg;
3683
3684                     newSeg = _DtCvContainerListOfSeg(newSeg);
3685                     free(tmpSeg);
3686                   }
3687                 break;
3688
3689             case _DtCvSTRING:
3690                 /*
3691                  * now load the font for this element
3692                  */
3693                 (load_font)(client_data,
3694                                         _DtHelpFontHintsLang(curFonts),
3695                                         _DtHelpFontHintsCharSet(curFonts),
3696                                         curFonts,
3697                                         &(_DtCvFontOfStringSeg(newSeg)));
3698
3699                 /*
3700                  * put this segment in the display list.
3701                  */
3702                 if (NULL != prevData)
3703                     prevData->next_disp = newSeg;
3704
3705                 prevData = newSeg;
3706                 break;
3707
3708             case _DtCvREGION:
3709                 region = (_DtHelpDARegion *) _DtCvInfoOfRegionSeg(src_seg);
3710                 if (False == region->inited)
3711                   {
3712                     _DtHelpDASpcInfo *spcInfo =
3713                                         (_DtHelpDASpcInfo *) region->handle;
3714
3715                     (resolve_spc)(client_data,
3716                                         _DtHelpFontHintsLang(curFonts),
3717                                         _DtHelpFontHintsCharSet(curFonts),
3718                                         curFonts,
3719                                         spcInfo->name,
3720                                         &(_DtCvInfoOfRegionSeg(newSeg)),
3721                                         &(_DtCvWidthOfRegionSeg(newSeg)),
3722                                         &(_DtCvHeightOfRegionSeg(newSeg)),
3723                                         &(_DtCvAscentOfRegionSeg(newSeg)));
3724
3725                     ClearDupFlag(src_seg);
3726                   }
3727
3728                 /*
3729                  * check for in-line flags on this item.
3730                  */
3731                 if (NULL != match &&
3732                         (SdlClassInLine == match->clan ||
3733                          SdlClassButton == match->clan ||
3734                          SdlClassIcon   == match->clan))
3735                     newSeg->type = _DtCvSetTypeToInLine(newSeg->type);
3736
3737                 /*
3738                  * put this segment in the display list.
3739                  */
3740                 if (NULL != prevData)
3741                     prevData->next_disp = newSeg;
3742
3743                 prevData = newSeg;
3744                 break;
3745           }
3746
3747         if (topSeg == NULL)
3748             topSeg = newSeg;
3749
3750         lastSeg = newSeg;
3751         src_seg = _DtCvNextSeg(src_seg);
3752       }
3753
3754     if (NULL != prev_data)
3755         *prev_data = prevData;
3756
3757     if (NULL != last_seg)
3758         *last_seg = lastSeg;
3759
3760     return topSeg;
3761 }
3762
3763 /******************************************************************************
3764  * Function:    _DtCvSegment *ResolveSnref (FormatStruct my_struct,
3765  *                                              int element_types,
3766  *                                              int exceptions);
3767  *
3768  * Parameters:
3769  *
3770  * Returns:     0 if successful, -1 if errors
3771  *
3772  * Purpose:     Looks for the virtual page attributes.
3773  *
3774  ******************************************************************************/
3775 static  _DtCvSegment *
3776 ResolveSnref(
3777     FormatStruct        *my_struct,
3778     _DtCvSegment        *snref,
3779     char                *snref_id)
3780 {
3781     _DtCvValue   found      = False;
3782     _DtCvSegment        *snbEntry   = NULL;
3783     _DtCvSegment        *altText    = NULL;
3784     _DtCvSegment        *newSeg     = NULL;
3785     _DtCvSegment        *refItem    = _DtCvContainerListOfSeg(snref);
3786     FrmtPrivateInfo     *priv;
3787     _DtHelpFontHints     saveFonts  = *(my_struct->my_fonts);
3788
3789     /*
3790      * Check to see if a snb has been found yet. If not, put off resolving
3791      * refitems.
3792      */
3793     if (NULL != my_struct->snb)
3794       {
3795         /*
3796          * check each refitem to see if it can be resolved
3797          */
3798         while (False == found && NULL != refItem)
3799           {
3800             /*
3801              * assume the refitem will be found in the snb
3802              */
3803             found    = True;
3804             snbEntry = NULL;
3805             if (NULL != _DtCvContainerIdOfSeg(refItem))
3806                 snbEntry = FindSnbEntry(my_struct->snb,
3807                                         _DtCvContainerIdOfSeg(refItem));
3808             else
3809                 /* the <alttext> container */
3810                 altText  = refItem;
3811
3812             if (NULL == snbEntry)
3813               {
3814                 /*
3815                  * didn't find the refitem, so set the flag
3816                  * for another loop.
3817                  */
3818                 found   = False;
3819                 refItem = _DtCvNextSeg(refItem);
3820               }
3821           }
3822
3823         /*
3824          * was a system notation block item found?
3825          */
3826         if (True == found)
3827           {
3828             /*
3829              * an refitem can be a region (graphic, audio, video, animate),
3830              * text or a script. If a script, need to process it differently.
3831              */
3832             priv = FrmtPrivInfoPtr(snbEntry);
3833             if (SdlElementScript == priv->sdl_el_type)
3834               {
3835                 /*
3836                  * NULL variables, get the interpretor.
3837                  */
3838                 SdlMatchData *match;
3839                 char *runData;
3840                 char *newData   = NULL;
3841                 char *interpStr = GetInterpCmd((SdlOption) (priv->interp));
3842
3843                 /*
3844                  * get the data to run
3845                  */
3846                 runData = _DtCvStringOfStringSeg(
3847                                         _DtCvContainerListOfSeg(snbEntry));
3848
3849                 if (NULL == interpStr
3850                         || -1 == _DtCvRunInterp(my_struct->ui_info->exec_filter,
3851                                         my_struct->ui_info->client_data,
3852                                         interpStr, runData, &newData)
3853                         || NULL == newData || 0 == strlen(newData))
3854                     return NULL;
3855
3856                 /*
3857                  * set the match data for toss lookup
3858                  */
3859                 match = SegMatchDataPtr(refItem);
3860
3861                 if (NULL != match && NULL != my_struct->toss)
3862                     _DtHelpCeMergeSdlAttribInfo(
3863                                         _DtHelpCeMatchSemanticStyle(
3864                                                         my_struct->toss,
3865                                                         match->clan,
3866                                                         match->level,
3867                                                         match->ssi),
3868                                         newSeg,
3869                                         my_struct->my_fonts,
3870                                         NULL,
3871                                         NULL,
3872                                         NULL);
3873
3874                 if (0 != MySaveString(&newSeg, my_struct, newData,
3875                                         my_struct->cur_link, my_struct->mb_len,
3876                                         False))
3877                     return NULL;
3878
3879                 free(newData);
3880               }
3881             else
3882               {
3883                 /*
3884                  * strip the container wrapper from the snbEntry before
3885                  * duplication.
3886                  *
3887                  * Also, include the toss match data for this segment
3888                  * in the snbEntry.
3889                  */
3890                 snbEntry = _DtCvContainerListOfSeg(snbEntry);
3891                 if (NULL != snbEntry)
3892                   {
3893                     SegMatchData(snbEntry) = SegMatchData(refItem);
3894
3895                     newSeg = DuplicateElement(my_struct->ui_info->client_data,
3896                                         my_struct->toss,
3897                                         snbEntry,
3898                                         &(my_struct->prev_data),
3899                                         NULL,
3900                                         my_struct->ui_info->load_font,
3901                                         my_struct->ui_info->resolve_spc,
3902                                         my_struct->ui_info->line_height / 2,
3903                                         my_struct->ui_info->avg_char,
3904                                         *(my_struct->my_fonts),
3905                                         my_struct->cur_link, True);
3906
3907                     SegMatchData(snbEntry) = NULL;
3908
3909                     if (NULL == newSeg)
3910                         return NULL;
3911
3912                     /*
3913                      * if the only item in the list for the snb entry is
3914                      * a region, then assume it is a graphic, video, etc.
3915                      * Check to see if the region is in-line or a figure.
3916                      * If in-line, ignore any heads with the refitem. If a
3917                      * figure, include them (they may be a caption to the
3918                      * region).
3919                      */
3920                     if (_DtCvIsSegRegion(newSeg) && NULL == _DtCvNextSeg(newSeg))
3921                       {
3922                         SdlMatchData *info = SegMatchDataPtr(refItem);
3923
3924                         /*
3925                          * is this a figure?
3926                          */
3927                         if (SdlClassFigure == info->clan)
3928                           {
3929                             _DtCvNextSeg(newSeg) = _DtCvContainerListOfSeg(refItem);
3930                             _DtCvContainerListOfSeg(refItem) = NULL;
3931                           }
3932                       }
3933                   }
3934               }
3935           }
3936
3937         /*
3938          * was there alternate text?
3939          */
3940         else if (NULL != altText && NULL != _DtCvContainerListOfSeg(altText))
3941           {
3942             /*
3943              * the new segment becomes the contents of the <alttext>
3944              * container - why copy? Just null the <alttext> pointer
3945              * to prevent the free from destroying the contents.
3946              */
3947             newSeg = _DtCvContainerListOfSeg(altText);
3948             _DtCvContainerListOfSeg(altText) = NULL;
3949
3950             /*
3951              * load the font for this snref.
3952              */
3953             (my_struct->ui_info->load_font)(my_struct->ui_info->client_data,
3954                                 _DtHelpFontHintsLang(*(my_struct->my_fonts)),
3955                                 _DtHelpFontHintsCharSet(*(my_struct->my_fonts)),
3956                                 *(my_struct->my_fonts),
3957                                 &(_DtCvFontOfStringSeg(newSeg)));
3958           }
3959
3960         if (my_struct->prev_data != NULL)
3961             my_struct->prev_data->next_disp = newSeg;
3962
3963         my_struct->last_was_space = False;
3964         my_struct->last_was_mb    = False;
3965         my_struct->last_was_nl    = False;
3966         if (NULL != newSeg)
3967             my_struct->prev_data      = newSeg;
3968       }
3969     else if (_DtCvTRUE == my_struct->save_snref)
3970       {
3971         int count = my_struct->snref_cnt;
3972
3973         if (NULL == my_struct->un_snrefs)
3974             my_struct->un_snrefs = (UnresSnref *) malloc (sizeof(UnresSnref));
3975         else
3976             my_struct->un_snrefs = (UnresSnref *) realloc (
3977                                         (void *) my_struct->un_snrefs,
3978                                         (sizeof(UnresSnref) * (count + 1)));
3979         if (NULL != my_struct->un_snrefs)
3980           {
3981             my_struct->un_snrefs[count].id       = snref_id;
3982             my_struct->un_snrefs[count].seg      = snref;
3983             my_struct->un_snrefs[count].cur_link = my_struct->cur_link;
3984             my_struct->un_snrefs[count].fonts    = *(my_struct->my_fonts);
3985
3986             my_struct->snref_cnt++;
3987
3988             /*
3989              * return the snref segment as our new segment to act as a
3990              * place holder, otherwise it gets squeezed
3991              * out.
3992              */
3993             newSeg = snref;
3994
3995             if (my_struct->prev_data != NULL)
3996                 my_struct->prev_data->next_disp = newSeg;
3997
3998             my_struct->prev_data      = newSeg;
3999
4000             /*
4001              * make the snref a noop so it gets the proper next/last
4002              * display pointers.
4003              */
4004             newSeg->type = _DtCvSetTypeToNoop(newSeg->type);
4005           }
4006       }
4007
4008     *(my_struct->my_fonts) = saveFonts;
4009     return newSeg;
4010
4011 } /* End ResolveSnref */
4012
4013 /******************************************************************************
4014  * Function:    static CEFontSpecs AllocateFontInfo(my_struct);
4015  *
4016  * Parameters:
4017  *
4018  * Returns:     non-null  if successful, NULL if errors
4019  *
4020  * Purpose:     Allocates a FontInfo structure and intializes it to
4021  *              the current fonts hints.
4022  *
4023  ******************************************************************************/
4024 static  _DtHelpFontHints *
4025 AllocateFontInfo(
4026     FormatStruct *my_struct)
4027 {
4028     _DtHelpFontHints *retFont = NULL;
4029
4030     if (my_struct->free_cnt > 0)
4031         retFont = my_struct->free_fonts[--my_struct->free_cnt];
4032     else
4033       {
4034         /*
4035          * malloc and initialize the starting font information
4036          */
4037         retFont = (_DtHelpFontHints *) malloc (sizeof(_DtHelpFontHints));
4038
4039         if (NULL == retFont)
4040             return NULL;
4041       }
4042
4043     /*
4044      * initialize the font structure
4045      */
4046     if (NULL != my_struct->my_fonts)
4047         *retFont = *(my_struct->my_fonts);
4048     else
4049         *retFont = DefFontInfo;
4050
4051     return retFont;
4052 }
4053
4054 /******************************************************************************
4055  * Function:    static _DtCvSegment **ConvertToList(segs);
4056  *
4057  * Parameters:
4058  *
4059  * Returns:     non-null  if successful, NULL if errors
4060  *
4061  * Purpose:     Allocates a list of null terminated _DtCvSegment pointers.
4062  *
4063  ******************************************************************************/
4064 static  _DtCvSegment **
4065 ConvertToList(_DtCvSegment *segs)
4066 {
4067     _DtCvSegment **ptr  = NULL;
4068
4069     /*
4070      * count the segments
4071      */
4072     while (NULL != segs)
4073       {
4074         _DtCvSegment *next;
4075
4076         ptr = (_DtCvSegment **) _DtCvAddPtrToArray ((void **) ptr,
4077                                                         (void *) segs);
4078         next = _DtCvNextSeg(segs);
4079         _DtCvNextSeg(segs) = NULL;
4080         segs = next;
4081       }
4082
4083     return (ptr);
4084 }
4085
4086 /******************************************************************************
4087  * Function:    static int DestroyFontInfo(my_struct);
4088  *
4089  * Parameters:
4090  *
4091  * Returns:     0 if successful, -1 if errors
4092  *
4093  * Purpose:     Places the font structure in the free list for re-use.
4094  *
4095  ******************************************************************************/
4096 static  void
4097 DestroyFontInfo(
4098     FormatStruct *my_struct)
4099 {
4100     /*
4101      * free the font structures allocated
4102      */
4103     while (0 < my_struct->free_cnt)
4104       {
4105         my_struct->free_cnt--;
4106         free(my_struct->free_fonts[my_struct->free_cnt]);
4107       }
4108
4109     if (NULL != my_struct->free_fonts)
4110         free(my_struct->free_fonts);
4111
4112     my_struct->free_fonts = NULL;
4113
4114     if (NULL != my_struct->my_fonts)
4115         free(my_struct->my_fonts);
4116 }
4117
4118 /******************************************************************************
4119  * Function:    static int FreeFontInfo(my_struct);
4120  *
4121  * Parameters:
4122  *
4123  * Returns:     0 if successful, -1 if errors
4124  *
4125  * Purpose:     Places the font structure in the free list for re-use.
4126  *
4127  ******************************************************************************/
4128 static  int
4129 FreeFontInfo(
4130     FormatStruct *my_struct)
4131 {
4132     if (my_struct->free_cnt >= my_struct->free_max)
4133       {
4134         my_struct->free_max += GROW_SIZE;
4135         if (NULL != my_struct->free_fonts)
4136             my_struct->free_fonts = (_DtHelpFontHints **) realloc (
4137                         my_struct->free_fonts,
4138                         sizeof(_DtHelpFontHints *) * my_struct->free_max);
4139         else
4140             my_struct->free_fonts = (_DtHelpFontHints **) malloc (
4141                         sizeof(_DtHelpFontHints *) * my_struct->free_max);
4142
4143         if (NULL == my_struct->free_fonts)
4144             return -1;
4145       }
4146
4147     my_struct->free_fonts[my_struct->free_cnt++] = my_struct->my_fonts;
4148
4149     return 0;
4150 }
4151
4152 /******************************************************************************
4153  * Function:    static int ResolveAsyncBlock(my_struct, table_seg);
4154  *
4155  * Parameters:
4156  *
4157  * Returns:     0 if successful, -1 if errors
4158  *
4159  * Purpose:     
4160  *
4161  ******************************************************************************/
4162 static  int
4163 ResolveAsyncBlock(
4164     FormatStruct        *my_struct,
4165     _DtCvSegment        *table_seg)
4166 {
4167     char        c;
4168     char       *next;
4169     char       *start  = NULL;
4170     char      **rowIds = _DtCvCellIdsOfTableSeg(table_seg);
4171     _DtCvFrmtOption *colJ;
4172     _DtCvSegment **cellSegs;
4173     _DtCvSegment  *newSeg;
4174     _DtCvSegment  *asyncSegs;
4175     _DtCvValue  found;
4176
4177     while (NULL != rowIds && NULL != *rowIds)
4178       {
4179         /*
4180          * get the start of the row ids
4181          */
4182         next = *rowIds;
4183         colJ = _DtCvColJustifyOfTableSeg(table_seg);
4184         while (NULL != next && '\0' != *next)
4185           {
4186             /*
4187              * skip leading spaces
4188              */
4189             while (' ' == *next) next++;
4190
4191             /*
4192              * set the starting pointer.
4193              */
4194             start = next;
4195
4196             /*
4197              * skip to the next delimitter.
4198              */
4199             while (' ' != *next && '\0' != *next) next++;
4200
4201             /*
4202              * check for the id in the set of segments.
4203              */
4204             if (start != next)
4205               {
4206                 /*
4207                  * save and replace the last character with a null byte.
4208                  */
4209                 c = *next;
4210                 *next = '\0';
4211
4212                 /*
4213                  * get the cells in the table
4214                  */
4215                 cellSegs = _DtCvCellsOfTableSeg(table_seg);
4216
4217                 /*
4218                  * check that one of these cells matches the id
4219                  */
4220                 found   = False;
4221                 if (NULL != cellSegs)
4222                   {
4223                     while (False == found && NULL != *cellSegs)
4224                       {
4225                         if (_DtCvStrCaseCmpLatin1(
4226                                         _DtCvContainerIdOfSeg(*cellSegs),
4227                                                                 start) == 0)
4228                             found = True;
4229                         else
4230                             cellSegs++;
4231                       }
4232                     newSeg = *cellSegs;
4233                   }
4234
4235                 /*
4236                  * the id did not match any of the cells in the table
4237                  * Look in the async list.
4238                  */
4239                 if (False == found)
4240                   {
4241                     asyncSegs = my_struct->async_blks;
4242                     while (False == found && NULL != asyncSegs)
4243                       {
4244                         if (_DtCvStrCaseCmpLatin1(
4245                                         _DtCvContainerIdOfSeg(asyncSegs),
4246                                         start) == 0)
4247                             found = True;
4248                         else
4249                             asyncSegs = _DtCvNextSeg(asyncSegs);
4250                       }
4251
4252                     /*
4253                      * found one in the aysnc blocks
4254                      * Duplicate it.
4255                      */
4256                     if (True == found)
4257                       {
4258                         _DtCvSegment *lastSrc  = NULL;
4259                         _DtCvSegment *lastNext = NULL;
4260
4261                         /*
4262                          * break the link to the next segment
4263                          * or we'll copy this segment and all
4264                          * the next segments.
4265                          */
4266                         _DtCvSegment *nextSeg = _DtCvNextSeg(asyncSegs);
4267                         _DtCvNextSeg(asyncSegs) = NULL;
4268
4269                         /*
4270                          * allocate a new segment for this async block.
4271                          */
4272                         newSeg = DuplicateElement(
4273                                         my_struct->ui_info->client_data,
4274                                         my_struct->toss,
4275                                         asyncSegs, &lastSrc, &lastNext,
4276                                         my_struct->ui_info->load_font,
4277                                         my_struct->ui_info->resolve_spc,
4278                                         my_struct->ui_info->line_height / 2,
4279                                         my_struct->ui_info->avg_char,
4280                                         *(my_struct->my_fonts),
4281                                         -1, False);
4282
4283                         /*
4284                          * restore the async seg linked list
4285                          */
4286                         _DtCvNextSeg(asyncSegs) = nextSeg;
4287
4288                         /*
4289                          * check to see if anything was copied
4290                          */
4291                         if (NULL == newSeg)
4292                             return -1;
4293                         /*
4294                          * now place this segment in the list.
4295                          */
4296                         _DtCvCellsOfTableSeg(table_seg) = (_DtCvSegment **)
4297                                 _DtCvAddPtrToArray(
4298                                 (void **) _DtCvCellsOfTableSeg(table_seg),
4299                                         (void *) newSeg);
4300                       }
4301                   }
4302                /*
4303                 * replace the character.
4304                 */
4305                *next = c;
4306               }
4307
4308             colJ++;
4309           }
4310
4311         /*
4312          * check the next row
4313          */
4314         rowIds++;
4315       }
4316
4317     return 0;
4318 }
4319
4320 /******************************************************************************
4321  * Function:    static int FindSnb(my_struct, id);
4322  *
4323  * Parameters:
4324  *
4325  * Returns:     0 if successful, -1 if errors
4326  *
4327  * Purpose:     
4328  *
4329  ******************************************************************************/
4330 static  _DtCvSegment *
4331 FindSnbEntry(
4332     _DtCvSegment         *snb,
4333     char         *target)
4334 {
4335     char      *id;
4336     _DtCvSegment *retEntry;
4337
4338     if (NULL != snb)
4339       {
4340         retEntry = _DtCvContainerListOfSeg(snb);
4341         while (NULL != retEntry)
4342           {
4343             id = NULL;
4344             if (_DtCvIsSegContainer(retEntry))
4345                 id = _DtCvContainerIdOfSeg(retEntry);
4346
4347             if (NULL != id && _DtCvStrCaseCmpLatin1(target, id) == 0)
4348                 return retEntry;
4349
4350             retEntry = _DtCvNextSeg(retEntry);
4351           }
4352       }
4353
4354     return NULL;
4355 }
4356
4357 /******************************************************************************
4358  * Function:    static int ProcessString(string, int idx);
4359  *
4360  * Parameters:
4361  *
4362  * Returns:     0 if successful, -1 if errors
4363  *
4364  * Purpose:     
4365  *
4366  ******************************************************************************/
4367 static  int
4368 ProcessString(
4369     FormatStruct         *my_struct,
4370     _DtCvValue            last_flag,
4371     _DtCvValue            nl_flag,
4372     _DtCvValue            mod_str,
4373     _DtCvValue            cpy_str,
4374     _DtCvValue            process_flag,
4375     char                 *string,
4376     int                   byte_len,
4377     int                  *idx)
4378 {
4379     if (mod_str == True)
4380         string[*idx] = '\0';
4381
4382     if (process_flag == True && MySaveString(&(my_struct->seg_list),
4383                                     my_struct, string, my_struct->cur_link,
4384                                     byte_len, nl_flag) != 0)
4385       {
4386         MyFree(string);
4387         return -1;
4388       }
4389
4390     my_struct->last_was_space = last_flag;
4391
4392     if (cpy_str == True)
4393       {
4394         strcpy (string, &string[*idx+1]);
4395         *idx = -1;
4396       }
4397     return 0;
4398 }
4399
4400 /******************************************************************************
4401  * Function:    static void CompressLinkSeg(seg);
4402  *
4403  * Parameters:
4404  *
4405  * Returns:     nothing
4406  *
4407  * Purpose:     Check to see if there is a blank at the beginning of the
4408  *              segment and if it is needed.
4409  *
4410  ******************************************************************************/
4411 static  void
4412 CompressLinkSeg(
4413     _DtCvSegment *p_seg)
4414 {
4415     void    *pChar;
4416     wchar_t  fChar;
4417     int      wcFlag;
4418
4419     /*
4420      * check to see if the first segment is a string.
4421      */
4422     while (NULL != p_seg && _DtCvIsSegNoop(p_seg))
4423         p_seg = _DtCvNextSeg(p_seg);
4424
4425     if (NULL == p_seg)
4426         return;
4427
4428     if (_DtCvIsSegString(p_seg))
4429       {
4430         wcFlag = _DtCvIsSegWideChar(p_seg);
4431         pChar  = _DtCvStrPtr(_DtCvStringOfStringSeg(p_seg), wcFlag, 0);
4432
4433         /*
4434          * is this the only segment in the link?
4435          * Is it only one character in size?
4436          */
4437         if (NULL == _DtCvNextDisp(p_seg) && 1 <= _DtCvStrLen(pChar, wcFlag))
4438             return;
4439
4440         /*
4441          * is it a blank? (wide char and single char codes are equal
4442          * for blanks - ISO standard)
4443          */
4444         if ((_DtCvIsSegWideChar(p_seg) && ' ' == *((wchar_t *) pChar)) ||
4445                 (_DtCvIsSegRegChar(p_seg) && ' ' == *((char *) pChar)))
4446           {
4447             /*
4448              * compress out the blank
4449              *
4450              * is this a single byte string? If so, use strcpy to move
4451              * the string.
4452              */
4453             if (_DtCvIsSegRegChar(p_seg))
4454                 strcpy(((char *)pChar), &(((char *)pChar)[1]));
4455             else
4456               {
4457                 int i;
4458                 wchar_t *wcChar = (wchar_t *) pChar;
4459
4460                 while (0 != wcChar[0])
4461                   {
4462                     wcChar[0] = wcChar[1];
4463                     wcChar++;
4464                   }
4465               }
4466           }
4467       }
4468 }
4469
4470 /******************************************************************************
4471  * Function:    static int ProcessNonBreakChar(string, int idx);
4472  *
4473  * Parameters:
4474  *
4475  * Returns:     0 if successful, -1 if errors
4476  *
4477  * Purpose:
4478  *
4479  ******************************************************************************/
4480 static  int
4481 ProcessNonBreakChar(
4482     FormatStruct        *my_struct,
4483     _DtCvValue           process_flag,
4484     char                *break_str,
4485     char                *string,
4486     int                  byte_len,
4487     int                 *idx)
4488 {
4489     if (ProcessString(my_struct, False, False, True, False,
4490                                 process_flag, string, byte_len, idx) != 0)
4491         return -1;
4492
4493     my_struct->flags = _DtCvSetTypeToNonBreak(my_struct->flags);
4494     if (ProcessString(my_struct, False, False, False, False,
4495                                 process_flag, break_str, byte_len, idx) != 0)
4496         return -1;
4497
4498     my_struct->flags = my_struct->flags & ~(_DtCvNON_BREAK);
4499     strcpy (string, &string[*idx+1]);
4500     *idx = -1;
4501     return 0;
4502 }
4503
4504 /******************************************************************************
4505  * Function:    static int MoveString(string, int idx);
4506  *
4507  * Parameters:
4508  *
4509  * Returns:     0 if successful, -1 if errors
4510  *
4511  * Purpose:     
4512  *
4513  ******************************************************************************/
4514 static  int
4515 MoveString(
4516     char        **string,
4517     int          *max_len,
4518     int          *idx)
4519 {
4520     int    i     = *idx;
4521     int    myLen = *max_len;
4522     char  *src   = *string;
4523
4524     i--;
4525     if (i == -1)
4526       {
4527         if (strlen(src) == myLen)
4528           {
4529             src = (char *) realloc (src, myLen + 2);
4530             if (src == NULL)
4531                 return -1;
4532
4533             myLen++;
4534             *string  = src;
4535             *max_len = myLen;
4536           }
4537         for (i = myLen; i > 0; i--)
4538             src[i] = src[i-1];
4539       }
4540
4541     *idx = i;
4542     return 0;
4543 }
4544
4545 /******************************************************************************
4546  * Function:    int SetUp (_DtHelpVolumeHdl volume,
4547  *                              CESDLVolume **sdl_vol,
4548  *                              FormatStruct *frmt_struct,
4549  *                              _DtCvSegment *toss,
4550  *                              _DtCvSegment *cur_frmt,
4551  *                              _DtCvValue lang
4552  *
4553  * Parameters:
4554  *              volume          Specifies the volume handle. If non-NULL,
4555  *                              create and return the sdl volume pointer
4556  *                              in 'sdl_vol'.
4557  *              sdl_vol         If not NULL, returns the sdl volume pointer.
4558  *              frmt_struct     Specifies the formatting structure to use.
4559  *              toss            Specifies the toss to use. If NULL and
4560  *                              sdl_vol asked for and flag == True, the
4561  *                              sdl_vol->toss will be used.
4562  *              lang            Specifies if the language/charset should
4563  *                              be set using information from the volume.
4564  *              flag            Specifies if to get/use the sdl_vol->toss
4565  *                              if toss is NULL.
4566  *
4567  * Returns:     0 if no failures, -1 if errors.
4568  *
4569  * Purpose:     Set up the formatting structure to use.
4570  *
4571  *****************************************************************************/
4572 static  int
4573 SetUp (
4574     _DtHelpVolumeHdl      volume,
4575     CESDLVolume         **sdl_vol,
4576     FormatStruct         *frmt_struct,
4577     _DtCvSegment                 *toss,
4578     const _FrmtUiInfo    *ui_info,
4579     int                   fd,
4580     _DtCvValue            lang,
4581     _DtCvValue            flag)
4582 {
4583     *frmt_struct = DefFormatStruct;
4584
4585     frmt_struct->my_links = _DtLinkDbCreate();
4586     if (NULL == frmt_struct->my_links)
4587         return -1;
4588
4589     if (volume != NULL && sdl_vol != NULL)
4590       {
4591         *sdl_vol = _DtHelpCeGetSdlVolumePtr(volume);
4592         if (*sdl_vol == NULL)
4593           {
4594             _DtLinkDbDestroy(frmt_struct->my_links);
4595             return -1;
4596           }
4597       }
4598
4599     /*
4600      * malloc and initialize the starting font information
4601      */
4602     frmt_struct->my_fonts = AllocateFontInfo(frmt_struct);
4603     if (NULL == frmt_struct->my_fonts)
4604       {
4605         _DtLinkDbDestroy(frmt_struct->my_links);
4606         return -1;
4607       }
4608
4609     if (volume != NULL)
4610       {
4611         frmt_struct->vol_name = _DtHelpCeGetVolumeName(volume);
4612
4613         if (toss == NULL && flag == True)
4614             toss = _DtHelpCeGetSdlVolToss(volume, fd);
4615
4616         if (lang == True)
4617           {
4618             _DtHelpFontHintsLang(*(frmt_struct->my_fonts)) =
4619                                 _DtHelpCeGetSdlVolLanguage(volume);
4620             _DtHelpFontHintsCharSet(*(frmt_struct->my_fonts)) =
4621                                 (char *) _DtHelpCeGetSdlVolCharSet(volume);
4622           }
4623       }
4624
4625     /*
4626      * determine mb_len should be based on lang/charset.
4627      */
4628     frmt_struct->mb_len   = _DtHelpCeGetMbLen(
4629                         _DtHelpFontHintsLang(*(frmt_struct->my_fonts)),
4630                         _DtHelpFontHintsCharSet(*(frmt_struct->my_fonts)));
4631     frmt_struct->toss     = toss;
4632     frmt_struct->ui_info  = ui_info;
4633
4634     return 0;
4635 }
4636
4637 /******************************************************************************
4638  * Function:    void AddToAsyncList (_DtCvSegment *seg_list)
4639  *
4640  * Parameters:
4641  *
4642  * Returns      Nothing
4643  *
4644  * Purpose:     Add a segment block to the async list.
4645  *
4646  *****************************************************************************/
4647 static  void
4648 AddToAsyncList (
4649     FormatStruct        *my_struct,
4650     _DtCvSegment        *block_seg)
4651 {
4652
4653     if (my_struct->async_blks != NULL)
4654       {
4655         _DtCvSegment  *pSeg = my_struct->async_blks;
4656
4657         while (_DtCvNextSeg(pSeg) != NULL)
4658             pSeg = _DtCvNextSeg(pSeg);
4659         
4660         _DtCvNextSeg(pSeg) = block_seg;
4661       }
4662     else
4663         my_struct->async_blks = block_seg;
4664
4665 }
4666
4667 /******************************************************************************
4668  * Function:    int CheckOptionList (int attr_value_type, const char *attr,
4669  *                                      _DtCvValue check_flag,
4670  *                                      SdlOption cur_num,
4671  *                                      SdlOption *num);
4672  *
4673  * Parameters:
4674  *
4675  * Returns:     0 if successful, -1 if errors
4676  *
4677  * Purpose:     If found, returns the enum value.
4678  *
4679  ******************************************************************************/
4680 static  int
4681 CheckOptionList(
4682     int          attr_value_type,
4683     const char  *attr,
4684     _DtCvValue   check,
4685     SdlOption    cur_num,
4686     SdlOption   *num)
4687 {
4688     int    i = 0;
4689     int    lowerChar;
4690     int    result = -1;
4691     const OptionList *option;
4692     _DtCvValue  found  = False;
4693     _DtCvValue  cmpFnd = False;
4694
4695     while (SDLOptionsList[i].attr_value != -1 &&
4696                         SDLOptionsList[i].attr_value != attr_value_type)
4697         i++;
4698
4699     if (SDLOptionsList[i].attr_value != -1)
4700       {
4701         option    = SDLOptionsList[i].options;
4702         lowerChar = _DtHelpCeToLower(*attr);
4703
4704         while (option != NULL && option->string != NULL &&
4705                                         (check == True || cmpFnd == False))
4706           {
4707             /*
4708              * check to see if the current option is in the list
4709              * of valid options for this attribute.
4710              */
4711             if (check && cur_num == option->option_value)
4712               {
4713                 /*
4714                  * okay, it's been found, don't check anymore.
4715                  */
4716                 found = True;
4717                 check = False;
4718               }
4719
4720             /*
4721              * otherwise, find out if this value is a valid option
4722              * for the attribute.
4723              */
4724             else if (cmpFnd == False &&
4725                         lowerChar == _DtHelpCeToLower(*(option->string)) &&
4726                         _DtCvStrCaseCmpLatin1(option->string, attr) == 0)
4727               {
4728                 cmpFnd = True;
4729                 *num   = option->option_value;
4730               }
4731             option++;
4732           }
4733       }
4734
4735     /*
4736      * if found is true, means check was originally set to true and
4737      * we found the current value in the option list for this attribute.
4738      */
4739     if (found == True)
4740         *num = cur_num;
4741
4742     /*
4743      * if we found that the current value was valid or that the string
4744      * was a valid option in the list for the attribute, return no error.
4745      */
4746     if (found == True || cmpFnd == True)
4747         result = 0;
4748
4749     return result;
4750 }
4751
4752 /******************************************************************************
4753  * Function:    int CheckFontList (int attr_value_type, char *attr,
4754  *                                      enum CEFontSpec *num);
4755  *
4756  * Parameters:
4757  *
4758  * Returns:     0 if successful, -1 if errors
4759  *
4760  * Purpose:     If found, returns the enum value.
4761  *
4762  ******************************************************************************/
4763 static  int
4764 CheckFontList(
4765     int                  attr_value_type,
4766     char                *attr,
4767     _DtHelpFontValue    *num)
4768 {
4769     int    i = 0;
4770     const FontSpecOption *option;
4771
4772     while (SDLFontList[i].attr_value != -1 &&
4773                         SDLFontList[i].attr_value != attr_value_type)
4774         i++;
4775
4776     if (SDLFontList[i].attr_value != -1)
4777       {
4778         option = SDLFontList[i].options;
4779
4780         while (option != NULL && option->string != NULL)
4781           {
4782             if (_DtCvStrCaseCmpLatin1(option->string, attr) == 0)
4783               {
4784                 *num = option->option_value;
4785                 return 0;
4786               }
4787             option++;
4788           }
4789       }
4790     return -1;
4791 }
4792
4793 /******************************************************************************
4794  * Function:    int LookAhead (FormatStruct my_struct, int token_value,
4795  *                              int remove_flag);
4796  *
4797  * Parameters:
4798  *              my_struct       Specifies the parsing structure.
4799  *              token_value     Specifies the token to match
4800  *              remove_flag     Specifies whether to clear the look ahead
4801  *                              value. If True, will set the look ahead
4802  *                              parsed value to invalid iff token_value
4803  *                              equals the parsed look ahead value.
4804  *
4805  * Returns:      0 if token_value matched parsed value,
4806  *               1 if parsed value is invalid.
4807  *              -1 if parsed value is valid but token_value did not match.
4808  *
4809  * Purpose:
4810  *
4811  ******************************************************************************/
4812 static  int
4813 TestLookAhead(
4814     FormatStruct        *my_struct,
4815     enum SdlElement      token_value,
4816     _DtCvValue           end_flag,
4817     int                  remove_flag)
4818 {
4819     if (my_struct->parsed == SdlElementNone)
4820         return 1;
4821
4822     if (my_struct->parsed == token_value && my_struct->end_flag == end_flag)
4823       {
4824         if (remove_flag == True)
4825           {
4826             my_struct->parsed = SdlElementNone;
4827             if (my_struct->remember != NULL)
4828               {
4829                 free (my_struct->remember);
4830                 my_struct->remember = NULL;
4831               }
4832           }
4833         return 0;
4834       }
4835
4836     return -1;
4837 }
4838
4839 /******************************************************************************
4840  * Function:    int MatchSDLElement (FormatStruct my_struct, sdl_string,
4841  *                                      int sdl_element, sig_chars)
4842  *
4843  * Parameters:
4844  *
4845  * Returns:     0 if successful, -1 if errors
4846  *
4847  * Purpose:     Looks for the specific element.
4848  *
4849  ******************************************************************************/
4850 static  int
4851 MatchSDLElement(
4852     FormatStruct        *my_struct,
4853     const char          *sdl_string,
4854     enum SdlElement      sdl_element,
4855     int                  sig_chars,
4856     _DtCvValue           end_flag)
4857 {
4858     int    i;
4859
4860     i = TestLookAhead(my_struct, sdl_element, end_flag, True);
4861
4862     if ( i != 1)
4863         return i;
4864
4865     return (_DtHelpCeMatchSdlElement(my_struct->my_file,sdl_string,sig_chars));
4866 }
4867
4868 /******************************************************************************
4869  * Function:    void SetAttributeFlag (
4870  *
4871  ******************************************************************************/
4872 static  void
4873 SetAttributeFlag(
4874     ElementInfoPtr      cur_info,
4875     unsigned long       attr_define)
4876 {
4877     unsigned long  flag = attr_define & ~(VALUE_MASK);
4878
4879     switch (attr_define & VALUE_MASK)
4880       {
4881         case ENUM_VALUE:
4882                 cur_info->enum_values |= flag;
4883                 break;
4884         case STRING1_VALUE:
4885                 cur_info->str1_values |= flag;
4886                 break;
4887         case STRING2_VALUE:
4888                 cur_info->str2_values |= flag;
4889                 break;
4890         case NUMBER_VALUE:
4891                 cur_info->num_values |= flag;
4892                 break;
4893
4894       }
4895 }
4896
4897 /******************************************************************************
4898  * Function:    void InitAttributes(SDLAttrStruct *as,
4899  *                                              SDLElementAttrList *attr_list)
4900  *
4901  * Parameters:
4902  *
4903  * Returns:     Attribute Processed if successful, -1 if errors
4904  *
4905  * Purpose:     Looks for the virtual page beginning.
4906  *
4907  ******************************************************************************/
4908 static  void
4909 InitAttributes(
4910     _DtCvSegment        *p_seg,
4911     _DtHelpFontHints    *font_specs,
4912     ElementInfo         *element_info,
4913     const SDLElementAttrList    *attr_list)
4914 {
4915    char         **strPtr1;
4916    char          *varOffset1;
4917    SDLNumber     *numPtr1;
4918    SdlOption     *enumPtr1;
4919    SdlOption      defNum = _DtCvOPTION_BAD;
4920    const SDLAttribute *pAttr;
4921
4922    while (attr_list->sdl_attr_define != -1)
4923      {
4924         if (attr_list->def_string != NULL ||
4925                                 attr_list->sdl_value == SdlAttrValueImpliedDef)
4926           {
4927             pAttr = SDLAttributeList;
4928             while (pAttr->data_type != SdlAttrDataTypeInvalid &&
4929                     !(ATTRS_EQUAL(pAttr->data_type,
4930                         pAttr->sdl_attr_define, attr_list->sdl_attr_define)))
4931                 pAttr++;
4932
4933             if (pAttr->struct_type != SdlIgnore &&
4934                 pAttr->data_type != SdlAttrDataTypeInvalid &&
4935                 SDLIsAttrSet(*element_info, pAttr->sdl_attr_define) == False)
4936               {
4937                 /*
4938                  * determine which structure the information goes in
4939                  */
4940                 if (pAttr->struct_type == SdlFontSpecific)
4941                     varOffset1 = ((char *) font_specs);
4942                 else if (pAttr->struct_type == SdlContainerSpecific)
4943                     varOffset1 = ((char *)_SdlContainerPtrOfSeg(p_seg));
4944                 else if (pAttr->struct_type == SdlElementSpecific)
4945                     varOffset1 = ((char *) element_info);
4946                 else if (pAttr->struct_type == SdlTableSpecific)
4947                     varOffset1 = ((char *) element_info->w.table_info);
4948
4949                 varOffset1 = varOffset1 + pAttr->field_ptr;
4950                 if (pAttr->data_type == SdlAttrDataTypeNumber)
4951                   {
4952                     numPtr1  = (SDLNumber *) varOffset1;
4953                     *numPtr1 = ((SDLNumber)atoi(attr_list->def_string));
4954                   }
4955                 else if (pAttr->data_type == SdlAttrDataTypeEnum)
4956                   {
4957                     enumPtr1  = (SdlOption *) varOffset1;
4958                     (void) CheckOptionList (attr_list->sdl_attr_define,
4959                                         attr_list->def_string,
4960                 ((attr_list->sdl_attr_define & SDL_ATTR_CLASS) ? True : False),
4961                                         ElInfoClan(element_info),
4962                                         &defNum);
4963                     if ((attr_list->sdl_attr_define & SDL_ATTR_CLASS & ~(VALUE_MASK))
4964                                         && ElInfoClan(element_info) != defNum)
4965                         SetAttributeFlag(element_info,
4966                                                 attr_list->sdl_attr_define);
4967                     *enumPtr1 = defNum;
4968                   }
4969                 else if (SDLIsString1(pAttr->sdl_attr_define)
4970                                         ||
4971                          SDLIsString2(pAttr->sdl_attr_define))
4972                   {
4973                     strPtr1  = (char **) varOffset1;
4974                     *strPtr1 = (char *) attr_list->def_string;
4975                   }
4976               }
4977           }
4978        attr_list++;
4979      }
4980 }
4981
4982 #ifdef  DEBUG
4983 static char *
4984 ElToName(enum SdlElement el)
4985 {
4986     switch (el)
4987       {
4988         case SdlElementNone: return ("None");
4989         case SdlElementComment: return ("Comment");
4990         case SdlElementSdlDoc: return ("SdlDoc");
4991         case SdlElementVStruct: return ("VStruct");
4992         case SdlElementVirpage: return ("Virpage");
4993         case SdlElementHead: return ("Head");
4994         case SdlElementSubHead: return ("SubHead");
4995         case SdlElementSnb: return ("Snb");
4996         case SdlElementBlock: return ("Block");
4997         case SdlElementForm: return ("Form");
4998         case SdlElementPara: return ("Para");
4999         case SdlElementCPara: return ("CPara");
5000         case SdlElementFdata: return ("Fdata");
5001         case SdlElementFstyle: return ("Fstyle");
5002         case SdlElementFrowvec: return ("Frowvec");
5003         case SdlElementKey: return ("Key");
5004         case SdlElementCdata: return ("Cdata");
5005         case SdlElementGraphic: return ("Graphic");
5006         case SdlElementText: return ("Text");
5007         case SdlElementAudio: return ("Audio");
5008         case SdlElementVideo: return ("Video");
5009         case SdlElementAnimate: return ("Animate");
5010         case SdlElementCrossDoc: return ("CrossDoc");
5011         case SdlElementManPage: return ("ManPage");
5012         case SdlElementTextFile: return ("TextFile");
5013         case SdlElementSysCmd: return ("SysCmd");
5014         case SdlElementCallback: return ("Callback");
5015         case SdlElementScript: return ("Script");
5016         case SdlElementAnchor: return ("Anchor");
5017         case SdlElementLink: return ("Link");
5018         case SdlElementSwitch: return ("Switch");
5019         case SdlElementSnRef: return ("SnRef");
5020         case SdlElementRefItem: return ("RefItem");
5021         case SdlElementAltText: return ("AltText");
5022         case SdlElementSphrase: return ("Sphrase");
5023         case SdlElementRev: return ("Rev");
5024         case SdlElementSpc: return ("Spc");
5025         case SdlElementIf: return ("If");
5026         case SdlElementCond: return ("Cond");
5027         case SdlElementThen: return ("Then");
5028         case SdlElementElse: return ("Else");
5029         case SdlElementDocument: return ("Document");
5030         case SdlElementSgml: return ("Sgml");
5031         case SdlElementDocType: return ("DocType");
5032         case SdlElementLoids: return ("Loids");
5033         case SdlElementToss: return ("Toss");
5034         case SdlElementLoPhrases: return ("LoPhrases");
5035         case SdlElementPhrase: return ("Phrase");
5036         case SdlElementIndex: return ("Index");
5037         case SdlElementEntry: return ("Entry");
5038         case SdlElementRelDocs: return ("RelDocs");
5039         case SdlElementRelFile: return ("RelFile");
5040         case SdlElementNotes: return ("Notes");
5041         case SdlElementKeyStyle: return ("KeyStyle");
5042         case SdlElementHeadStyle: return ("HeadStyle");
5043         case SdlElementFormStyle: return ("FormStyle");
5044         case SdlElementFrmtStyle: return ("FrmtStyle");
5045         case SdlElementGrphStyle: return ("GrphStyle");
5046         case SdlElementId: return ("Id");
5047         case SdlElementBlockAsync: return ("BlockAsync");
5048         case SdlElementTitle: return ("Title");
5049         case SdlPcDataFollows: return ("Follows");
5050       }
5051     return ("Unknown");
5052 }
5053 #endif /* DEBUG */
5054
5055 /******************************************************************************
5056  * Function:    int ProcessSDLAttribute(FormatStruct my_struct,
5057  *                                              SDLAttrStruct *cur_attr,
5058  *                                              SDLElementAttrList *attr_list,
5059  *                                              char     *attr_name,
5060  *
5061  * Parameters:
5062  *
5063  * Returns:     0 if successful, -1 if errors
5064  *
5065  * Purpose:     Looks for the virtual page beginning.
5066  *
5067  ******************************************************************************/
5068 static  int
5069 ProcessSDLAttribute(
5070     FormatStruct        *my_struct,
5071     _DtCvSegment                *p_seg,
5072     _DtHelpFontHints    *font_specs,
5073     ElementInfo         *element_info,
5074     const SDLElementAttrList    *attr_list,
5075     char                *attr_name)
5076 {
5077     int          result;
5078     char        *attrValue;
5079     char        **strPtr;
5080     char         numBuf[DTD_NAMELEN+1];
5081     char        *varOffset1;
5082     SDLNumber   *numPtr1;
5083     SdlOption   *enumPtr1;
5084     SdlOption    attrNum;
5085     _DtHelpFontValue     fontNum;
5086     _DtHelpFontValue    *fontPtr1;
5087     const SDLAttribute *pAttr = SDLAttributeList;
5088
5089     /*
5090      * find the attribute in the list of SDL attributes
5091      * assumes that 'attr_name' has been lower cased, since all the
5092      * attribute names in SDLAttributeList are already lower case.
5093      */
5094     while (pAttr->data_type != SdlAttrDataTypeInvalid &&
5095               (*(pAttr->name) != *attr_name || strcmp(pAttr->name, attr_name)))
5096         pAttr++;
5097
5098     if (pAttr->data_type != SdlAttrDataTypeInvalid)
5099       {
5100
5101         /*
5102          * Check to see if this element contains an attribute with
5103          * the found value.
5104          */
5105         while (attr_list->sdl_attr_define != -1 &&
5106                         !ATTRS_EQUAL(pAttr->data_type, pAttr->sdl_attr_define,
5107                                                 attr_list->sdl_attr_define))
5108             attr_list++;
5109
5110         if (attr_list->sdl_attr_define == -1)
5111             return -1;
5112       }
5113
5114     /*
5115      * check it against the ones that are allowed for this element
5116      */
5117     if (pAttr->data_type != SdlAttrDataTypeInvalid)
5118       {
5119         switch (pAttr->data_type)
5120           {
5121             case SdlAttrDataTypeId:
5122                     result = _DtHelpCeGetSdlId(my_struct->my_file, &attrValue);
5123                     break;
5124
5125             case SdlAttrDataTypeNumber:
5126                     result = _DtHelpCeGetSdlNumber(my_struct->my_file, numBuf);
5127                     break;
5128
5129             case SdlAttrDataTypeCdata:
5130                     result = _DtHelpCeGetSdlAttributeCdata(my_struct->my_file,
5131                                                     False, &attrValue);
5132                     break;
5133
5134             case SdlAttrDataTypeFont:
5135                     result = _DtHelpCeGetSdlAttributeCdata(my_struct->my_file,
5136                                                     False, &attrValue);
5137                     if (result != -1)
5138                         result = CheckFontList (attr_list->sdl_attr_define,
5139                                                      attrValue, &fontNum);
5140                     break;
5141
5142             case SdlAttrDataTypeEnum:
5143                     result = _DtHelpCeGetSdlAttributeCdata(my_struct->my_file,
5144                                                     False, &attrValue);
5145                     if (result != -1)
5146                         result = CheckOptionList (attr_list->sdl_attr_define,
5147                                                     attrValue, False,
5148                                                     (SdlOption) _DtCvOPTION_BAD,
5149                                                     &attrNum);
5150                     break;
5151
5152             default:
5153                     printf ("hit unknown in processing attribute\n");
5154                     result = -1;
5155                     break;
5156           }
5157
5158         if (result == 0)
5159           {
5160             if (pAttr->struct_type != SdlIgnore)
5161               {
5162                 /*
5163                  * determine which structure the information goes in
5164                  */
5165                 if (pAttr->struct_type == SdlFontSpecific)
5166                     varOffset1 = ((char *) font_specs);
5167                 else if (pAttr->struct_type == SdlContainerSpecific)
5168                     varOffset1 = ((char *)_SdlContainerPtrOfSeg(p_seg));
5169                 else if (pAttr->struct_type == SdlElementSpecific)
5170                     varOffset1 = ((char *) element_info);
5171                 else if (pAttr->struct_type == SdlTableSpecific)
5172                     varOffset1 = ((char *) element_info->w.table_info);
5173
5174                 varOffset1 = varOffset1 + pAttr->field_ptr;
5175                 if (pAttr->data_type == SdlAttrDataTypeNumber)
5176                   {
5177                     numPtr1  = (SDLNumber *) varOffset1;
5178                     *numPtr1 = ((SDLNumber) atoi(numBuf));
5179                   }
5180                 else if (pAttr->data_type == SdlAttrDataTypeEnum)
5181                   {
5182                     enumPtr1  = (SdlOption *) varOffset1;
5183                     *enumPtr1 = attrNum;
5184     
5185                     free(attrValue);
5186                   }
5187                 else if (pAttr->data_type == SdlAttrDataTypeFont)
5188                   {
5189                     fontPtr1  = (_DtHelpFontValue *) varOffset1;
5190                     *fontPtr1 = fontNum;
5191     
5192                     free(attrValue);
5193                   }
5194                 else
5195                   {
5196                     strPtr = (char **) varOffset1;
5197                     *strPtr = attrValue;
5198                   }
5199               }
5200             else if (SdlAttrDataTypeNumber != pAttr->data_type)
5201                 free(attrValue);
5202             SetAttributeFlag(element_info, pAttr->sdl_attr_define);
5203           }
5204         return result;
5205       }
5206
5207     return -1;
5208 }
5209
5210 /******************************************************************************
5211  * Function:    int VerifyAttrList (
5212  *                                              SDLElementAttrList *attr_list)
5213  *
5214  * Parameters:
5215  *
5216  * Returns:     Attribute Processed if successful, -1 if errors
5217  *
5218  * Purpose:     Looks for the virtual page beginning.
5219  *
5220  ******************************************************************************/
5221 static  int
5222 VerifyAttrList(
5223     ElementInfoPtr               el_info,
5224     const SDLElementAttrList    *attr_list)
5225 {
5226     long  value;
5227     while (attr_list->sdl_attr_define != -1)
5228       {
5229         if (attr_list->sdl_value == SdlAttrValueRequired)
5230           {
5231             switch (attr_list->sdl_attr_define & VALUE_MASK)
5232               {
5233                 case ENUM_VALUE:
5234                                 /*
5235                                  * mask off the minor number
5236                                  */
5237                                 value = el_info->enum_values & ~(MINOR_MASK);
5238                                 break;
5239                 case STRING1_VALUE:
5240                                 value = el_info->str1_values;
5241                                 break;
5242                 case STRING2_VALUE:
5243                                 value = el_info->str2_values;
5244                                 break;
5245                 case NUMBER_VALUE:
5246                                 value = el_info->num_values;
5247                                 break;
5248               }
5249             if (!(attr_list->sdl_attr_define & value))
5250                 return -1;
5251           }
5252         attr_list++;
5253       }
5254
5255     return 0;
5256 }
5257
5258 /******************************************************************************
5259  * Function:    void MergeTossInfo (
5260  *                              _DtCvSegment *cur_element,
5261  *                              FormatStruct my_struct);
5262  *
5263  * Parameters:
5264  *
5265  * Returns:     nothing
5266  *
5267  * Purpose:     Looks for the virtual page beginning.
5268  *
5269  ******************************************************************************/
5270 static  void
5271 MergeTossInfo(
5272     FormatStruct        *my_struct,
5273     _DtCvSegment                *cur_contain,
5274     _DtHelpFontHints    *font_specs)
5275 {
5276     _DtCvSegment *tossSeg;
5277
5278     if (my_struct->toss == NULL)
5279         return;
5280
5281     tossSeg = _DtHelpCeMatchSemanticStyle (my_struct->toss,
5282                                 ElClan(my_struct),
5283                                 ElLevel(my_struct),
5284                                 ElSsi(my_struct));
5285     _DtHelpCeMergeSdlAttribInfo(tossSeg, cur_contain, font_specs,
5286                                 &(my_struct->el_info),
5287                                 &(my_struct->el_info.str1_values),
5288                                 &(my_struct->el_info.str2_values));
5289
5290     return;
5291 }
5292
5293 \f
5294 /*------------------------- Element Processing ------------------------------*/
5295 /******************************************************************************
5296  * Function:    int ParseElementStart (
5297  *                              FormatStruct my_struct,
5298  *                              int element, _DtCvValue process_flag);
5299  *
5300  * Parameters:
5301  *
5302  * Returns:     0 if successful, -1 if errors
5303  *
5304  * Purpose:     Looks for the virtual page beginning.
5305  *
5306  ******************************************************************************/
5307 static  int
5308 ParseElementStart(
5309     FormatStruct        *my_struct,
5310     SDLElementInfo       element,
5311     _DtCvValue           process_flag)
5312 {
5313     _DtCvSegment  *segPtr;
5314     _DtCvSegment  *newSeg;
5315     FrmtPrivateInfo *priv;
5316
5317     if (MatchSDLElement (my_struct, element.element_str, element.sdl_element,
5318                                         element.str_sig_chars, False) != 0)
5319         return -1;
5320         
5321     /*
5322      * remember what we are currently parsing
5323      */
5324     ElType(my_struct) = element.sdl_element;
5325
5326     /*
5327      * does this element possibly pull in different fonts?
5328      * if so, allocate a new font structure.
5329      */
5330     if (True == process_flag && element.new_fonts)
5331       {
5332         my_struct->my_fonts = AllocateFontInfo(my_struct);
5333         if (NULL == my_struct->my_fonts)
5334             return -1;
5335       }
5336
5337     /*
5338      * if Cdata or skipping information don't do anything else
5339      */
5340     if (element.sdl_to_gen == SdlToNone || process_flag == False)
5341         return 0;
5342
5343     /*
5344      * allocate a segment for this element
5345      */
5346     if (_DtHelpCeAllocSegment(my_struct->malloc_size,
5347                                 &(my_struct->alloc_size),
5348                                 &(my_struct->block_list), &segPtr) != 0)
5349         return -1;
5350
5351     /*
5352      * add this segment to the list when done
5353      */
5354     my_struct->add_seg = segPtr;
5355
5356     /*
5357      * Set the flags and initialize variables depending on the
5358      * type of general segment this element becomes.
5359      */
5360     switch (element.sdl_to_gen)
5361       {
5362         case SdlToContainer:
5363                 /*
5364                  * set the container flag and initialize its formatting
5365                  * information to the default.
5366                  */
5367                 segPtr->type = _DtCvSetTypeToContainer(segPtr->type);
5368                 _DtCvContainerOfSeg(segPtr) = DefFrmtSpecs;
5369                 _DtCvContainerLeadingOfSeg(segPtr) =
5370                                                 my_struct->ui_info->leading;
5371         
5372                 /*
5373                  * if this is a formatting type container, do some more work.
5374                  */
5375                 if (element.formatting)
5376                   {
5377                     const _DtCvContainer *active = my_struct->active_frmt;
5378
5379                     if (NULL == active) active = &DefFrmtSpecs;
5380
5381                     /*
5382                      * The margin information - it gets zero'ed
5383                      */
5384                     _DtCvContainerLMarginOfSeg(segPtr) = 0;
5385                     _DtCvContainerRMarginOfSeg(segPtr) = 0;
5386                     _DtCvContainerFMarginOfSeg(segPtr) = 0;
5387                     _DtCvContainerTMarginOfSeg(segPtr) = 0;
5388                     _DtCvContainerBMarginOfSeg(segPtr) = 0;
5389
5390                     /*
5391                      * inherit some of the formatting directives
5392                      */
5393                     _DtCvContainerVJustifyOfSeg(segPtr) =
5394                                         ContainerPtrToVJustify(active);
5395                     _DtCvContainerJustifyOfSeg(segPtr) =
5396                                         ContainerPtrToJustify(active);
5397                     /*
5398                      * break the connection with the previous data.
5399                      */
5400                     my_struct->prev_data = NULL;
5401                     _DtCvContainerListOfSeg(segPtr) = NULL;
5402         
5403                     /*
5404                      * check to see if these are controllers.
5405                      */
5406                     if (element.sdl_element == SdlElementHead ||
5407                                 SdlElementSubHead == element.sdl_element)
5408                         segPtr->type = _DtCvSetTypeToController(segPtr->type);
5409                     
5410                     /*
5411                      * make this the currently active formatting information
5412                      */
5413                     my_struct->active_frmt = &(_DtCvContainerOfSeg(segPtr));
5414                   }
5415                 break;
5416
5417         case SdlToMarker:
5418                 /*
5419                  * set the type; the attribute processing will set the id.
5420                  */
5421                 segPtr->type = _DtCvSetTypeToMarker(segPtr->type);
5422                 break;
5423
5424         case SdlToSnb:
5425                 /*
5426                  * set the type; the attribute processing will set the id.
5427                  * graphics only exist in a snb. You have to keep the
5428                  * id around until the graphic get resolved. So a graphic
5429                  * is a container with a region.
5430                  */
5431                 segPtr->type = _DtCvSetTypeToContainer(segPtr->type);
5432
5433                 /*
5434                  * remember the refitem type.
5435                  */
5436                 priv = FrmtPrivInfoPtr(segPtr);
5437                 priv->sdl_el_type = ElType(my_struct);
5438                 break;
5439
5440         case SdlToSpc:
5441                 /*
5442                  * set the type; the attribute processing will set the id.
5443                  */
5444                 segPtr->type = _DtCvSetTypeToRegion(segPtr->type);
5445                 break;
5446       }
5447
5448     if (my_struct->cur_link != -1)
5449       {
5450         segPtr->type = _DtCvSetTypeToHyperText(segPtr->type);
5451         segPtr->link_idx = my_struct->cur_link;
5452       }
5453
5454     switch (element.sdl_element)
5455       {
5456         case SdlElementSnb:
5457                 my_struct->resolve_font = _SdlFontModeNone;
5458                 my_struct->snb          = segPtr;
5459                 my_struct->prev_data    = NULL;
5460                 break;
5461
5462         case SdlElementAltText:
5463                 segPtr->type = _DtCvSetTypeToNonBreak(segPtr->type);
5464                 break;
5465
5466         case SdlElementForm:
5467                 /*
5468                  * allocate a table for all the information
5469                  */
5470                 if (_DtHelpCeAllocSegment(my_struct->malloc_size,
5471                                 &(my_struct->alloc_size),
5472                                 &(my_struct->block_list), &newSeg) != 0)
5473                     return -1;
5474
5475                 newSeg->type = _DtCvSetTypeToTable(newSeg->type);
5476                 _DtCvJustifyCharsOfTableSeg(newSeg) = NULL;
5477
5478                 /*
5479                  * set the my_struct pointer to this table so that
5480                  * as the fstyle and frowec elements are parsed, the
5481                  * data goes directly into this table.
5482                  */
5483                 ElTable(my_struct) = newSeg;
5484                 break;
5485       }
5486
5487     return 0;
5488
5489 } /* End ParseElementStart */
5490
5491 /******************************************************************************
5492  * Function:    int ParseElementAttr (
5493  *                                      FormatStruct my_struct,
5494  *                                      SDLElementAttrList *attribs)
5495  *
5496  * Parameters:
5497  *
5498  * Returns:     0 if successful, -1 if errors
5499  *
5500  * Purpose:     Looks for the virtual page attributes.
5501  *
5502  ******************************************************************************/
5503 static  int
5504 ParseElementAttr(
5505     FormatStruct        *my_struct,
5506     enum SdlElement      cur_element,
5507     const SDLElementAttrList    *attribs,
5508     _DtCvValue           flag,
5509     _DtCvValue           process_flag)
5510 {
5511     int           result = 0;
5512     char          attribName[MAX_ATTRIBUTE_LENGTH + 2];
5513     _DtCvSegment *mySeg;
5514
5515     if (attribs == NULL || process_flag == False)
5516       {
5517         /*
5518          * No attributes - is there cdata in here?
5519          */
5520         if (flag || attribs != NULL)
5521             result = _DtHelpCeSkipCdata (my_struct->my_file,
5522                         (cur_element == SdlElementDocType ? True : False));
5523
5524         /*
5525          * get the element's end.
5526          */
5527         if (result != -1)
5528             result = _DtHelpCeGetSdlAttribute(my_struct->my_file,
5529                                                 MAX_ATTRIBUTE_LENGTH,
5530                                                 attribName);
5531
5532         /*
5533          * _DtHelpCeGetSdlAttribute should return 1, meaning it found
5534          * the >
5535          */
5536         if (result != 1)
5537             return -1;
5538         return 0;
5539       }
5540
5541     /*
5542      * clean and initialize the attributes for this element.
5543      */
5544     my_struct->el_info.enum_values = 0;
5545     my_struct->el_info.num_values = 0;
5546     my_struct->el_info.str1_values = 0;
5547     my_struct->el_info.str2_values = 0;
5548
5549     mySeg = my_struct->add_seg;
5550     InitAttributes(mySeg, my_struct->my_fonts, &(my_struct->el_info), attribs);
5551
5552     /*
5553      * clear the colJ and colW
5554      */
5555     if (SdlElementForm == ElType(my_struct))
5556       {
5557         ElTableColJStr(my_struct) = NULL;
5558         ElTableColWStr(my_struct) = NULL;
5559       }
5560
5561     /*
5562      * force the default of subheading orientation to heads as below the head.
5563      */
5564     if (ElType(my_struct) == SdlElementSubHead)
5565         _DtCvContainerVOrientOfSeg(mySeg) = _DtCvJUSTIFY_BOTTOM;
5566
5567     do {
5568         result = _DtHelpCeGetSdlAttribute(my_struct->my_file,
5569                                                 MAX_ATTRIBUTE_LENGTH,
5570                                                 attribName);
5571         if (result == 0)
5572             result = ProcessSDLAttribute(my_struct, mySeg,
5573                                         my_struct->my_fonts,
5574                                         &(my_struct->el_info),
5575                                         attribs,
5576                                         attribName);
5577     } while (result == 0);
5578
5579     if (result != -1)
5580         result = VerifyAttrList(&(my_struct->el_info), attribs);
5581
5582     if (result != -1)
5583       {
5584         if (cur_element == SdlElementVirpage
5585                                 ||
5586             SDLIsAttrSet(my_struct->el_info, SDL_ATTR_CLASS)
5587                                 ||
5588             SDLIsAttrSet(my_struct->el_info, SDL_ATTR_SSI)
5589                                 ||
5590             SDLIsAttrSet(my_struct->el_info, SDL_ATTR_LEVEL))
5591         MergeTossInfo(my_struct, mySeg, my_struct->my_fonts);
5592
5593         if (SDLIsStrAttrSet(my_struct->el_info, SDL_ATTR_LANGUAGE)
5594                 || SDLIsStrAttrSet(my_struct->el_info, SDL_ATTR_CHARSET))
5595             my_struct->mb_len = _DtHelpCeGetMbLen(
5596                         _DtHelpFontHintsLang(*(my_struct->my_fonts)),
5597                         _DtHelpFontHintsCharSet(*(my_struct->my_fonts)));
5598         /*
5599          * Do some specific work for containers.
5600          */
5601         if (NULL != mySeg && _DtCvIsSegContainer(mySeg))
5602           {
5603             /*
5604              * transfer any id or rid that got specified
5605              */
5606             if (SDLIsStrAttrSet(my_struct->el_info, SDL_ATTR_ID) ||
5607                         SDLIsStrAttrSet(my_struct->el_info, SDL_ATTR_RID))
5608               {
5609                 _DtCvContainerIdOfSeg(mySeg) = ElId(my_struct);
5610                 ClearAttrFlag(my_struct->el_info, SDL_ATTR_ID);
5611                 ClearAttrFlag(my_struct->el_info, SDL_ATTR_RID);
5612               }
5613
5614             /*
5615              * set the margins to absolute values
5616              */
5617             if (my_struct->ui_info->avg_char > 0)
5618               {
5619                 _DtCvContainerLMarginOfSeg(mySeg) =
5620                                         _DtCvContainerLMarginOfSeg(mySeg) *
5621                                                 my_struct->ui_info->avg_char;
5622
5623                 _DtCvContainerRMarginOfSeg(mySeg) =
5624                                         _DtCvContainerRMarginOfSeg(mySeg) *
5625                                                 my_struct->ui_info->avg_char;
5626
5627                 _DtCvContainerFMarginOfSeg(mySeg) =
5628                                         _DtCvContainerFMarginOfSeg(mySeg) *
5629                                                 my_struct->ui_info->avg_char;
5630
5631               }
5632             /*
5633              * set the container spacing to absolute values
5634              */
5635             if (my_struct->ui_info->line_height / 2 > 0)
5636               {
5637 /*
5638  * TODO .... take maximum! of spacing.
5639  */
5640                 TMarginOfSeg(mySeg) = TMarginOfSeg(mySeg) *
5641                                         (my_struct->ui_info->line_height / 2);
5642                 BMarginOfSeg(mySeg) = BMarginOfSeg(mySeg) *
5643                                         (my_struct->ui_info->line_height / 2);
5644
5645               }
5646
5647             /*
5648              * set the border width information
5649              */
5650             if (_DtCvBORDER_NONE != _DtCvContainerBorderOfSeg(mySeg))
5651                 _DtCvContainerLineWidthOfSeg(mySeg) =
5652                                                 my_struct->ui_info->line_width;
5653           }
5654       }
5655
5656     if (result == 1)
5657         result = 0;
5658
5659     return result;
5660
5661 } /* End ParseElementAttr */
5662
5663 /******************************************************************************
5664  * Function:    int ParseElementEnd (
5665  *                                      FormatStruct my_struct,
5666  *                                      int el_type);
5667  *
5668  * Parameters:
5669  *
5670  * Returns:     0 if successful, -1 if errors
5671  *
5672  * Purpose:     Looks for the virtual page beginning.
5673  *
5674  ******************************************************************************/
5675 static  int
5676 ParseElementEnd(
5677     FormatStruct        *my_struct,
5678     _DtCvSegment        *if_prev,
5679     SDLElementInfo       element,
5680     _DtCvValue           process_flag,
5681     _DtCvValue           end_flag)
5682 {
5683     char                *id;
5684     _DtCvSegment        *newSeg;
5685     _DtCvSegment        *segList;
5686
5687     if (MatchSDLElement (my_struct, element.element_end_str,
5688                 element.sdl_element, element.end_sig_chars, True) != 0 ||
5689                 (end_flag == False &&
5690                     _DtHelpCeFindSkipSdlElementEnd(my_struct->my_file) != 0))
5691         return -1;
5692
5693     if (process_flag == True)
5694       {
5695         _DtCvSegment  *pElement = my_struct->add_seg;
5696
5697         /*
5698          * if we aren't resolving the fonts for this element,
5699          * we need to save the toss information for later
5700          * when the element gets used in a table or snref.
5701          */
5702         if (_SdlFontModeResolve != my_struct->resolve_font &&
5703                 (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_CLASS)
5704                                 ||
5705                  SDLIsAttrSet(my_struct->el_info, SDL_ATTR_SSI)
5706                                 ||
5707                  SDLIsAttrSet(my_struct->el_info, SDL_ATTR_LEVEL)))
5708           {
5709             SdlMatchData *match;
5710
5711             /*
5712              * was a segment allocated for this element?
5713              * if not, we'll have to put our own special segment
5714              * around the segment list so the correct font inheritance
5715              * occurs. Later, this special segment will have to be
5716              * stripped out when the async blocks or snref item
5717              * is resolved.
5718              */
5719             if (NULL == pElement)
5720               {
5721                 if (_DtHelpCeAllocSegment(1, NULL, NULL, &pElement) != 0)
5722                     return -1;
5723
5724                 pElement->type = _DtCvSetTypeToContainer(pElement->type);
5725                 pElement->type = SetSdlWrapper(pElement->type);
5726                 _DtCvContainerListOfSeg(pElement) = my_struct->seg_list;
5727                 my_struct->seg_list = pElement;
5728               }
5729
5730             /*
5731              * has match data already been allocated for this element?
5732              */
5733             match = SegMatchDataPtr(pElement);
5734             if (NULL == match)
5735               {
5736                 match = (SdlMatchData *) malloc(sizeof(SdlMatchData));
5737                 if (NULL == match)
5738                     return -1;
5739               }
5740
5741             /*
5742              * save the clan, level and ssi of this element.
5743              */
5744             *match = my_struct->el_info.match;
5745             SegMatchData(pElement) = (void *) match;
5746             ClearAttrFlag(my_struct->el_info, SDL_ATTR_SSI);
5747           }
5748
5749         /*
5750          * attach the current segment list to the container's list
5751          */
5752         if (NULL != pElement && _DtCvIsSegContainer(pElement))
5753             _DtCvContainerListOfSeg(pElement) = my_struct->seg_list;
5754
5755         /*
5756          * check to see if the element has any data.
5757          * If not, can it (the element) be eleminated and free up memory?
5758          */
5759         if (NULL != pElement && my_struct->seg_list == NULL
5760             && element.elim_flag == True
5761             && ElType(my_struct) != SdlElementKey
5762             && TMarginOfSeg(pElement) == 0 && BMarginOfSeg(pElement) == 0)
5763           {
5764             _DtHelpFreeSegments(my_struct->add_seg, _DtCvFALSE,
5765                                         my_struct->ui_info->destroy_region,
5766                                         my_struct->ui_info->client_data);
5767
5768             if (ElType(my_struct) == SdlElementLink)
5769                 _DtLinkDbRemoveLink(my_struct->my_links,
5770                                                     my_struct->cur_link);
5771             my_struct->add_seg = NULL;
5772           }
5773         else
5774           {
5775             switch(ElType(my_struct))
5776               {
5777                 case SdlElementSnb:
5778                     my_struct->add_seg = NULL;
5779                     break;
5780
5781                 case SdlElementBlock:
5782                     if (ElTiming(my_struct) == SdlTimingAsync)
5783                       {
5784                         if (NULL != my_struct->add_seg)
5785                             AddToAsyncList(my_struct, my_struct->add_seg);
5786
5787                         my_struct->add_seg = NULL;
5788                       }
5789                     break;
5790
5791                 case SdlElementHead:
5792                 case SdlElementSubHead:
5793                     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_ABBREV)
5794                                 && ElAbbrev(my_struct) != NULL
5795                                 && strlen(ElAbbrev(my_struct)))
5796                       {
5797                         AbbrevOfSeg(my_struct->add_seg) =
5798                                                 (void *) ElAbbrev(my_struct);
5799                         ClearAttrFlag(my_struct->el_info, SDL_ATTR_ABBREV);
5800                       }
5801                     break;
5802
5803                 case SdlElementFdata:
5804                     ElTableList(my_struct) = ConvertToList(my_struct->seg_list);
5805                     break;
5806
5807                 case SdlElementLink:
5808                     CompressLinkSeg(my_struct->seg_list);
5809
5810                 case SdlElementKey:
5811                 case SdlElementSphrase:
5812                     /*
5813                      * move the content of the element up.
5814                      */
5815                     my_struct->add_seg = my_struct->seg_list;
5816
5817                     /*
5818                      * free the no longer needed segments.
5819                      */
5820                     if (NULL != pElement)
5821                       {
5822                         _DtCvContainerListOfSeg(pElement) = NULL;
5823                         _DtHelpFreeSegments(pElement, _DtCvFALSE,
5824                                         my_struct->ui_info->destroy_region,
5825                                         my_struct->ui_info->client_data);
5826                       }
5827                     break;
5828
5829                 case SdlElementForm:
5830                     /*
5831                      * get the segment list.
5832                      */
5833                     newSeg = ElTable(my_struct);
5834
5835                     /*
5836                      * include any async blocks into the table list.
5837                      */
5838                     if (ResolveAsyncBlock(my_struct, newSeg) != 0)
5839                         return -1;
5840
5841                     /*
5842                      * compress the table if possible down to just
5843                      * a container.
5844                      */
5845                     newSeg = CompressTable(my_struct, newSeg);
5846
5847                     /*
5848                      * add the table segment to the form's container list
5849                      * taking into account any heads for the form.
5850                      */
5851                     _DtCvNextSeg(newSeg) = _DtCvContainerListOfSeg(pElement);
5852                     _DtCvContainerListOfSeg(pElement) = newSeg;
5853                     break;
5854
5855                 case SdlElementIf:
5856                     if (ResolveIf (my_struct, if_prev))
5857                         return -1;
5858                     break;
5859
5860                 case SdlElementSnRef:
5861                     /*
5862                      * get the id of snref
5863                      */
5864                     id = NULL;
5865                     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_ID))
5866                         id = _DtCvContainerIdOfSeg(pElement);
5867
5868                     /*
5869                      * Resolve the snref to one of its items
5870                      */
5871                     newSeg = ResolveSnref(my_struct, pElement, id);
5872
5873                     /*
5874                      * if the snref got resolved, process
5875                      * otherwise, let it pass through. We'll try to
5876                      * resolve it later.
5877                      */
5878                     if (newSeg != pElement)
5879                       {
5880                         /*
5881                          * remember the segment list that we want
5882                          * to free. This includes the snref.
5883                          */
5884                         segList = pElement;
5885
5886                         /*
5887                          * if this <snref> had an id with it, then
5888                          * expand the <snref> to a marker segment
5889                          * (with the id) and a resolved refitem.
5890                          *
5891                          * Otherwise, eliminate the container.
5892                          */
5893                         if (NULL != id)
5894                           {
5895                             /*
5896                              * remember the segment list of the container.
5897                              * Since we are re-using the snref segment,
5898                              * we want to eliminate just the refitems of
5899                              * the snref and not the actual snref.
5900                              */
5901                             segList = _DtCvContainerListOfSeg(pElement);
5902
5903                             /*
5904                              * Move the refitem to be a sibling of the
5905                              * container.
5906                              */
5907                             _DtCvNextSeg(pElement) = newSeg;
5908
5909                             /*
5910                              * transfer the container id to a marker id
5911                              * and change the container into a marker.
5912                              */
5913                             _DtCvIdOfMarkerSeg(pElement) =
5914                                         _DtCvContainerIdOfSeg(pElement);
5915                             pElement->type =
5916                                         _DtCvSetTypeToMarker(pElement->type);
5917                             newSeg = pElement;
5918                           }
5919
5920                         /*
5921                          * free the no longer needed segments.
5922                          */
5923                         _DtHelpFreeSegments(segList, _DtCvFALSE,
5924                                         my_struct->ui_info->destroy_region,
5925                                         my_struct->ui_info->client_data);
5926                       }
5927
5928                     my_struct->add_seg = newSeg;
5929                     break;
5930               }
5931           }
5932
5933         /*
5934          * free the attributes for this element
5935          */
5936         FreeAttributes(ElType(my_struct),
5937                                 &(my_struct->el_info), my_struct->my_fonts);
5938
5939         /*
5940          * if this element can pull in new fonts, then a new font
5941          * structure was allocated for this element. Since we are
5942          * leaving the element, place the font structure in the
5943          * free list for possible reuse.
5944          */
5945         if (element.new_fonts && FreeFontInfo(my_struct) == -1)
5946             return -1;
5947       }
5948     else
5949         my_struct->add_seg = my_struct->seg_list;
5950
5951     if (element.formatting == True)
5952         my_struct->prev_data = NULL;
5953
5954     return 0;
5955
5956 } /* End ParseElementEnd */
5957 \f
5958 /******************************************************************************
5959  *
5960  * SDL Element Content Functions
5961  *
5962  *****************************************************************************/
5963 /******************************************************************************
5964  * Function:    int FindAndFix (
5965  *                                      _DtCvSegment *toss,
5966  *                                      _DtCvSegment *snb,
5967  *                                      _DtCvSegment *seg_list)
5968  *
5969  * Parameters:
5970  *
5971  * Returns:     0 if successful, -1 if errors
5972  *
5973  * Purpose:
5974  *
5975  ******************************************************************************/
5976 static  int
5977 FindAndFix(
5978     FormatStruct        *my_struct)
5979 {
5980     int           curLink  = my_struct->cur_link;
5981     _DtCvSegment *newSeg;
5982     _DtCvSegment *prevData = my_struct->prev_data;
5983     _DtCvSegment *lastSeg  = my_struct->last_seg;
5984     _DtCvSegment *tmpSeg;
5985
5986     _DtHelpFontHints *oldFonts = my_struct->my_fonts; 
5987
5988     /*
5989      * If the head has an snref in it, get the snb and resolve them
5990      */
5991     if (0 < my_struct->snref_cnt)
5992       {
5993         UnresSnref      *snref = my_struct->un_snrefs;
5994
5995         while (my_struct->snref_cnt)
5996           {
5997             /*
5998              * reset the structure to what it was at the time
5999              * this snref was encountered.
6000              */
6001             my_struct->prev_data = NULL;
6002             my_struct->last_seg  = NULL;
6003             my_struct->my_fonts  = &(snref->fonts);
6004             my_struct->cur_link  = snref->cur_link;
6005
6006             /*
6007              * resolve it.
6008              */
6009             newSeg = ResolveSnref(my_struct, snref->seg, NULL);
6010
6011             /*
6012              * free the snref items
6013              */
6014             _DtHelpFreeSegments(_DtCvContainerListOfSeg(snref->seg), _DtCvFALSE,
6015                                         my_struct->ui_info->destroy_region,
6016                                         my_struct->ui_info->client_data);
6017
6018             /*
6019              * find the end of the new segment's and have it point to
6020              * the next segments that the old segment points to.
6021              */
6022             if (NULL != newSeg)
6023               {
6024                 tmpSeg = newSeg;
6025                 while (NULL != _DtCvNextSeg(tmpSeg))
6026                     tmpSeg = _DtCvNextSeg(tmpSeg);
6027
6028                 _DtCvNextSeg(tmpSeg)  = _DtCvNextSeg(snref->seg);
6029                 _DtCvNextDisp(tmpSeg) = _DtCvNextDisp(snref->seg);
6030               }
6031
6032             /*
6033              * does the snref have an id?
6034              */
6035             if (NULL != snref->id)
6036               {
6037                 /*
6038                  * re-use the old snref, turning it into a marker
6039                  */
6040                 _DtCvIdOfMarkerSeg(snref->seg) = snref->id;
6041                 snref->seg->type = _DtCvSetTypeToMarker(snref->seg->type);
6042
6043                 /*
6044                  * set the next pointers on the old segment to
6045                  * the new segment.
6046                  */
6047                 if (NULL != newSeg)
6048                   {
6049                     _DtCvNextSeg(snref->seg)  = newSeg;
6050                     _DtCvNextDisp(snref->seg) = newSeg;
6051                   }
6052               }
6053
6054             /*
6055              * else move the resolved segment on top of the old snref.
6056              */
6057             else if (NULL != newSeg)
6058               {
6059                 /*
6060                  * free the private information. No longer needed.
6061                  */
6062                 free(snref->seg->client_use);
6063
6064                 /*
6065                  * now trounce the snref segment info.
6066                  */
6067                 *(snref->seg) = *newSeg;
6068
6069                 /*
6070                  * free the duplicate new segment.
6071                  */
6072                 if (_DtCvIsSegContainer(newSeg))
6073                     _DtCvContainerListOfSeg(newSeg) = NULL;
6074
6075                 free(newSeg);
6076               }
6077             /*
6078              * else there was no resolution, leave this segment as a NOOP.
6079              */
6080
6081             /*
6082              * go to the next unresolved snref
6083              */
6084             snref++;
6085             my_struct->snref_cnt--;
6086           }
6087
6088         free(my_struct->un_snrefs);
6089         my_struct->un_snrefs = NULL;
6090       }
6091
6092     my_struct->cur_link  = curLink;
6093     my_struct->prev_data = prevData;
6094     my_struct->last_seg  = lastSeg;
6095     my_struct->my_fonts  = oldFonts;
6096     return 0;
6097 }
6098
6099 /******************************************************************************
6100  * Function:    char *GetInterpCmd (SdlOption interp_type);
6101  *
6102  * Parameters:
6103  *
6104  * Returns:     0 if successful, -1 if errors
6105  *
6106  * Purpose:     Return the command associated with the interpreter type.
6107  *
6108  ******************************************************************************/
6109 static char *
6110 GetInterpCmd(SdlOption  interp_type)
6111 {
6112     const _CEInterpData *interp = InterpData;
6113
6114     while (interp->type != _DtCvOPTION_BAD)
6115       {
6116         if (interp->type == interp_type)
6117             return interp->cmd;
6118
6119         interp++;
6120       }
6121
6122     return NULL;
6123
6124 }
6125
6126 /******************************************************************************
6127  * Function:    int CheckForSnb (
6128  *                                              FormatStruct my_struct,
6129  *                                              int element_types,
6130  *                                              int exceptions);
6131  *
6132  * Parameters:
6133  *
6134  * Returns:     0 if successful, -1 if errors
6135  *
6136  * Purpose:     Looks for the virtual page attributes.
6137  *
6138  ******************************************************************************/
6139 static  int
6140 CheckForSnb(
6141     FormatStruct        *my_struct,
6142     SDLMask             *element_types,
6143     enum SdlElement      sig_element,
6144     SDLMask             *exceptions,
6145     SDLMask             *process_mask)
6146 {
6147     int    result = 0;
6148
6149     /*
6150      * If the head has an snref in it, get the snb and resolve them
6151      */
6152     if (my_struct->snref_used == True)
6153       {
6154         _DtCvSegment    *oldSegList = my_struct->seg_list;
6155         _DtCvSegment    *oldAddSeg  = my_struct->add_seg;
6156         _DtCvSegment    *oldPrevSeg = my_struct->prev_data;
6157         _DtCvSegment    *oldLastSeg = my_struct->last_seg;
6158
6159         my_struct->seg_list  = NULL;
6160         my_struct->add_seg   = NULL;
6161         my_struct->prev_data = NULL;
6162         my_struct->last_seg  = NULL;
6163
6164         result = ProcessSDLMarkup(my_struct, SdlElementSnb, SdlElementNone,
6165                                                 exceptions, process_mask);
6166         my_struct->seg_list  = oldSegList;
6167         my_struct->add_seg   = oldAddSeg;
6168         my_struct->prev_data = oldPrevSeg;
6169         my_struct->last_seg  = oldLastSeg;
6170
6171         /*
6172          * if no problems getting the snb, go through the items and
6173          * resolve the snrefs.
6174          */
6175         if (result != -1)
6176             result = FindAndFix(my_struct);
6177       }
6178
6179     return result;
6180
6181 } /* End CheckForSnb */
6182
6183 /******************************************************************************
6184  * Function:    int SetSaveSnref (
6185  *                                              FormatStruct my_struct,
6186  *                                              int element_types,
6187  *                                              int exceptions);
6188  *
6189  * Parameters:
6190  *
6191  * Returns:     0 if successful, -1 if errors
6192  *
6193  * Purpose:     Looks for the virtual page attributes.
6194  *
6195  ******************************************************************************/
6196 static  int
6197 SetSaveSnref(
6198     FormatStruct        *my_struct,
6199     SDLMask             *element_types,
6200     enum SdlElement      sig_element,
6201     SDLMask             *exceptions,
6202     SDLMask             *process_mask)
6203 {
6204     my_struct->save_snref = _DtCvTRUE;
6205     return 0;
6206
6207 } /* End SetSaveSnref */
6208
6209 /******************************************************************************
6210  * Function:    int ClearAndCheckSnref (
6211  *                                              FormatStruct my_struct,
6212  *                                              int element_types,
6213  *                                              int exceptions);
6214  *
6215  * Parameters:
6216  *
6217  * Returns:     0 if successful, -1 if errors
6218  *
6219  * Purpose:     Looks for the virtual page attributes.
6220  *
6221  ******************************************************************************/
6222 static  int
6223 ClearAndCheckSnref(
6224     FormatStruct        *my_struct,
6225     SDLMask             *element_types,
6226     enum SdlElement      sig_element,
6227     SDLMask             *exceptions,
6228     SDLMask             *process_mask)
6229 {
6230     int result = 0;
6231
6232     /*
6233      * reset the flag for saving snref elements
6234      */
6235     my_struct->save_snref = _DtCvFALSE;
6236
6237     /*
6238      * was any snrefs found? If so, resolve them now.
6239      */
6240     if (my_struct->snref_used == True)
6241         result = FindAndFix(my_struct);
6242
6243     return result;
6244
6245 } /* End ClearAndCheckSnref */
6246
6247 /******************************************************************************
6248  * Function:    int CheckType (
6249  *                                              FormatStruct my_struct,
6250  *                                              int element_types,
6251  *                                              int exceptions);
6252  *
6253  * Parameters:
6254  *
6255  * Returns:     0 if successful, -1 if errors
6256  *
6257  * Purpose:     Looks for the virtual page attributes.
6258  *
6259  ******************************************************************************/
6260 static  int
6261 CheckType(
6262     FormatStruct        *my_struct,
6263     SDLMask             *element_types,
6264     enum SdlElement      sig_element,
6265     SDLMask             *exceptions,
6266     SDLMask             *process_mask)
6267 {
6268     SdlOption    newOpt;
6269
6270     /*
6271      * cannot honor newlines in super or sub scripts.
6272      */
6273     newOpt = ElFrmtType(my_struct);
6274     if (SdlTypeLiteral == newOpt)
6275         newOpt = SdlTypeUnlinedLiteral;
6276     else if (SdlTypeLined == newOpt)
6277         newOpt = SdlTypeDynamic;
6278
6279     ElFrmtType(my_struct) = newOpt;
6280     if (SdlTypeDynamic != newOpt)
6281         my_struct->flags = _DtCvSetTypeToNonBreak(my_struct->flags);
6282
6283     if (SdlClassSub == ElClan(my_struct))
6284         my_struct->flags = _DtCvSetTypeToSubScript(my_struct->flags);
6285     else if (SdlClassSuper == ElClan(my_struct))
6286         my_struct->flags = _DtCvSetTypeToSuperScript(my_struct->flags);
6287
6288     /*
6289      * strip hypertext links
6290      */
6291     my_struct->cur_link = -1;
6292
6293     return 0;
6294
6295 } /* End CheckType */
6296
6297 /******************************************************************************
6298  * Function:    int SetType (
6299  *                                              FormatStruct my_struct,
6300  *                                              int element_types,
6301  *                                              int exceptions);
6302  *
6303  * Parameters:
6304  *
6305  * Returns:     0 if successful, -1 if errors
6306  *
6307  * Purpose:     Looks for the virtual page attributes.
6308  *
6309  ******************************************************************************/
6310 static  int
6311 SetType(
6312     FormatStruct        *my_struct,
6313     SDLMask             *element_types,
6314     enum SdlElement      sig_element,
6315     SDLMask             *exceptions,
6316     SDLMask             *process_mask)
6317 {
6318     if (ElType(my_struct) == SdlElementSphrase)
6319       {
6320         ContainerPtrToType(my_struct->active_frmt) =
6321                                    (_DtCvFrmtOption) SdlTypeLiteral;
6322         ElFrmtType(my_struct)                      = SdlTypeLiteral;
6323         my_struct->flags                           = 0;
6324       }
6325     else
6326         ElFrmtType(my_struct) = SdlTypeCdata;
6327
6328     if (SdlElementScript == ElType(my_struct))
6329       {
6330         /*
6331          * remember the interpretor value
6332          */
6333         FrmtPrivateInfo *priv = FrmtPrivInfoPtr(my_struct->add_seg);
6334
6335         priv->interp  = ElInterp(my_struct);
6336       }
6337
6338     return 0;
6339
6340 } /* End SetType */
6341
6342 /******************************************************************************
6343  * Function:    int ElseInfo (
6344  *                                              FormatStruct my_struct,
6345  *                                              int element_types,
6346  *                                              int exceptions);
6347  *
6348  * Parameters:
6349  *
6350  * Returns:     0 if successful, -1 if errors
6351  *
6352  * Purpose:     Looks for the virtual page attributes.
6353  *
6354  ******************************************************************************/
6355 static  int
6356 IfInfo(
6357     FormatStruct        *my_struct,
6358     SDLMask             *element_types,
6359     enum SdlElement      sig_element,
6360     SDLMask             *exceptions,
6361     SDLMask             *process_mask)
6362 {
6363     if (ElType(my_struct) == SdlElementIf)
6364       {
6365         my_struct->then_prev = NULL;
6366         my_struct->else_prev = NULL;
6367       }
6368     else if (ElType(my_struct) == SdlElementThen)
6369         my_struct->then_prev = my_struct->prev_data;
6370     else /* if (ElType(my_struct) == SdlElementElse) */
6371         my_struct->else_prev = my_struct->prev_data;
6372
6373     return 0;
6374
6375 } /* End IfInfo */
6376
6377 /******************************************************************************
6378  * Function:    int MarkFound (
6379  *                                              FormatStruct my_struct,
6380  *                                              int element_types,
6381  *                                              int exceptions);
6382  *
6383  * Parameters:
6384  *
6385  * Returns:     0 if successful, -1 if errors
6386  *
6387  * Purpose:     Looks for the virtual page attributes.
6388  *
6389  ******************************************************************************/
6390 static  int
6391 MarkFound(
6392     FormatStruct        *my_struct,
6393     SDLMask             *element_types,
6394     enum SdlElement      sig_element,
6395     SDLMask             *exceptions,
6396     SDLMask             *process_mask)
6397 {
6398     my_struct->snref_used = True;
6399
6400     /*
6401      * is there a newline hanging around that needs turning into a space?
6402      */
6403     if (SDLSearchMask(process_mask, SdlElementCdata)
6404         && my_struct->last_was_space == False && my_struct->last_was_nl == True)
6405       {
6406         _DtCvSegment *pSeg = my_struct->prev_data;
6407
6408         /*
6409          * tack the space onto the end of previous string if possible.
6410          */
6411         if (pSeg != NULL && _DtCvIsSegString(pSeg) &&
6412                         _DtCvIsSegRegChar(pSeg) && !(_DtCvIsSegNewLine(pSeg)))
6413           {
6414             char *strPtr;
6415             int   len = _DtCvStrLen(_DtCvStringOfStringSeg(pSeg), 0);
6416
6417             _DtCvStringOfStringSeg(pSeg) = (char *) realloc(
6418                                         _DtCvStringOfStringSeg(pSeg), len+2);
6419             if (_DtCvStringOfStringSeg(pSeg) == NULL)
6420                 return -1;
6421
6422              strPtr   = (char *) _DtCvStrPtr(_DtCvStringOfStringSeg(pSeg),
6423                                                                 0, len);
6424             *strPtr++ = ' ';
6425             *strPtr   = '\0';
6426           }
6427         else if (MySaveString(&(my_struct->seg_list), my_struct, " ",
6428                                 my_struct->cur_link, 1, False ) != 0)
6429             return -1;
6430
6431         my_struct->last_was_space = True;
6432         my_struct->last_was_nl    = False;
6433       }
6434
6435     return 0;
6436
6437 } /* End MarkFound */
6438
6439 /******************************************************************************
6440  * Function:    int SaveItemInfo (
6441  *                                              FormatStruct my_struct,
6442  *                                              int element_types,
6443  *                                              int exceptions);
6444  *
6445  * Parameters:
6446  *
6447  * Returns:     0 if successful, -1 if errors
6448  *
6449  * Purpose:     Looks for the virtual page attributes.
6450  *
6451  ******************************************************************************/
6452 static  int
6453 SaveItemInfo(
6454     FormatStruct        *my_struct,
6455     SDLMask             *element_types,
6456     enum SdlElement      sig_element,
6457     SDLMask             *exceptions,
6458     SDLMask             *process_mask)
6459 {
6460     _DtCvSegment         *refItem = my_struct->add_seg;
6461     SdlMatchData *info;
6462
6463     if (SDLSearchMask(process_mask, SdlElementRefItem) == False)
6464         return 0;
6465
6466     info = (SdlMatchData *) malloc (sizeof(SdlMatchData));
6467     if (NULL == info)
6468         return -1;
6469
6470     /*
6471      * save the clan, ssi & level of this refitem
6472      */
6473     *info = my_struct->el_info.match;
6474     SegMatchData(refItem) = (void *) info;
6475
6476     ClearAttrFlag(my_struct->el_info, SDL_ATTR_SSI);
6477
6478     return 0;
6479
6480 } /* End SaveItemInfo */
6481
6482 /******************************************************************************
6483  * Function:    int AllocateBlock (
6484  *                                              FormatStruct my_struct,
6485  *                                              int element_types,
6486  *                                              int exceptions);
6487  * Parameters:
6488  *
6489  * Returns:     0 if successful, -1 if errors
6490  *
6491  * Purpose:
6492  *
6493  ******************************************************************************/
6494 static  int
6495 AllocateBlock(
6496     FormatStruct        *my_struct,
6497     SDLMask             *element_types,
6498     enum SdlElement      sig_element,
6499     SDLMask             *exceptions,
6500     SDLMask             *process_mask)
6501 {
6502     /*
6503      * allocate a block of information all at once for later segments.
6504      * This, hopefully, will save processing time when later freed.
6505      *
6506      * Simply change the malloc_size in the formatting struct.
6507      */
6508     if (my_struct->add_seg != NULL)
6509       {
6510         if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_COUNT))
6511             my_struct->malloc_size = ElCount(my_struct);
6512         else
6513           {
6514             my_struct->malloc_size = 500;
6515             if (ElType(my_struct) == SdlElementToss)
6516                 my_struct->malloc_size = 160;
6517           }
6518       }
6519
6520     return 0;
6521
6522 } /* End AllocateBlock */
6523
6524 /******************************************************************************
6525  * Function:    int CleanUpBlock (
6526  *                                              FormatStruct my_struct,
6527  *                                              int element_types,
6528  *                                              int exceptions);
6529  * Parameters:
6530  *
6531  * Returns:     0 if successful, -1 if errors
6532  *
6533  * Purpose:
6534  *
6535  ******************************************************************************/
6536 static  int
6537 CleanUpBlock(
6538     FormatStruct        *my_struct,
6539     SDLMask             *element_types,
6540     enum SdlElement      sig_element,
6541     SDLMask             *exceptions,
6542     SDLMask             *process_mask)
6543 {
6544     /*
6545      * Go back to piece meal allocation.
6546      */
6547     my_struct->malloc_size = 1;
6548     return 0;
6549
6550 } /* End CleanUpBlock */
6551
6552 /******************************************************************************
6553  * Function:    int RegisterLink (
6554  *                                              FormatStruct my_struct,
6555  *                                              int element_types,
6556  *                                              int exceptions);
6557  *
6558  * Parameters:
6559  *
6560  * Returns:     0 if successful, -1 if errors
6561  *
6562  * Purpose:     Looks for the virtual page attributes.
6563  *
6564  ******************************************************************************/
6565 static  int
6566 RegisterLink(
6567     FormatStruct        *my_struct,
6568     SDLMask             *element_types,
6569     enum SdlElement      sig_element,
6570     SDLMask             *exceptions,
6571     SDLMask             *process_mask)
6572 {
6573     int          winType = _DtCvWindowHint_CurrentWindow;
6574     SDLId        rid     = _DtCvContainerIdOfSeg(my_struct->add_seg);
6575
6576     if (SDLSearchMask(process_mask, SdlElementLink) == False)
6577         return 0;
6578
6579     switch (ElWindow(my_struct))
6580       {
6581         case SdlWindowNew: winType = _DtCvWindowHint_NewWindow;
6582                         break;
6583         case SdlWindowPopup: winType = _DtCvWindowHint_PopupWindow;
6584                         break;
6585       }
6586
6587     my_struct->cur_link = _DtLinkDbAddLink(my_struct->my_links, NULL, rid,
6588                                 _DtCvLinkType_SameVolume, winType, NULL);
6589
6590     if (rid == NULL || my_struct->cur_link < 0)
6591         return -1;
6592
6593     /*
6594      * indicate that at least a blank should be saved for the link
6595      */
6596     my_struct->save_blank = True;
6597
6598     return 0;
6599
6600 } /* End RegisterLink */
6601
6602 /******************************************************************************
6603  * Function:    int ResolveIf (FormatStruct my_struct)
6604  *
6605  * Parameters:
6606  *
6607  * Returns:     0 if successful, -1 if errors
6608  *
6609  * Purpose:     Looks for the virtual page attributes.
6610  *
6611  ******************************************************************************/
6612 static  int
6613 ResolveIf(
6614     FormatStruct        *my_struct,
6615     _DtCvSegment        *prev_data)
6616 {
6617
6618     _DtCvSegment        *ifSeg       = my_struct->add_seg;
6619
6620     _DtCvSegment        *condSeg     = _DtCvContainerListOfSeg(ifSeg);
6621     _DtCvSegment        *condDataSeg = _DtCvContainerListOfSeg(condSeg);
6622
6623     _DtCvSegment        *thenSeg     = _DtCvNextSeg(condSeg);
6624     _DtCvSegment        *elseSeg     = _DtCvNextSeg(thenSeg);
6625
6626     _DtCvSegment        *resolveSeg  = NULL;
6627     _DtCvSegment        *nextDisp    = NULL;
6628     _DtCvSegment        *el          = NULL;
6629     char                *ifData      = NULL;
6630     char                *interpStr;
6631
6632     interpStr = GetInterpCmd(ElInterp(my_struct));
6633     if (NULL == interpStr)
6634         return -1;
6635
6636     if (_DtCvRunInterp(my_struct->ui_info->exec_filter,
6637                                 my_struct->ui_info->client_data,
6638                                 interpStr,
6639                         _DtCvStringOfStringSeg(condDataSeg), &ifData) == 0)
6640       {
6641         /*
6642          * Get the pointer to the next displayable item in the 'then'
6643          * list. This usually will point into the 'then' list,
6644          * but may point into the 'else' list.
6645          */
6646         if (my_struct->then_prev != NULL)
6647             nextDisp = my_struct->then_prev->next_disp;
6648
6649         /*
6650          * use the 'then' data
6651          */
6652         if (atoi (ifData) != 0)
6653           {
6654             el = thenSeg;
6655
6656             /*
6657              * check to make sure that the next_disp is NOT into the
6658              * 'else' list (because it's about to become a dangling
6659              * next_disp if it is!).
6660              */
6661             if (elseSeg != NULL)
6662               {
6663                 /*
6664                  * if the next displayable segment is in the 'else'
6665                  * list, null out the next displayable segement since
6666                  * there isn't anything in the 'then' list.
6667                  */
6668                 if (my_struct->then_prev == my_struct->else_prev)
6669                     nextDisp = NULL;
6670                 else
6671                     /*
6672                      * terminate the displayable segment list
6673                      * before the 'else' list.
6674                      */
6675                     my_struct->else_prev->next_disp = NULL;
6676               }
6677           }
6678         else if (elseSeg != NULL)
6679           {
6680             /*
6681              * use the 'else' data.
6682              */
6683             el = elseSeg;
6684
6685             /*
6686              * Get the next displayable item in the 'else' list.
6687              */
6688             if (my_struct->else_prev != NULL)
6689                 nextDisp = my_struct->else_prev->next_disp;
6690           }
6691
6692         if (el != NULL)
6693           {
6694             resolveSeg   = _DtCvContainerListOfSeg(el);
6695             _DtCvContainerListOfSeg(el) = NULL;
6696           }
6697
6698         free(ifData);
6699       }
6700
6701     /*
6702      * set the true next displayable pointer.
6703      */
6704     if (prev_data != NULL)
6705         prev_data->next_disp = nextDisp;
6706
6707     /*
6708      * set the previous displayable segment to the last displayable
6709      * segment in the 'if' clause; in case more displayable segments
6710      * follow.
6711      */
6712     my_struct->prev_data = nextDisp;
6713
6714     /*
6715      * free the no longer needed if construct
6716      */
6717     _DtHelpFreeSegments(my_struct->add_seg, _DtCvFALSE,
6718                                         my_struct->ui_info->destroy_region,
6719                                         my_struct->ui_info->client_data);
6720
6721     /*
6722      * set the add segment to the result of the if
6723      */
6724     my_struct->add_seg = resolveSeg;
6725
6726     return 0;
6727
6728 } /* End ResolveIf */
6729
6730 /******************************************************************************
6731  * Function:    int ZeroOrOne (
6732  *                                              FormatStruct my_struct,
6733  *                                              int element_types,
6734  *                                              int exceptions);
6735  *
6736  * Parameters:
6737  *
6738  * Returns:     0 if successful, -1 if errors
6739  *
6740  * Purpose:     Looks for the virtual page attributes.
6741  *
6742  ******************************************************************************/
6743 static  int
6744 ZeroOrOne(
6745     FormatStruct        *my_struct,
6746     SDLMask             *element_types,
6747     enum SdlElement      sig_element,
6748     SDLMask             *exceptions,
6749     SDLMask             *process_mask)
6750 {
6751     int    result = 0;
6752
6753     if (my_struct->parsed == SdlElementNone)
6754         result = _DtHelpCeReturnSdlElement(my_struct->my_file, SdlElementList,
6755                         SDLSearchMask(element_types, SdlElementCdata),
6756                                 &(my_struct->parsed), &(my_struct->remember),
6757                                 &(my_struct->end_flag));
6758
6759     if (result == 0 && my_struct->end_flag == False &&
6760                 SDLSearchMask(element_types, my_struct->parsed) == True)
6761       {
6762         /*
6763          * check to make sure this is *not* Cdata or if it is that the
6764          * PcDataFollows flag is *not* set.
6765          */
6766         if (my_struct->parsed != SdlElementCdata ||
6767                 SDLSearchMask(element_types, SdlPcDataFollows) == False)
6768             result = ParseSDL(my_struct, my_struct->parsed, sig_element,
6769                                                 exceptions, process_mask);
6770       }
6771     else if (result == 1) /* eof on compressed entry/file */
6772         result = 0;
6773
6774     return result;
6775 } /* End ZeroOrOne */
6776
6777 /******************************************************************************
6778  * Function:    int ZeroToN (
6779  *                                              FormatStruct my_struct,
6780  *                                              int element_types,
6781  *                                              int exceptions);
6782  *
6783  * Parameters:
6784  *
6785  * Returns:     0 if successful, -1 if errors
6786  *
6787  * Purpose:     Looks for the virtual page attributes.
6788  *
6789  ******************************************************************************/
6790 static  int
6791 ZeroToN(
6792     FormatStruct        *my_struct,
6793     SDLMask             *element_types,
6794     enum SdlElement      sig_element,
6795     SDLMask             *exceptions,
6796     SDLMask             *process_mask)
6797 {
6798     _DtCvValue done   = False;
6799     int       result = 0;
6800
6801     while (result == 0 && !done)
6802       {
6803         if (my_struct->parsed == SdlElementNone)
6804             result = _DtHelpCeReturnSdlElement(my_struct->my_file, SdlElementList,
6805                         SDLSearchMask(element_types, SdlElementCdata),
6806                                 &(my_struct->parsed), &(my_struct->remember),
6807                                 &(my_struct->end_flag));
6808
6809         if (result == 0 && my_struct->end_flag == False &&
6810                 SDLSearchMask(element_types, my_struct->parsed) == True)
6811           {
6812             /*
6813              * check to make sure this is *not* Cdata or if it is that the
6814              * PcDataFollows flag is *not* set.
6815              */
6816             if (my_struct->parsed != SdlElementCdata ||
6817                       SDLSearchMask(element_types, SdlPcDataFollows) == False)
6818                 result = ParseSDL(my_struct, my_struct->parsed,
6819                                         sig_element, exceptions, process_mask);
6820             else
6821                 done = True;
6822           }
6823         else
6824           {
6825             if (result == 1) /* eof on compressed entry/file */
6826                 result = 0;
6827             done   = True;
6828           }
6829       }
6830
6831     return result;
6832
6833 } /* End ZeroToN */
6834
6835 /******************************************************************************
6836  * Function:    int OneToN (
6837  *                                              FormatStruct my_struct,
6838  *                                              int element_types,
6839  *                                              int exceptions);
6840  *
6841  * Parameters:
6842  *
6843  * Returns:     0 if successful, -1 if errors
6844  *
6845  * Purpose:     Looks for the virtual page attributes.
6846  *
6847  ******************************************************************************/
6848 static  int
6849 OneToN(
6850     FormatStruct        *my_struct,
6851     SDLMask             *element_types,
6852     enum SdlElement      sig_element,
6853     SDLMask             *exceptions,
6854     SDLMask             *process_mask)
6855 {
6856     int    found  = False;
6857     int    result = 0;
6858     int    done   = False;
6859
6860     while (result == 0 && !done)
6861       {
6862         if (my_struct->parsed == SdlElementNone)
6863             result = _DtHelpCeReturnSdlElement(my_struct->my_file, SdlElementList,
6864                         SDLSearchMask(element_types, SdlElementCdata),
6865                                 &(my_struct->parsed), &(my_struct->remember),
6866                                 &(my_struct->end_flag));
6867
6868         if (result == 0 && my_struct->end_flag == False &&
6869                 SDLSearchMask(element_types, my_struct->parsed) == True)
6870           {
6871             found = True;
6872             result = ParseSDL(my_struct, my_struct->parsed, sig_element,
6873                                                 exceptions, process_mask);
6874           }
6875         else
6876             done = True;
6877       }
6878
6879     if (!found)
6880         result = -1;
6881
6882     return result;
6883
6884 } /* End OneToN */
6885
6886 /******************************************************************************
6887  * Function:    int OnlyOne (
6888  *                                              FormatStruct my_struct,
6889  *                                              int element_types,
6890  *                                              int exceptions);
6891  *
6892  * Parameters:
6893  *
6894  * Returns:     0 if successful, -1 if errors
6895  *
6896  * Purpose:     Looks for the virtual page attributes.
6897  *
6898  ******************************************************************************/
6899 static  int
6900 OnlyOne(
6901     FormatStruct        *my_struct,
6902     SDLMask             *element_types,
6903     enum SdlElement      sig_element,
6904     SDLMask             *exceptions,
6905     SDLMask             *process_mask)
6906 {
6907     _DtCvValue found  = False;
6908     int       result = 0;
6909
6910     if (my_struct->parsed == SdlElementNone)
6911         result = _DtHelpCeReturnSdlElement(my_struct->my_file, SdlElementList,
6912                         SDLSearchMask(element_types, SdlElementCdata),
6913                                 &(my_struct->parsed), &(my_struct->remember),
6914                                 &(my_struct->end_flag));
6915
6916     if (result == 0 && my_struct->end_flag == False &&
6917                 SDLSearchMask(element_types, my_struct->parsed) == True)
6918       {
6919         found = True;
6920         result = ParseSDL(my_struct, my_struct->parsed, sig_element,
6921                                                 exceptions, process_mask);
6922       }
6923
6924     if (!found)
6925         result = -1;
6926
6927     return result;
6928
6929 } /* End OnlyOne */
6930
6931 /******************************************************************************
6932  * Function:    int OnlyOneEach (
6933  *                                              FormatStruct my_struct,
6934  *                                              int element_types,
6935  *                                              int exceptions);
6936  *
6937  * Parameters:
6938  *
6939  * Returns:     0 if successful, -1 if errors
6940  *
6941  * Purpose:     Looks for the virtual page attributes.
6942  *
6943  ******************************************************************************/
6944 static  int
6945 OnlyOneEach(
6946     FormatStruct        *my_struct,
6947     SDLMask             *element_types,
6948     enum SdlElement      sig_element,
6949     SDLMask             *exceptions,
6950     SDLMask             *process_mask)
6951 {
6952     int       result = 0;
6953     enum SdlElement myEl;
6954     SDLMask     myMask[SDL_MASK_LEN];
6955
6956     SaveRestoreMask(myMask, element_types);
6957
6958     while (result == 0 && SDLCheckMask(myMask))
6959       {
6960         if (my_struct->parsed == SdlElementNone)
6961             result = _DtHelpCeReturnSdlElement(my_struct->my_file, SdlElementList,
6962                         SDLSearchMask(myMask, SdlElementCdata),
6963                                 &(my_struct->parsed), &(my_struct->remember),
6964                                 &(my_struct->end_flag));
6965
6966         if (result == 0 && my_struct->end_flag == False &&
6967                 SDLSearchMask(element_types, my_struct->parsed) == True)
6968           {
6969             myEl   = my_struct->parsed;
6970             result = ParseSDL(my_struct, my_struct->parsed, sig_element,
6971                                                 exceptions, process_mask);
6972
6973             SDLStripFromMask(myMask, myEl);
6974           }
6975         else
6976             result = -1;
6977       }
6978
6979     if (SDLCheckMask(myMask))
6980         result = -1;
6981
6982     return result;
6983
6984 } /* End OnlyOneEach */
6985
6986 /******************************************************************************
6987  * Function:    int Cdata (FormatStruct my_struct,
6988  *                                      int cur_element, exceptions);
6989  *
6990  * Parameters:
6991  *
6992  * Returns:     0 if successful, -1 if errors
6993  *
6994  * Purpose:     Looks for the virtual page attributes.
6995  *
6996  ******************************************************************************/
6997 static  int
6998 Cdata(
6999     FormatStruct        *my_struct,
7000     SDLMask             *cur_element,
7001     enum SdlElement      sig_element,
7002     SDLMask             *exceptions,
7003     SDLMask             *process_mask)
7004 {
7005     int          i;
7006     int          reason;
7007     int          myLen    = 0;
7008     int          curLen   = my_struct->mb_len;
7009     int          multiLen = my_struct->mb_len;
7010     int          saveLen  = my_struct->mb_len;
7011     char         nonBreakChar;
7012     char        *string   = NULL;
7013     char         spaceStr[] = " ";
7014     char         dashStr[]  = "-";
7015     SdlOption type     = ElFrmtType(my_struct);
7016     _DtCvSegment        *pSeg       = NULL;
7017     _DtCvValue   nlToSpace   = True;
7018     _DtCvValue   processFlag = SDLSearchMask(process_mask, SdlElementCdata);
7019
7020     if (my_struct->ui_info->nl_to_space == 0)
7021         nlToSpace = False;
7022
7023     if (type == SdlTypeCdata)
7024       {
7025         /*
7026          * the element requires straight cdata for processing - i.e.
7027          * the data is going to be passed off to an interperter.
7028          * Therefore it doesn't want it broken up into different
7029          * byte length segments.
7030          *
7031          * Therefore, force the string save to put all the data into
7032          * one string.
7033          */
7034         saveLen = 1;
7035       }
7036
7037     if (my_struct->remember != NULL)
7038       {
7039         i   = 0;
7040         string  = my_struct->remember;
7041         myLen   = strlen(string);
7042         while (string[i] != '\0')
7043           {
7044             if (multiLen != 1)
7045                 curLen = mblen (&string[i], multiLen);
7046
7047             if (curLen == 1)
7048               {
7049                 if (my_struct->last_was_nl == True)
7050                   {
7051                     if (MoveString(&string, &myLen, &i) == -1)
7052                         return -1;
7053
7054                     string[i++] = ' ';
7055                     my_struct->last_was_space = True;
7056                   }
7057
7058                 my_struct->last_was_nl = False;
7059                 my_struct->last_was_mb = False;
7060
7061                 if (string[i] == '\t')
7062                     string[i] = ' ';
7063     
7064                 if (string[i] == '&')
7065                   {
7066                     strcpy (&string[i], &string[i+1]);
7067                     if (string[i] == '\0')
7068                       {
7069                         string[i] = BufFileGet(my_struct->my_file);
7070                         if (string[i] == BUFFILEEOF)
7071                             return -1;
7072                         string[i+1] = '\0';
7073                       }
7074     
7075                     /*
7076                      * is this an SGML numeric character reference
7077                      * entity?  if so, it should have the format
7078                      * '&#d[d[d]][;]' where 'ddd' represent characters
7079                      * of '0' to '9'.  The semi-colon is required iff
7080                      * the next character is a numeric character of '0'
7081                      * to '9'.  Otherwise it is optional.
7082                      */
7083                     if (string[i] == '#')
7084                       {
7085                         int j;
7086                         int value;
7087
7088 #define ESC_STRING_LEN  4
7089                         i++;
7090
7091                         /*
7092                          * Is there enough to room to process three digits
7093                          * and a possible semi-colon?
7094                          */
7095                         if (myLen - i < ESC_STRING_LEN)
7096                           {
7097                             /*
7098                              * lengthen the string so that it can contain
7099                              * the information
7100                              */
7101                             myLen  += ESC_STRING_LEN;
7102                             string  = (char *) realloc(string,
7103                                                 sizeof(char) * (myLen + 1));
7104                             if (string == NULL)
7105                                 return -1;
7106                           }
7107
7108                         /*
7109                          * now make sure that the entire numeric entity
7110                          * exists in the string.
7111                          */
7112                         j = i;
7113                         while ('0' <= string[i] && string[i] <= '9')
7114                             i++;
7115
7116                         /*
7117                          * run into the end of string before running
7118                          * into a delimiter? Fill out the escaped
7119                          * numeric character.
7120                          */
7121                         if (string[i] == '\0')
7122                           {
7123                             do
7124                               {
7125                                 string[i] = BufFileGet(my_struct->my_file);
7126                                 if (string[i] == BUFFILEEOF)
7127                                     return -1;
7128                                 i++;
7129                               } while (i < myLen && '0' <= string[i-1]
7130                                                         && string[i-1] <= '9');
7131                             /*
7132                              * end the string and back up to the last
7133                              * character
7134                              */
7135                             string[i] = '\0';
7136                             i--;
7137                           }
7138
7139                         /*
7140                          * the fourth character is a numeric, error
7141                          */
7142                         if ('0' <= string[i] && string[i] <= '9')
7143                             return -1;
7144
7145                         if (string[i] == ';')
7146                             i++;
7147
7148                         value = atoi(&string[j]);
7149                         if (value > 255)
7150                             return -1;
7151
7152                         /*
7153                          * smash over the pound sign with the 'real' value
7154                          * and copy the rest of the string to after it.
7155                          */
7156                         string[j-1] = (char) value;
7157                         strcpy (&string[j], &string[i]);
7158                         i = j;
7159                       }
7160
7161                     if (string[i] == '\n')
7162                       {
7163                         if (ProcessString(my_struct, True, True, True,
7164                                         True,
7165                                         processFlag, string, saveLen, &i) != 0)
7166                             return -1;
7167                       }
7168                     else if (string[i] == ' ')
7169                       {
7170                         if (ProcessNonBreakChar(my_struct, processFlag,
7171                                         spaceStr, string, saveLen, &i) != 0)
7172                             return -1;
7173                       }
7174                     else if (string[i] == '-')
7175                       {
7176                         if (ProcessNonBreakChar(my_struct, processFlag,
7177                                         dashStr, string, saveLen, &i) != 0)
7178                             return -1;
7179                       }
7180                     else
7181                         my_struct->last_was_space = False;
7182                     i++;
7183                   }
7184                 else if (string[i] == '\n')
7185                   {
7186                     /*
7187                      * want to keep the newlines
7188                      */
7189                     if (type == SdlTypeCdata)
7190                         i++;
7191                     else if (type == SdlTypeDynamic ||
7192                                                 type == SdlTypeUnlinedLiteral)
7193                       {
7194                         if (my_struct->last_was_space == False)
7195                             my_struct->last_was_nl = True;
7196
7197                         strcpy (&string[i], &string[i+1]);
7198                       }
7199                     else
7200                       {
7201                         string[i] = '\0';
7202                         if (processFlag == True &&
7203                                     MySaveString(&(my_struct->seg_list),
7204                                         my_struct, string, my_struct->cur_link,
7205                                         saveLen, True) != 0)
7206                           {
7207                             MyFree(string);
7208                             return -1;
7209                           }
7210     
7211                         strcpy (string, &string[i+1]);
7212                         i = 0;
7213                       }
7214                   }
7215                 else if (string[i] == ' ')
7216                   {
7217                     if (False == my_struct->save_blank &&
7218                         type != SdlTypeLiteral && type != SdlTypeUnlinedLiteral
7219                                         && my_struct->last_was_space == True)
7220                         strcpy (&string[i], &string[i+1]);
7221                     else
7222                         i++;
7223                     my_struct->last_was_space = True;
7224                   }
7225                 else
7226                   {
7227                     my_struct->last_was_space = False;
7228                     i++;
7229                   }
7230               }
7231             else if (curLen > 0)
7232               {
7233                 if (my_struct->last_was_nl == True)
7234                   {
7235                     if (nlToSpace == True || my_struct->last_was_mb == False)
7236                       {
7237                         if (MoveString(&string, &myLen, &i) == -1)
7238                             return -1;
7239
7240                         string[i++] = ' ';
7241                       }
7242                     else /* the last was a multibyte character, tighten up */
7243                       {
7244                         i--;
7245                         strcpy (&string[i], &string[i+1]);
7246                       }
7247                   }
7248
7249                 my_struct->last_was_space = False;
7250                 my_struct->last_was_nl    = False;
7251                 my_struct->last_was_mb    = True;
7252                 i += curLen;
7253               }
7254             else if (curLen == 0)
7255                 return -1;
7256             else /* if (curLen < 0) */
7257               {
7258                 /*
7259                  * must finish up the character
7260                  */
7261                 int  len = i + 1;
7262
7263                 while (curLen < 0 && len - i < multiLen)
7264                   {
7265                     if (myLen <= len)
7266                       {
7267                         string = (char *) realloc(string, myLen + multiLen + 1);
7268                         if (string == NULL)
7269                             return -1;
7270                         myLen += multiLen;
7271                       }
7272
7273                     string[len] = BufFileGet(my_struct->my_file);
7274                     if (string[len++] == BUFFILEEOF)
7275                             return -1;
7276
7277                     string[len] = '\0';
7278                     curLen      = mblen (&string[i], multiLen);
7279                   }
7280
7281                 if (curLen < 0)
7282                     return -1;
7283               }
7284           }
7285
7286         if (processFlag == False)
7287           {
7288             free(string);
7289             string = NULL;
7290             myLen  = 0;
7291           }
7292
7293         my_struct->remember = NULL;
7294       }
7295
7296     do {
7297         my_struct->parsed = SdlElementNone;
7298         reason = _DtHelpCeGetSdlCdata(my_struct->my_file, type, multiLen,
7299                                 nlToSpace,
7300                                 &my_struct->last_was_space,
7301                                 &my_struct->last_was_nl,
7302                                 &my_struct->last_was_mb,
7303                                 &nonBreakChar,
7304                         (processFlag == True ? &string : ((char**)NULL)),
7305                                 &myLen);
7306         if (reason < 0)
7307             return -1;
7308
7309         if (string != NULL && *string != '\0')
7310           {
7311             /*
7312              * save the string.
7313              */
7314             if (MySaveString(&(my_struct->seg_list), my_struct,
7315                         string, my_struct->cur_link, saveLen,
7316                         (1 == reason ? True : False)) != 0)
7317               {
7318                 MyFree(string);
7319                 return -1;
7320               }
7321
7322             /*
7323              * indicate that a string was saved for the current link
7324              */
7325             my_struct->save_blank = False;
7326
7327             /*
7328              * null the temp buffer.
7329              */
7330             string[0] = '\0';
7331  
7332             /*
7333              * reset flags if we stopped because of a newline.
7334              */
7335             if (1 == reason && (SdlTypeLiteral == type || SdlTypeLined == type))
7336               {
7337                 my_struct->last_was_space = True;
7338                 my_struct->last_was_nl    = False;
7339               }
7340           }
7341         else if (reason == 1) /* stopped because of newline */
7342           {
7343             pSeg = my_struct->prev_data;
7344
7345             if (pSeg == NULL || _DtCvIsSegNewLine(pSeg))
7346               {
7347                 if (_DtHelpCeAllocSegment(my_struct->malloc_size,
7348                                 &(my_struct->alloc_size),
7349                                 &(my_struct->block_list), &pSeg) != 0)
7350                     return -1;
7351
7352                 pSeg->type   = _DtCvSetTypeToNoop(pSeg->type);
7353                 if (my_struct->prev_data != NULL)
7354                     my_struct->prev_data->next_disp = pSeg;
7355
7356                 my_struct->prev_data = pSeg;
7357                 _DtHelpCeAddSegToList(pSeg, &(my_struct->seg_list),
7358                                                 &(my_struct->last_seg));
7359               }
7360
7361             pSeg->type = _DtCvSetTypeToNewLine(pSeg->type);
7362
7363             my_struct->last_was_space = True;
7364             my_struct->last_was_nl    = False;
7365           }
7366
7367         /*
7368          * did we stop because of a non-breaking character?
7369          */
7370         if (2 == reason && True == processFlag)
7371           {
7372             /*
7373              * copy the non breaking character into a buffer.
7374              */
7375             if (1 > myLen)
7376               {
7377                 string = (char *) malloc (sizeof(char) * 32);
7378                 myLen  = 32;
7379               }
7380             string[0] = nonBreakChar;
7381             string[1] = '\0';
7382
7383             /*
7384              * save the string.
7385              */
7386             my_struct->flags = _DtCvSetTypeToNonBreak(my_struct->flags);
7387             if (MySaveString(&(my_struct->seg_list), my_struct,
7388                         string, my_struct->cur_link, saveLen, False) != 0)
7389               {
7390                 MyFree(string);
7391                 return -1;
7392               }
7393             my_struct->flags = my_struct->flags & ~(_DtCvNON_BREAK);
7394
7395             /*
7396              * indicate that the non-breaking character is considered
7397              * non-white space.
7398              */
7399             my_struct->last_was_space = False;
7400
7401             /*
7402              * indicate that a string was saved for the current link
7403              */
7404             my_struct->save_blank = False;
7405
7406             /*
7407              * null the temp buffer.
7408              */
7409             string[0] = '\0';
7410           }
7411
7412       } while (reason > 0);
7413
7414     MyFree(string);
7415     return 0;
7416
7417 } /* End Cdata */
7418
7419 /******************************************************************************
7420  * Function:    int ProcessEnterAttr (
7421  *                                      FormatStruct my_struct,
7422  *                                      int cur_element, exceptions);
7423  *
7424  * Parameters:
7425  *
7426  * Returns:     0 if successful, -1 if errors
7427  *
7428  * Purpose:
7429  *
7430  ******************************************************************************/
7431 static  int
7432 ProcessEnterAttr(
7433     FormatStruct        *my_struct,
7434     SDLMask             *cur_element,
7435     enum SdlElement      sig_element,
7436     SDLMask             *exceptions,
7437     SDLMask             *process_mask)
7438 {
7439     /*
7440      * save the enter string as part of this element's segment list
7441      */
7442     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_ENTER) &&
7443         ((int)strlen(ElEnter(my_struct))) > 0 &&
7444         MySaveString(&(my_struct->seg_list), my_struct, ElEnter(my_struct),
7445                         my_struct->cur_link, my_struct->mb_len, False) != 0)
7446             return -1;
7447
7448     return 0;
7449
7450 } /* End ProcessEnterAttr */
7451
7452 /******************************************************************************
7453  * Function:    int ProcessExitAttr (
7454  *                                      FormatStruct my_struct,
7455  *                                      int cur_element, exceptions);
7456  *
7457  * Parameters:
7458  *
7459  * Returns:     0 if successful, -1 if errors
7460  *
7461  * Purpose:
7462  *
7463  ******************************************************************************/
7464 static  int
7465 ProcessExitAttr(
7466     FormatStruct        *my_struct,
7467     SDLMask             *cur_element,
7468     enum SdlElement      sig_element,
7469     SDLMask             *exceptions,
7470     SDLMask             *process_mask)
7471 {
7472     /*
7473      * save the exit string as part of this element's segment list
7474      */
7475     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_EXIT) &&
7476         ((int)strlen(ElExit(my_struct))) > 0 &&
7477         MySaveString(&(my_struct->seg_list), my_struct, ElExit(my_struct),
7478                         my_struct->cur_link, my_struct->mb_len, False) != 0)
7479             return -1;
7480
7481     return 0;
7482
7483 } /* End ProcessExitAttr */
7484
7485 /******************************************************************************
7486  * Function:    int FakeEnd (FormatStruct my_struct,
7487  *                                      int cur_element, exceptions);
7488  *
7489  * Parameters:
7490  *
7491  * Returns:     0 if successful, -1 if errors
7492  *
7493  * Purpose:     Looks for the virtual page attributes.
7494  *
7495  ******************************************************************************/
7496 static  int
7497 FakeEnd(
7498     FormatStruct        *my_struct,
7499     SDLMask             *cur_element,
7500     enum SdlElement      sig_element,
7501     SDLMask             *exceptions,
7502     SDLMask             *process_mask)
7503 {
7504
7505     my_struct->end_flag  = True;
7506     my_struct->faked_end = True;
7507     MaskToValue(cur_element, my_struct->parsed);
7508
7509     return 0;
7510
7511 } /* End FakeEnd */
7512
7513 /******************************************************************************
7514  * Function:    int AddRowToTable (FormatStruct my_struct,
7515  *                                      int cur_element, exceptions);
7516  *
7517  * Parameters:
7518  *
7519  * Returns:     0 if successful, -1 if errors
7520  *
7521  * Purpose:     Looks for the virtual page attributes.
7522  *
7523  ******************************************************************************/
7524 static  int
7525 AddRowToTable(
7526     FormatStruct        *my_struct,
7527     SDLMask             *cur_element,
7528     enum SdlElement      sig_element,
7529     SDLMask             *exceptions,
7530     SDLMask             *process_mask)
7531 {
7532     if (SDLSearchMask(process_mask, SdlElementFrowvec) != False)
7533       {
7534         ElTableCellIds(my_struct) = (char **) _DtCvAddPtrToArray(
7535                                         (void **) ElTableCellIds(my_struct),
7536                                         ElTableCellId(my_struct));
7537
7538         if (NULL == ElTableCellIds(my_struct))
7539             return -1;
7540
7541         ClearAttrFlag(my_struct->el_info, SDL_ATTR_CELLS);
7542       }
7543
7544     return 0;
7545
7546 } /* End AddRowToTable */
7547
7548 /******************************************************************************
7549  * Function:    int SaveLangCharSet (
7550  *                                      FormatStruct my_struct,
7551  *                                      int cur_element, exceptions);
7552  *
7553  * Parameters:
7554  *
7555  * Returns:     0 if successful, -1 if errors
7556  *
7557  * Purpose:     Looks for the virtual page attributes.
7558  *
7559  ******************************************************************************/
7560 static  int
7561 SaveLangCharSet(
7562     FormatStruct        *my_struct,
7563     SDLMask             *cur_element,
7564     enum SdlElement      sig_element,
7565     SDLMask             *exceptions,
7566     SDLMask             *process_mask)
7567 {
7568     char **info;
7569
7570     if (SDLSearchMask(process_mask, SdlElementText) == False ||
7571         !(SDLIsAttrSet(my_struct->el_info, SDL_ATTR_LANGUAGE) ||
7572                 SDLIsAttrSet(my_struct->el_info, SDL_ATTR_CHARSET)))
7573         return 0;
7574
7575     info = (char **) calloc (2, sizeof(char *));
7576     if (NULL == info)
7577         return -1;
7578
7579     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_LANGUAGE))
7580         info[0] = ElLanguage(my_struct);
7581     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_CHARSET))
7582         info[1] = ElCharSet(my_struct);
7583
7584     ClearAttrFlag(my_struct->el_info, SDL_ATTR_LANGUAGE);
7585     ClearAttrFlag(my_struct->el_info, SDL_ATTR_CHARSET);
7586
7587     _SdlSegLangChar(my_struct->add_seg) = (void *) info;
7588     return 0;
7589
7590 } /* End SaveLangCharSet */
7591
7592 /******************************************************************************
7593  * Function:    int CopyDocInfo (FormatStruct my_struct,
7594  *                                      int cur_element, exceptions);
7595  *
7596  * Parameters:
7597  *
7598  * Returns:     0 if successful, -1 if errors
7599  *
7600  * Purpose:     Looks for the virtual page attributes.
7601  *
7602  ******************************************************************************/
7603 static  int
7604 CopyDocInfo(
7605     FormatStruct        *my_struct,
7606     SDLMask             *cur_element,
7607     enum SdlElement      sig_element,
7608     SDLMask             *exceptions,
7609     SDLMask             *process_mask)
7610 {
7611     SDLDocInfo *docInfo;
7612
7613     if (SDLSearchMask(process_mask, SdlElementSdlDoc) == False)
7614         return 0;
7615
7616     docInfo = (SDLDocInfo *) malloc (sizeof(SDLDocInfo));
7617     if (NULL == docInfo)
7618         return -1;
7619
7620     *(docInfo) = ElDocInfo(my_struct);
7621     _SdlDocInfoPtrLanguage(docInfo) = strdup(ElLanguage(my_struct));
7622     _SdlDocInfoPtrCharSet(docInfo)  = strdup(ElCharSet(my_struct));
7623
7624     ClearAttrFlag(my_struct->el_info, SDL_ATTR_DOCID);
7625     ClearAttrFlag(my_struct->el_info, SDL_ATTR_SDLDTD);
7626     ClearAttrFlag(my_struct->el_info, SDL_ATTR_TIMESTAMP);
7627     ClearAttrFlag(my_struct->el_info, SDL_ATTR_FRST_PG);
7628     ClearAttrFlag(my_struct->el_info, SDL_ATTR_VERSION);
7629
7630     FrmtPrivInfoPtr(my_struct->add_seg)->doc_info = (void *) docInfo;
7631     return 0;
7632
7633 } /* End CopyDocInfo */
7634
7635 /******************************************************************************
7636  * Function:    int CopyAnchorId (FormatStruct my_struct,
7637  *                                      int cur_element, exceptions);
7638  *
7639  * Parameters:
7640  *
7641  * Returns:     0 if successful, -1 if errors
7642  *
7643  * Purpose:     Looks for the virtual page attributes.
7644  *
7645  ******************************************************************************/
7646 static  int
7647 CopyAnchorId(
7648     FormatStruct        *my_struct,
7649     SDLMask             *cur_element,
7650     enum SdlElement      sig_element,
7651     SDLMask             *exceptions,
7652     SDLMask             *process_mask)
7653 {
7654      _DtCvSegment        *mySeg = my_struct->add_seg;
7655
7656     /*
7657      * if we're not suppose to process this, skip.
7658      */
7659     if (SDLSearchMask(process_mask, SdlElementAnchor) == False)
7660         return 0;
7661
7662     /*
7663      * copy the id.
7664      */
7665     _DtCvIdOfMarkerSeg(mySeg) = ElId(my_struct);
7666
7667     /*
7668      * clear the flag so that it don't get freed.
7669      */
7670     ClearAttrFlag(my_struct->el_info, SDL_ATTR_ID);
7671
7672     return 0;
7673
7674 } /* End CopyDocInfo */
7675
7676 /******************************************************************************
7677  * Function:    int LoadGraphic (
7678  *                                      FormatStruct my_struct,
7679  *                                      int cur_element, exceptions);
7680  *
7681  * Parameters:
7682  *
7683  * Returns:     0 if successful, -1 if errors
7684  *
7685  * Purpose:     Looks for the virtual page attributes.
7686  *
7687  ******************************************************************************/
7688 static  int
7689 LoadGraphic(
7690     FormatStruct        *my_struct,
7691     SDLMask             *cur_element,
7692     enum SdlElement      sig_element,
7693     SDLMask             *exceptions,
7694     SDLMask             *process_mask)
7695 {
7696     int result = 0;
7697
7698     if (SDLSearchMask(process_mask, SdlElementGraphic) != False)
7699       {
7700         /*
7701          * get my container segment.
7702          */
7703         _DtCvSegment        *mySeg = my_struct->add_seg;
7704         _DtCvSegment        *cvRegion;  /* Canvas Engine Region */
7705
7706         result = -1;
7707
7708         /*
7709          * allocate a Canvas Engine region.
7710          */
7711         if (_DtHelpCeAllocSegment(1, NULL, NULL, &cvRegion) == 0)
7712           {
7713             /*
7714              * got memory for a region, now fill out the information.
7715              *
7716              * even if the load fails, we should just throw away
7717              * the graphic and continue.
7718              */
7719             result = 0;
7720             if (NULL != my_struct->ui_info->load_graphic &&
7721                 (*(my_struct->ui_info->load_graphic))(
7722                                 my_struct->ui_info->client_data,
7723                                 my_struct->vol_name,
7724                                 my_struct->id_string,
7725                                 ElSnbXid(my_struct),
7726                                 ElSnbFormat(my_struct),
7727                                 ElSnbMethod(my_struct),
7728                                 &(_DtCvWidthOfRegionSeg(cvRegion)),
7729                                 &(_DtCvHeightOfRegionSeg(cvRegion)),
7730                                 &(_DtCvInfoOfRegionSeg(cvRegion))) == 0)
7731               {
7732                 /*
7733                  * set the type on the region! And its ascent!
7734                  */
7735                 cvRegion->type = _DtCvSetTypeToRegion(cvRegion->type);
7736                 _DtCvAscentOfRegionSeg(cvRegion) = -1;
7737
7738                 /*
7739                  * set the seg list for the wrapper container.
7740                  */
7741                 _DtCvContainerListOfSeg(mySeg) = cvRegion;
7742
7743                 /*
7744                  * indicate the link has been fixed up
7745                  */
7746                 my_struct->save_blank = True;
7747               }
7748             else
7749               {
7750                 /*
7751                  * problems loading the graphic. Clean up!
7752                  */
7753                 MyFree(cvRegion);
7754               }
7755           }
7756       }
7757     return result;
7758
7759 } /* End LoadGraphic */
7760
7761 /******************************************************************************
7762  * Function:    int ColInfoToTableInfo (
7763  *                                      FormatStruct my_struct,
7764  *                                      int cur_element, exceptions);
7765  *
7766  * Parameters:
7767  *
7768  * Returns:     0 if successful, -1 if errors
7769  *
7770  * Purpose:     Looks for the virtual page attributes.
7771  *
7772  ******************************************************************************/
7773 static  int
7774 ColInfoToTableInfo(
7775     FormatStruct        *my_struct,
7776     SDLMask             *cur_element,
7777     enum SdlElement      sig_element,
7778     SDLMask             *exceptions,
7779     SDLMask             *process_mask)
7780 {
7781     if (SDLSearchMask(process_mask, SdlElementForm) != False)
7782       {
7783         int            i;
7784         int            mySize = ElTableColNum(my_struct);
7785         const char    *next;
7786         const char    *start     = NULL;
7787         const char    *last      = NULL;
7788         char         **colWidths = NULL;
7789         _DtCvFrmtOption  *colJust;
7790
7791         colWidths = (char **) malloc (sizeof(char *) * mySize);
7792         colJust   = (_DtCvFrmtOption *) malloc (sizeof(_DtCvFrmtOption)*mySize);
7793
7794         if (NULL == colWidths || NULL == colJust)
7795           {
7796             MyFree(colWidths);
7797             MyFree(colJust);
7798             return -1;
7799           }
7800
7801          /*
7802           * now process the column width specification.
7803           */
7804         next = ElTableColWStr(my_struct);
7805         if (NULL == next || '\0' == *next)
7806             next = "1";
7807
7808         for (i = 0; i < mySize; i++)
7809           {
7810             /* skip the leading spaces */
7811             while (' ' == *next) next++;
7812
7813             /* if the string really moved */
7814             if (last != next)
7815                 start = next;
7816
7817             /* go to the end of this specification */
7818             while (' ' != *next && '\0' != *next) next++;
7819
7820             /* duplicate the specification */
7821             colWidths[i] = strdup(start);
7822             if (NULL == colWidths[i])
7823                 return -1;
7824
7825             /* mark the end of the string */
7826             last = next;
7827           }
7828
7829          /*
7830           * now process the column justify specification.
7831           */
7832         next = ElTableColJStr(my_struct);
7833         if (NULL == next || '\0' == *next)
7834             next = NullOption;
7835
7836         for (i = 0; i < mySize; i++)
7837           {
7838             /* skip the leading spaces */
7839             while (' ' == *next) next++;
7840
7841             /* if the string really moved */
7842             if (last != next)
7843                 start = next;
7844
7845             /* go to the end of this specification */
7846             while (' ' != *next && '\0' != *next) next++;
7847
7848             /* determine the justification */
7849             switch (*start)
7850               {
7851                 case 'r':
7852                 case 'R': colJust[i] = _DtCvJUSTIFY_RIGHT;
7853                           break;
7854                 case 'c':
7855                 case 'C': colJust[i] = _DtCvJUSTIFY_CENTER;
7856                           break;
7857                 case 'd':
7858                 case 'D': colJust[i] = _DtCvJUSTIFY_NUM;
7859                           break;
7860                 case 'l':
7861                 case 'L': colJust[i] = _DtCvJUSTIFY_LEFT;
7862                           break;
7863
7864                 default : colJust[i] = _DtCvJUSTIFY_LEFT;
7865                           if (NullOption == start)
7866                               colJust[i] = _DtCvINHERIT;
7867                           break;
7868               }
7869
7870             /* mark the end of the string */
7871             last = next;
7872           }
7873
7874         ElTableColWidths(my_struct) = colWidths;
7875         ElTableColJust(my_struct)   = colJust;
7876       }
7877
7878     return 0;
7879
7880 } /* End ColInfoToTableInfo */
7881
7882 /******************************************************************************
7883  * Function:    int CopyIdInfo (FormatStruct my_struct,
7884  *                                      int cur_element, exceptions);
7885  *
7886  * Parameters:
7887  *
7888  * Returns:     0 if successful, -1 if errors
7889  *
7890  * Purpose:     Looks for the virtual page attributes.
7891  *
7892  ******************************************************************************/
7893 static  int
7894 CopyIdInfo(
7895     FormatStruct        *my_struct,
7896     SDLMask             *cur_element,
7897     enum SdlElement      sig_element,
7898     SDLMask             *exceptions,
7899     SDLMask             *process_mask)
7900 {
7901     SDLIdInfo *idInfo;
7902
7903     if (SDLSearchMask(process_mask, SdlElementId) == False)
7904         return 0;
7905
7906     idInfo = (SDLIdInfo *) malloc (sizeof(SDLIdInfo));
7907     if (NULL == idInfo)
7908         return -1;
7909
7910     *(idInfo) = ElIdInfo(my_struct);
7911     _SdlIdInfoPtrType(idInfo)   = ElFrmtType(my_struct);
7912     _SdlIdInfoPtrOffset(idInfo) = ElOffset(my_struct);
7913     _SdlIdInfoPtrRlevel(idInfo) = ElLevel(my_struct);
7914     _SdlIdInfoPtrRssi(idInfo)   = ElSsi(my_struct);
7915
7916     ClearAttrFlag(my_struct->el_info, SDL_ATTR_RID);
7917     ClearAttrFlag(my_struct->el_info, SDL_ATTR_RSSI);
7918
7919     FrmtPrivInfoPtr(my_struct->add_seg)->id_info = (void *) idInfo;
7920     return 0;
7921
7922 } /* End CopyIdInfo */
7923
7924 /******************************************************************************
7925  * Function:    int RegisterSnbLink (FormatStruct my_struct,
7926  *                                      int cur_element, exceptions);
7927  *
7928  * Parameters:
7929  *
7930  * Returns:     0 if successful, -1 if errors
7931  *
7932  * Purpose:     Looks for the virtual page attributes.
7933  *
7934  ******************************************************************************/
7935 static  int
7936 RegisterSnbLink(
7937     FormatStruct        *my_struct,
7938     SDLMask             *cur_element,
7939     enum SdlElement      sig_element,
7940     SDLMask             *exceptions,
7941     SDLMask             *process_mask)
7942 {
7943     int   linkType;
7944     int   len = 0;
7945     char  buffer[64];
7946     char *fileSpec = NULL;
7947
7948     if (SDLSearchMask(process_mask, ElType(my_struct)) == False)
7949         return 0;
7950
7951     fileSpec = ElSnbXid(my_struct);
7952
7953     switch (ElType(my_struct))
7954       {
7955         case SdlElementCrossDoc:
7956                         linkType = _DtCvLinkType_CrossLink;
7957                         break;
7958
7959         case SdlElementManPage:
7960                         linkType = _DtCvLinkType_ManPage;
7961                         break;
7962
7963         case SdlElementTextFile:
7964                         if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_OFFSET))
7965                           {
7966                             sprintf(buffer, " %d", ElOffset(my_struct));
7967                             len += strlen(buffer);
7968                           }
7969                         if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_FORMAT))
7970                             len += strlen(ElSnbFormat(my_struct));
7971
7972                         /*
7973                          * create a new file spec for the link
7974                          */
7975                         if (0 < len)
7976                           {
7977                             len += strlen(ElSnbXid(my_struct) + 1);
7978
7979                             fileSpec = malloc(sizeof(char) * len);
7980                             if (NULL == fileSpec)
7981                                 return -1;
7982                         
7983                             strcpy(fileSpec, ElSnbXid(my_struct));
7984                             strcat(fileSpec, buffer);
7985                             strcat(fileSpec, ElSnbFormat(my_struct));
7986                           }
7987                         linkType = _DtCvLinkType_TextFile;
7988                         break;
7989
7990         case SdlElementSysCmd:
7991                         linkType = _DtCvLinkType_Execute;
7992                         break;
7993
7994         case SdlElementCallback:
7995                         linkType = _DtCvLinkType_AppDefine;
7996                         break;
7997
7998         default: return -1;
7999       }
8000
8001     if (0 > _DtLinkDbAddLink(my_struct->my_links,
8002                                 _DtCvContainerIdOfSeg(my_struct->add_seg),
8003                                 fileSpec,
8004                                 linkType,
8005                                 _DtCvWindowHint_Original,
8006                                 NULL))
8007         return -1;
8008
8009     if (fileSpec != ElSnbXid(my_struct))
8010         free(fileSpec);
8011
8012     return 0;
8013
8014 } /* End RegisterSnbLink */
8015
8016 /******************************************************************************
8017  * Function:    int RegisterSwitch (FormatStruct my_struct,
8018  *                                      int cur_element, exceptions);
8019  *
8020  * Parameters:
8021  *
8022  * Returns:     0 if successful, -1 if errors
8023  *
8024  * Purpose:     Looks for the virtual page attributes.
8025  *
8026  ******************************************************************************/
8027 static  int
8028 RegisterSwitch(
8029     FormatStruct        *my_struct,
8030     SDLMask             *cur_element,
8031     enum SdlElement      sig_element,
8032     SDLMask             *exceptions,
8033     SDLMask             *process_mask)
8034 {
8035     int          result = -1;
8036     char        *interpStr;
8037
8038     if (SDLSearchMask(process_mask, ElType(my_struct)) == False)
8039         return 0;
8040
8041     interpStr = GetInterpCmd(ElInterp(my_struct));
8042     if (NULL != interpStr)
8043         interpStr = strdup(interpStr);
8044
8045     if (NULL != interpStr)
8046       {
8047         if (0 == _DtLinkDbAddSwitch(my_struct->my_links,
8048                         _DtCvContainerIdOfSeg(my_struct->add_seg),
8049                         interpStr,
8050                         _DtCvStringOfStringSeg(my_struct->add_seg),
8051                         ElSwitchBranches(my_struct)))
8052             result = 0;
8053
8054         free(my_struct->add_seg);
8055         my_struct->add_seg = NULL;
8056       }
8057
8058     return result;
8059
8060 } /* End RegisterSwitch */
8061
8062 /******************************************************************************
8063  * Function:    int ResolveSpcInfo (FormatStruct my_struct,
8064  *                                      int cur_element, exceptions);
8065  *
8066  * Parameters:
8067  *
8068  * Returns:     0 if successful, -1 if errors
8069  *
8070  * Purpose:     Looks for the virtual page attributes.
8071  *
8072  ******************************************************************************/
8073 static  int
8074 ResolveSpcInfo(
8075     FormatStruct        *my_struct,
8076     SDLMask             *cur_element,
8077     enum SdlElement      sig_element,
8078     SDLMask             *exceptions,
8079     SDLMask             *process_mask)
8080 {
8081     _DtCvSegment  *mySeg = my_struct->add_seg;
8082
8083     if (SDLSearchMask(process_mask, ElType(my_struct)) != False)
8084       {
8085         /*
8086          * set the non break character flag so that the layout routines
8087          * will only wrap this to the next line if there is a space
8088          * before it.
8089          *
8090          * Also set the inline flag so that the layout routines don't
8091          * think that the region is a figure.
8092          */
8093         mySeg->type = _DtCvSetTypeToNonBreak(mySeg->type);
8094         mySeg->type = _DtCvSetTypeToInLine(mySeg->type);
8095
8096         /*
8097          * now establish the proper display linking.
8098          */
8099         if (my_struct->prev_data != NULL)
8100             my_struct->prev_data->next_disp = mySeg;
8101
8102         my_struct->prev_data  = mySeg;
8103         my_struct->save_blank = False;
8104
8105         /*
8106          * resolve the font hints.
8107          */
8108         if (_SdlFontModeResolve == my_struct->resolve_font)
8109             (*(my_struct->ui_info->resolve_spc))(
8110                         my_struct->ui_info->client_data,
8111                         ElLanguage(my_struct),
8112                         ElCharSet(my_struct),
8113                         *(my_struct->my_fonts),
8114                         ElSpcName(my_struct),
8115                         &(_DtCvInfoOfRegionSeg(my_struct->add_seg)),
8116                         &(_DtCvWidthOfRegionSeg(my_struct->add_seg)),
8117                         &(_DtCvHeightOfRegionSeg(my_struct->add_seg)),
8118                         &(_DtCvAscentOfRegionSeg(my_struct->add_seg)));
8119         else
8120           {
8121             _DtHelpDARegion *pReg;
8122             _DtHelpDASpcInfo *spcInfo;
8123
8124             /*
8125              * malloc a structure to hold the spc
8126              */
8127             pReg = (_DtHelpDARegion *) malloc (sizeof(_DtHelpDARegion));
8128             if (NULL == pReg)
8129                 return -1;
8130             
8131             /*
8132              * malloc the structure to hold the information needed to
8133              * create the spc later.
8134              */
8135             spcInfo = (_DtHelpDASpcInfo *) calloc (1, sizeof(_DtHelpDASpcInfo));
8136             if (NULL == spcInfo)
8137               {
8138                 free(pReg);
8139                 return -1;
8140               }
8141
8142             /*
8143              * remember the spc's name and fonts
8144              */
8145             spcInfo->name = ElSpcName(my_struct);
8146             if (_SdlFontModeSave == my_struct->resolve_font)
8147               {
8148                 spcInfo->spc_fonts = *(my_struct->my_fonts);
8149                 _DtHelpFontHintsLang(spcInfo->spc_fonts) =
8150                                                         ElLanguage(my_struct);
8151                 _DtHelpFontHintsCharSet(spcInfo->spc_fonts) =
8152                                                         ElCharSet(my_struct);
8153
8154                 if (-1 == _DtHelpDupFontHints(&(spcInfo->spc_fonts)))
8155                     return -1;
8156               }
8157
8158             /*
8159              * remember the spc's name
8160              */
8161             pReg->inited = False;
8162             pReg->type   = _DtHelpDASpc;
8163             pReg->handle = (_DtCvPointer) spcInfo;
8164
8165             _DtCvInfoOfRegionSeg(mySeg) = (_DtCvPointer) pReg;
8166             ClearAttrFlag(my_struct->el_info, SDL_ATTR_NAME);
8167           }
8168
8169       }
8170
8171     return 0;
8172
8173 } /* End ResolveSpcInfo */
8174
8175 /******************************************************************************
8176  * Function:    int CopyTossInfo (FormatStruct my_struct,
8177  *                                      int cur_element, exceptions);
8178  *
8179  * Parameters:
8180  *
8181  * Returns:     0 if successful, -1 if errors
8182  *
8183  * Purpose:     Looks for the virtual page attributes.
8184  *
8185  ******************************************************************************/
8186 static  int
8187 CopyTossInfo(
8188     FormatStruct        *my_struct,
8189     SDLMask             *cur_element,
8190     enum SdlElement      sig_element,
8191     SDLMask             *exceptions,
8192     SDLMask             *process_mask)
8193 {
8194     SDLTossInfo *tossInfo;
8195
8196     if (SDLSearchMask(process_mask, ElType(my_struct)) == False)
8197         return 0;
8198
8199     tossInfo = (SDLTossInfo *) malloc (sizeof(SDLTossInfo));
8200     if (NULL == tossInfo)
8201         return -1;
8202
8203     /*
8204      * save the flags
8205      */
8206     _SdlTossInfoPtrFlag1(tossInfo)     = ElFlag1(my_struct);
8207     _SdlTossInfoPtrFlag2(tossInfo)     = ElFlag2(my_struct);
8208     _SdlTossInfoPtrFlag3(tossInfo)     = ElFlag3(my_struct);
8209     _SdlTossInfoPtrFlag4(tossInfo)     = ElFlag4(my_struct);
8210
8211     /*
8212      * save the match data - level, ssi and class/clan.
8213      */
8214     _SdlTossInfoPtrRlevel(tossInfo)    = ElLevel(my_struct);
8215     _SdlTossInfoPtrSsi(tossInfo)       = ElSsi(my_struct);
8216     _SdlTossInfoPtrClan(tossInfo)      = ElClan(my_struct);
8217
8218     /*
8219      * save the table information (colj, colw) or the keystyle
8220      * enter/exit data.
8221      */
8222     _SdlTossInfoPtrStr1(tossInfo)      = ElString1(my_struct);
8223     _SdlTossInfoPtrStr2(tossInfo)      = ElString2(my_struct);
8224
8225     /*
8226      * save the element type.
8227      */
8228     _SdlTossInfoPtrType(tossInfo)      = ElType(my_struct);
8229
8230     /*
8231      * save the fonts - even if this toss style doesn't specify fonts.
8232      */
8233     _SdlTossInfoPtrFontSpecs(tossInfo) = *(my_struct->my_fonts);
8234
8235     /*
8236      * now clear string attributes
8237      */
8238     ClearAttrFlag(my_struct->el_info, SDL_ATTR_SSI);
8239
8240     /*
8241      * table specs.
8242      */
8243     ClearAttrFlag(my_struct->el_info, SDL_ATTR_COLW);
8244     ClearAttrFlag(my_struct->el_info, SDL_ATTR_COLJ);
8245
8246     /*
8247      * key style specs.
8248      */
8249     ClearAttrFlag(my_struct->el_info, SDL_ATTR_ENTER);
8250     ClearAttrFlag(my_struct->el_info, SDL_ATTR_EXIT);
8251
8252     /*
8253      * font specs
8254      */
8255     ClearAttrFlag(my_struct->el_info, SDL_ATTR_COLOR);
8256     ClearAttrFlag(my_struct->el_info, SDL_ATTR_XLFD);
8257     ClearAttrFlag(my_struct->el_info, SDL_ATTR_XLFDI);
8258     ClearAttrFlag(my_struct->el_info, SDL_ATTR_XLFDB);
8259     ClearAttrFlag(my_struct->el_info, SDL_ATTR_XLFDIB);
8260     ClearAttrFlag(my_struct->el_info, SDL_ATTR_TYPENAM);
8261     ClearAttrFlag(my_struct->el_info, SDL_ATTR_TYPENAMI);
8262     ClearAttrFlag(my_struct->el_info, SDL_ATTR_TYPENAMB);
8263     ClearAttrFlag(my_struct->el_info, SDL_ATTR_TYPENAMIB);
8264
8265     /*
8266      * set the internal pointer
8267      */
8268     _SdlSegTossInfo(my_struct->add_seg) = (void *) tossInfo;
8269
8270     /*
8271      * now re-initialize the font specifications back to the original
8272      * values
8273      */
8274     *(my_struct->my_fonts) = DefFontInfo;
8275
8276     return 0;
8277
8278 } /* End CopyTossInfo */
8279
8280 /******************************************************************************
8281  * Function:    int CopyEntryInfo (FormatStruct my_struct,
8282  *                                      int cur_element, exceptions);
8283  *
8284  * Parameters:
8285  *
8286  * Returns:     0 if successful, -1 if errors
8287  *
8288  * Purpose:     Looks for the virtual page attributes.
8289  *
8290  ******************************************************************************/
8291 static  int
8292 CopyEntryInfo(
8293     FormatStruct        *my_struct,
8294     SDLMask             *cur_element,
8295     enum SdlElement      sig_element,
8296     SDLMask             *exceptions,
8297     SDLMask             *process_mask)
8298 {
8299     SDLEntryInfo *entryInfo;
8300
8301     if (SDLSearchMask(process_mask, ElType(my_struct)) == False)
8302         return 0;
8303
8304     entryInfo = (SDLEntryInfo *) malloc (sizeof(SDLEntryInfo));
8305     if (NULL == entryInfo)
8306         return -1;
8307
8308     /*
8309      * save the strings.
8310      */
8311     *entryInfo = ElEntryInfo(my_struct);
8312
8313     /*
8314      * now clear the attributes
8315      */
8316     ClearAttrFlag(my_struct->el_info, SDL_ATTR_MAIN);
8317     ClearAttrFlag(my_struct->el_info, SDL_ATTR_LOCS);
8318     ClearAttrFlag(my_struct->el_info, SDL_ATTR_SYNS);
8319     ClearAttrFlag(my_struct->el_info, SDL_ATTR_SORT);
8320
8321     /*
8322      * set the internal pointer
8323      */
8324     _SdlSegEntryInfo(my_struct->add_seg) = (void *) entryInfo;
8325
8326     return 0;
8327
8328 } /* End CopyEntryInfo */
8329
8330 /******************************************************************************
8331  * Function:    int InitLast (FormatStruct my_struct,
8332  *                                      int cur_element, exceptions);
8333  *
8334  * Parameters:
8335  *
8336  * Returns:     0 if successful, -1 if errors
8337  *
8338  * Purpose:     Looks for the virtual page attributes.
8339  *
8340  ******************************************************************************/
8341 static  int
8342 InitLast(
8343     FormatStruct        *my_struct,
8344     SDLMask             *cur_element,
8345     enum SdlElement      sig_element,
8346     SDLMask             *exceptions,
8347     SDLMask             *process_mask)
8348 {
8349     /*
8350      * set the parsing flags
8351      */
8352     my_struct->last_was_space = True;
8353     my_struct->last_was_mb    = False;
8354     my_struct->last_was_nl    = False;
8355
8356     /*
8357      * set the container type correctly.
8358      */
8359     if (NULL != my_struct->add_seg &&
8360         (SdlTypeLiteral == ElFrmtType(my_struct) ||
8361                                         SdlTypeLined == ElFrmtType(my_struct)))
8362         _DtCvContainerTypeOfSeg(my_struct->add_seg) = _DtCvLITERAL;
8363
8364     return 0;
8365
8366 } /* End InitLast */
8367
8368 /******************************************************************************
8369  * Function:    int SetTransit (FormatStruct my_struct,
8370  *                                      int cur_element, exceptions);
8371  *
8372  * Parameters:
8373  *
8374  * Returns:     0 if successful, -1 if errors
8375  *
8376  * Purpose:     Looks for the virtual page attributes.
8377  *
8378  ******************************************************************************/
8379 static  int
8380 SetTransit(
8381     FormatStruct        *my_struct,
8382     SDLMask             *cur_element,
8383     enum SdlElement      sig_element,
8384     SDLMask             *exceptions,
8385     SDLMask             *process_mask)
8386 {
8387     if (ElTiming(my_struct) == SdlTimingAsync)
8388         my_struct->resolve_font = _SdlFontModeNone;
8389
8390     return 0;
8391
8392 } /* End SetTransit */
8393
8394 \f
8395 /******************************************************************************
8396  *
8397  * Main Parsing Functions
8398  *
8399  *****************************************************************************/
8400 /******************************************************************************
8401  * Function:    int ParseSDL (FormatStruct my_struct,
8402  *                              int cur_element, int cur_execpt);
8403  *
8404  * Parameters:
8405  *
8406  * Returns:     0 if successful, -1 if errors
8407  *
8408  * Purpose:     Parses a set of rules.
8409  *
8410  ******************************************************************************/
8411 static  int
8412 ParseSDL(
8413     FormatStruct        *my_struct,
8414     enum SdlElement      cur_element,
8415     enum SdlElement      sig_element,
8416     SDLMask             *cur_except,
8417     SDLMask             *process_mask)
8418 {
8419     int    i = 0;
8420     int    result  = 0;
8421     int    oldLink = my_struct->cur_link;
8422     enum SdlElement      oldElType   = ElType(my_struct);
8423     _DtCvSegment        *oldCurSeg   = my_struct->last_seg;
8424     _DtCvSegment        *oldSeglist  = my_struct->seg_list;
8425     _DtCvSegment        *oldAddSeg   = my_struct->add_seg;
8426     _DtCvSegment        *ifPrevData  = my_struct->prev_data;
8427     _SdlFontMode         saveFontMode = my_struct->resolve_font;
8428     ElementInfo          saveElInfo  = my_struct->el_info;
8429     _DtHelpFontHints    *oldFontInfo = my_struct->my_fonts;
8430     const SDLContent    *content;
8431     _DtCvContainer      *activeFrmt = my_struct->active_frmt;
8432     SDLMask              oldMask[SDL_MASK_LEN];
8433     SDLMask              oldExcept[SDL_MASK_LEN];
8434     _DtCvValue           oldBlank    = my_struct->save_blank;
8435     _DtCvValue           processFlag =
8436                                 SDLSearchMask(process_mask, SdlElementCdata);
8437
8438     /*
8439      * While this element is allowed normally in the content of
8440      * the parent element, it it currently allowed?
8441      */
8442     if (SDLSearchMask(cur_except, cur_element) == True)
8443         return -1;
8444
8445     /*
8446      * special processing for CDATA elements
8447      */
8448     if (cur_element != SdlElementCdata)
8449       {
8450         my_struct->seg_list = NULL;
8451         my_struct->last_seg = NULL;
8452         my_struct->add_seg  = NULL;
8453       }
8454
8455     /*
8456      * look in the master list for this element
8457      */
8458     while (i < MaxSDLElements && SdlElementList[i].sdl_element != cur_element)
8459         i++;
8460
8461     /*
8462      * Didn't find this element in the master list.
8463      */
8464     if (i >= MaxSDLElements)
8465         return -1;
8466
8467     /*
8468      * merge this element's exceptions with parent's list.
8469      * save the old process mask.
8470      */
8471     SaveRestoreMask(oldExcept, cur_except);
8472     MergeMasks(cur_except, SdlElementList[i].exceptions);
8473     SaveRestoreMask(oldMask, process_mask);
8474
8475     /*
8476      * the content for this element is...
8477      */
8478     content = SdlElementList[i].content;
8479
8480     /*
8481      * check to see if we want to process this element
8482      * If sig_element is set, parse the element and its content.
8483      */
8484     if (sig_element != SdlElementNone)
8485       {
8486         processFlag = False;
8487         if (sig_element == cur_element)
8488           {
8489             processFlag  = True;
8490             sig_element  = SdlElementNone;
8491             SaveRestoreMask(process_mask, AllMaskSet);
8492           }
8493       }
8494
8495     /*
8496      * If not CDATA, then have to get the element start string, attributes
8497      * and ending markup tag.
8498      */
8499     if (cur_element != SdlElementCdata)
8500       {
8501         if (ParseElementStart(my_struct,SdlElementList[i],processFlag) != 0
8502                                 ||
8503                 ParseElementAttr(my_struct,
8504                                         cur_element,
8505                                         SdlElementList[i].attrib_list,
8506                                         SdlElementList[i].cdata_flag,
8507                                         processFlag) != 0)
8508             result = -1;
8509       }
8510
8511     /*
8512      * now parse the element's content
8513      */
8514     my_struct->faked_end = False;
8515     ElType(my_struct) = cur_element;
8516     while (result == 0 && content != NULL &&
8517                         SDLSearchMask(content->mask, SdlElementNone) == False)
8518       {
8519         result = (*(content->model))(my_struct, content->mask,
8520                                         sig_element, cur_except, process_mask);
8521         content++;
8522       }
8523
8524     /*
8525      * If not CDATA, get the element end markup and adjust some pointers
8526      */
8527     SaveRestoreMask(process_mask, oldMask);
8528     SaveRestoreMask(cur_except  , oldExcept);
8529     if (cur_element != SdlElementCdata)
8530       {
8531         if (result == 0 && SdlElementList[i].element_end_str != NULL)
8532             result = ParseElementEnd(my_struct, ifPrevData,
8533                                                         SdlElementList[i],
8534                                                         processFlag,
8535                                                         my_struct->faked_end);
8536         else
8537           {
8538             /*
8539              * free the attributes for this element.
8540              */
8541             FreeAttributes(ElType(my_struct),
8542                                 &(my_struct->el_info), my_struct->my_fonts);
8543
8544             if (SdlElementList[i].new_fonts && FreeFontInfo(my_struct) == -1)
8545                 result = -1;
8546           }
8547
8548
8549         my_struct->last_seg = oldCurSeg;
8550         my_struct->seg_list = oldSeglist;
8551
8552         if (result == 0 && my_struct->add_seg != NULL)
8553             _DtHelpCeAddSegToList(my_struct->add_seg, &(my_struct->seg_list),
8554                                                 &(my_struct->last_seg));
8555
8556         my_struct->add_seg   = oldAddSeg;
8557         my_struct->cur_link  = oldLink;
8558         if (SdlElementLink == cur_element)
8559             my_struct->save_blank = oldBlank;
8560
8561         my_struct->el_info  = saveElInfo;
8562         my_struct->my_fonts = oldFontInfo;
8563       }
8564
8565     my_struct->active_frmt  = activeFrmt;
8566     my_struct->resolve_font = saveFontMode;
8567     ElType(my_struct) = oldElType;
8568     return result;
8569
8570 } /* End ParseSDL */
8571
8572 /******************************************************************************
8573  * Function:    int ProcessSDLMarkup (FormatStruct my_struct,
8574  *                              int cur_element, int cur_execpt);
8575  *
8576  * Parameters:
8577  *
8578  * Returns:     0 if successful, -1 if errors
8579  *
8580  * Purpose:     Parses a set of rules, looks through the result and changes
8581  *              bad options into good.
8582  *
8583  ******************************************************************************/
8584 static  int
8585 ProcessSDLMarkup(
8586     FormatStruct        *my_struct,
8587     enum SdlElement      cur_element,
8588     enum SdlElement      sig_element,
8589     SDLMask             *cur_except,
8590     SDLMask             *process_mask)
8591 {
8592     int result = ParseSDL (my_struct, cur_element, sig_element, cur_except,
8593                                                                 process_mask);
8594
8595     if (-1 != result)
8596         PropagateJustification(my_struct->seg_list, _DtCvJUSTIFY_LEFT);
8597
8598     return result;
8599 }
8600
8601 /******************************************************************************
8602  * Function:    int ProcessContent (
8603  *                              FormatStruct *my_struct,
8604  *                              const SDLContent *content,
8605  *                              SDLMask *exceptions,
8606  *                              SDLMask *process_mask);
8607  *
8608  * Parameters:
8609  *              my_struct       Specifies specific informationg for this parse.
8610  *              content         Specifies the content model to parse.
8611  *              exceptions      Specifies the current elements excepted
8612  *                              from being in the current content.
8613  *              process_mask    Specifies which elements to save in memory.
8614  *
8615  * Returns:     0 if successful, -1 if errors
8616  *
8617  * Purpose:
8618  ******************************************************************************/
8619 static int
8620 ProcessContent(
8621     FormatStruct        *my_struct,
8622     const SDLContent    *content,
8623     enum SdlElement      sig_element,
8624     SDLMask             *exceptions,
8625     SDLMask             *process_mask)
8626 {
8627     int   result = 0;
8628
8629     while (result == 0 && content != NULL &&
8630                         SDLSearchMask(content->mask, SdlElementNone) == False)
8631       {
8632         result = (*(content->model))(my_struct, content->mask,
8633                                         sig_element, exceptions, process_mask);
8634         content++;
8635       }
8636
8637     if (-1 != result)
8638         PropagateJustification(my_struct->seg_list, _DtCvJUSTIFY_LEFT);
8639
8640     return result;
8641 }
8642
8643 /******************************************************************************
8644  * Function:    int SearchForController (_DtCvSegment p_seg, 
8645  *
8646  * Parameters:
8647  *
8648  * Returns:     0 if successful, -1 if errors
8649  *
8650  * Purpose:     Parses a set of rules.
8651  *
8652  ******************************************************************************/
8653 static  _DtCvSegment *
8654 SearchForController(
8655     _DtCvSegment                *p_seg)
8656 {
8657     while (NULL != p_seg &&
8658                 !(_DtCvIsSegContainer(p_seg) && _DtCvIsSegController(p_seg)))
8659         p_seg = _DtCvNextSeg(p_seg);
8660
8661     return p_seg;
8662
8663 } /* End SearchForController */
8664
8665 /******************************************************************************
8666  * Function:    int FormatSDLTitle (
8667  *
8668  * Parameters:
8669  *
8670  * Returns:     0 if successful, -1 if errors
8671  *
8672  * Purpose:     Parses a set of rules.
8673  *
8674  ******************************************************************************/
8675 static  int
8676 FormatSDLTitle(
8677     char                *filename,
8678     int                  offset,
8679     int                  fd,
8680     FormatStruct        *my_struct)
8681 {
8682     int         result = 0;
8683     SDLMask      processMask[SDL_MASK_LEN] = SDLSetAllBits;
8684 /*
8685     SDLMask     processMask[SDL_MASK_LEN] = SDLInitMaskEleven( \
8686                                 SdlElementTitle  , SdlElementHead   , \
8687                                 SdlElementKey    , SdlElementSphrase, \
8688                                 SdlElementRev    , SdlElementIf     , \
8689                                 SdlElementSpc    , SdlElementAnchor , \
8690                                 SdlElementLink   , SdlElementSnRef  , \
8691                                 SdlElementCdata);
8692 */
8693
8694     SDLMask     startExcept[SDL_MASK_LEN] = SDLInitMask(SdlElementNone);
8695
8696     /*
8697      * set the volume name for the graphics.
8698      */
8699     my_struct->vol_name = filename;
8700
8701     /*
8702      * can we seek to the correct place?
8703      */
8704     result = _DtHelpCeFileOpenAndSeek(filename, offset, fd,
8705                                         &(my_struct->my_file), NULL);
8706     if (result != -1)
8707       {
8708         result = ProcessSDLMarkup (my_struct, SdlElementTitle, SdlElementNone,
8709                                     startExcept, processMask);
8710         _DtHelpCeBufFileClose (my_struct->my_file, (fd == -1 ? True : False));
8711       }
8712
8713     return result;
8714
8715 } /* End FormatSDLTitle */
8716
8717 /******************************************************************************
8718  * Function:    void SetGhostLink (
8719  *
8720  * Parameters:
8721  *
8722  * Returns:
8723  *
8724  * Purpose:
8725  *
8726  ******************************************************************************/
8727 static  int
8728 SetGhostLink(
8729     _DtCvLinkDb          link_data,
8730     _DtCvSegment        *segments,
8731     int                  link_idx)
8732 {
8733     while (segments != NULL)
8734       {
8735         if (!(_DtCvIsSegContainer(segments)))
8736           {
8737             if (_DtCvIsSegHyperText(segments))
8738               {
8739                 _DtLinkDbRemoveLink(link_data, segments->link_idx);
8740                 segments->type = ClearSegLinks(segments);
8741               }
8742
8743             segments->type   = _DtCvSetTypeToGhostLink(segments->type);
8744             segments->link_idx = link_idx;
8745           }
8746         else /* if (_DtCvIsSegContainer(segments)) */
8747             SetGhostLink (link_data, _DtCvContainerListOfSeg(segments),
8748                                                                 link_idx);
8749         segments = _DtCvNextSeg(segments);
8750       }
8751
8752 } /* End SetGhostLink */
8753
8754 /******************************************************************************
8755  * Function:    void CreateAsciiString ()
8756  *
8757  * Parameters:
8758  *
8759  * Returns:
8760  *
8761  * Purpose:
8762  *
8763  ******************************************************************************/
8764 static  void
8765 CreateAsciiString(
8766     _DtCvSegment         *p_seg,
8767     _DtCvSegment         *snb,
8768     _DtCvValue           *nl_flag,
8769     char                **ret_string)
8770 {
8771     int          newLen;
8772     int          len;
8773
8774     while (p_seg != NULL)
8775       {
8776         len = 1;
8777         if (_DtCvIsSegString(p_seg))
8778           {
8779             if (*nl_flag == True)
8780               {
8781                 if (*ret_string != NULL &&
8782                                     (*ret_string)[strlen(*ret_string)-1] != ' ')
8783                   len++;
8784                 else
8785                   *nl_flag = False;
8786               }
8787
8788             newLen = _DtCvStrLen(_DtCvStringOfStringSeg(p_seg),
8789                                                 _DtCvIsSegWideChar(p_seg));
8790             if (_DtCvIsSegWideChar(p_seg))
8791                 newLen = newLen * MB_CUR_MAX;
8792
8793             len += newLen;
8794
8795             if (*ret_string == NULL)
8796               {
8797                 *ret_string  = (char *) malloc (len);
8798                 **ret_string = '\0';
8799               }
8800             else
8801               {
8802                 len += strlen(*ret_string);
8803                 *ret_string = (char *) realloc (*ret_string, len);
8804               }
8805
8806             if (*nl_flag == True)
8807                 strcat(*ret_string, " ");
8808
8809             /*
8810              * back up to the insertion point.
8811              */
8812             len -= newLen;
8813             len--;
8814
8815             /*
8816              * wide char or single byte?
8817              */
8818             if (_DtCvIsSegWideChar(p_seg))
8819                 wcstombs(&((*ret_string)[len]),
8820                                 (wchar_t *) _DtCvStringOfStringSeg(p_seg),
8821                                 newLen + 1);
8822             else
8823                 strcpy (&((*ret_string)[len]), _DtCvStringOfStringSeg(p_seg));
8824
8825             *nl_flag = False;
8826             if (p_seg->next_disp == NULL)
8827                 *nl_flag = True;
8828           }
8829         else if (_DtCvIsSegContainer(p_seg) && !(_DtCvIsSegController(p_seg)))
8830             CreateAsciiString(_DtCvContainerListOfSeg(p_seg),
8831                                         snb, nl_flag, ret_string);
8832
8833         p_seg = _DtCvNextSeg(p_seg);
8834       }
8835 }
8836
8837 /******************************************************************************
8838  * Function:    void CreateAsciiAbbrev ()
8839  *
8840  * Parameters:
8841  *
8842  * Returns:
8843  *
8844  * Purpose:
8845  *
8846  ******************************************************************************/
8847 static  void
8848 CreateAsciiAbbrev(
8849     _DtCvSegment         *p_el,
8850     char                **ret_abbrev)
8851 {
8852   *ret_abbrev = NULL;
8853   if (NULL != AbbrevOfSeg(p_el) && strlen ((char *) AbbrevOfSeg(p_el)))
8854         *ret_abbrev = strdup((char *) AbbrevOfSeg(p_el));
8855 }
8856
8857 /******************************************************************************
8858  * Function:    void CleanUpToc ()
8859  *
8860  * Parameters:
8861  *              my_struct       Specifies current formatting information.
8862  *              p_seg           Specifies the current segment list to modify.
8863  *              level           Specifes the parent element's level.
8864  *              lnk_indx        Specifies the link index to use for the
8865  *                              ghost link.
8866  *
8867  * Returns:     nothing
8868  *
8869  * Purpose:     Modifies the formatting information for conform to what
8870  *              it should be for a TOC and sets the ghost link.
8871  *
8872  ******************************************************************************/
8873 static  void
8874 CleanUpToc(
8875     FormatStruct        *my_struct,
8876     _DtCvSegment                *p_seg,
8877     int                  level,
8878     _DtCvValue           target)
8879 {
8880     level--;
8881     if (level < 0)
8882         level = 0;
8883
8884     while (p_seg != NULL)
8885       {
8886         if (_DtCvIsSegNewLine(p_seg))
8887             p_seg->type = p_seg->type & ~(_DtCvNEW_LINE);
8888
8889         if (_DtCvIsSegContainer(p_seg))
8890           {
8891             _DtCvContainerPercentOfSeg(p_seg)   = DefPercent;
8892             _DtCvContainerOrientOfSeg(p_seg)    = _DtCvJUSTIFY_LEFT_MARGIN;
8893             _DtCvContainerFlowOfSeg(p_seg)      = _DtCvWRAP_NONE;
8894             _DtCvContainerTypeOfSeg(p_seg)      = _DtCvLITERAL;
8895             _DtCvContainerVJustifyOfSeg(p_seg)  = _DtCvJUSTIFY_TOP;
8896             _DtCvContainerJustifyOfSeg(p_seg)   = _DtCvJUSTIFY_LEFT;
8897             _DtCvContainerFMarginOfSeg(p_seg)   = 0;
8898             _DtCvContainerLMarginOfSeg(p_seg)   =
8899                                 level * 2 * my_struct->ui_info->avg_char;
8900             _DtCvContainerRMarginOfSeg(p_seg)   = 0;
8901             _DtCvContainerTMarginOfSeg(p_seg)   = 0;
8902             _DtCvContainerBMarginOfSeg(p_seg)   = 0;
8903
8904             CleanUpToc(my_struct, _DtCvContainerListOfSeg(p_seg),
8905                                                         level, target);
8906           }
8907         else if (_DtCvIsSegString(p_seg))
8908           {
8909             _DtHelpFontHints *font_specs = (_DtHelpFontHints *)_DtCvFontOfStringSeg(p_seg);
8910
8911             _DtHelpFontPtrPtSize(font_specs) = 10;
8912             _DtHelpFontPtrWeight(font_specs) = _DtHelpFontWeightMedium;
8913
8914             if (target == True)
8915                 _DtHelpFontPtrWeight(font_specs) = _DtHelpFontWeightBold;
8916
8917             (my_struct->ui_info->load_font)(my_struct->ui_info->client_data,
8918                                 _DtHelpFontHintsLang(*font_specs),
8919                                 _DtHelpFontHintsCharSet(*font_specs),
8920                                 *font_specs,
8921                                 &(_DtCvFontOfStringSeg(p_seg)));
8922             free(font_specs);
8923           }
8924         else if (_DtCvIsSegRegion(p_seg))
8925           {
8926             int              result;
8927             _DtHelpDARegion *pReg = (_DtHelpDARegion *) _DtCvInfoOfRegionSeg(p_seg);
8928
8929             if (_DtHelpDASpc == pReg->type)
8930               {
8931                 _DtHelpDASpcInfo *pSpc = (_DtHelpDASpcInfo *) pReg->handle;
8932
8933                 _DtHelpFontHintsPtSize(pSpc->spc_fonts) = 10;
8934                 _DtHelpFontHintsWeight(pSpc->spc_fonts) =
8935                                                         _DtHelpFontWeightMedium;
8936
8937                 if (True == target)
8938                     _DtHelpFontHintsWeight(pSpc->spc_fonts) =
8939                                                         _DtHelpFontWeightBold;
8940
8941                 result = (*(my_struct->ui_info->resolve_spc))(
8942                                 my_struct->ui_info->client_data,
8943                                 _DtHelpFontHintsLang(pSpc->spc_fonts),
8944                                 _DtHelpFontHintsCharSet(pSpc->spc_fonts),
8945                                 pSpc->spc_fonts,
8946                                 pSpc->name,
8947                                 &(_DtCvInfoOfRegionSeg(p_seg)),
8948                                 &(_DtCvWidthOfRegionSeg(p_seg)),
8949                                 &(_DtCvHeightOfRegionSeg(p_seg)),
8950                                 &(_DtCvAscentOfRegionSeg(p_seg)));
8951                 if (0 != result)
8952                     p_seg->type = _DtCvSetTypeToNoop(p_seg->type);
8953
8954                 free(pSpc->name);
8955                 _DtHelpFreeFontHints(&(pSpc->spc_fonts));
8956
8957                 free(pSpc);
8958                 free(pReg);
8959               }
8960           }
8961
8962         p_seg = _DtCvNextSeg(p_seg);
8963       }
8964 }
8965
8966 /******************************************************************************
8967  * Function:    int AddEntryToToc ()
8968  *
8969  * Parameters:
8970  *
8971  * Returns:
8972  *
8973  * Purpose:
8974  *
8975  ******************************************************************************/
8976 static  int
8977 AddEntryToToc(
8978     FormatStruct        *my_struct,
8979     _DtHelpVolumeHdl     volume,
8980     int                  fd,
8981     int                  level,
8982     char                *lang,
8983     const char          *char_set,
8984     _DtCvSegment        *toss,
8985     _DtCvSegment        *info_seg,
8986     _DtCvValue           target,
8987     _DtCvSegment        **ret_snb,
8988     _DtCvSegment        **seg_list,
8989     _DtCvSegment        **prev_list)
8990 {
8991     int         result = 0;
8992     _DtCvLinkDb saveLinks;
8993     SDLIdInfo   *info;
8994
8995     /*
8996      * initialize the structure
8997      * save some information that's going to be destroyed in the setup.
8998      */
8999     saveLinks    = my_struct->my_links;
9000
9001     if (SetUp(NULL,NULL,my_struct,toss,my_struct->ui_info,fd,False,False) != 0)
9002         return -1;
9003
9004     /*
9005      * Initialize the standard/default to use
9006      */
9007     _DtHelpFontHintsLang(*(my_struct->my_fonts))    = lang;
9008     _DtHelpFontHintsCharSet(*(my_struct->my_fonts)) = (char *) char_set;
9009
9010     /*
9011      * free the new link database and restore the old one.
9012      * set font mode to save and the id for graphics.
9013      */
9014     _DtLinkDbDestroy(my_struct->my_links);
9015     my_struct->my_links     = saveLinks;
9016     my_struct->resolve_font = _SdlFontModeSave;
9017
9018     info = FrmtPrivInfoPtr(info_seg)->id_info;
9019     result = FormatSDLTitle(_DtHelpCeGetVolumeName(volume),
9020                                 _SdlIdInfoPtrOffset(info), fd, my_struct);
9021     /*
9022      * if no errors, continue
9023      */
9024     if (result != -1)
9025       {
9026         _DtCvSegment *headEl  = NULL;
9027
9028         /*
9029          * find the actual head element
9030          */
9031         if (my_struct->seg_list != NULL)
9032             headEl = SearchForController(
9033                                 _DtCvContainerListOfSeg(my_struct->seg_list));
9034
9035         /*
9036          * If there isn't a head element, use the id.
9037          */
9038         if (headEl == NULL)
9039           {
9040             _DtCvSegment *addSeg = NULL;
9041
9042             if (MySaveString(&(addSeg), my_struct,
9043                                         _DtCvContainerIdOfSeg(info_seg),
9044                                         -1, my_struct->mb_len, False) != 0)
9045               {
9046                 /*
9047                  * free the segments
9048                  */
9049                 _DtHelpFreeSegments(my_struct->seg_list, _DtCvTRUE,
9050                                         my_struct->ui_info->destroy_region,
9051                                         my_struct->ui_info->client_data);
9052                 my_struct->seg_list = NULL;
9053                 DestroyFontInfo(my_struct);
9054                 return -1;
9055               }
9056
9057             /*
9058              * if there is a virpage, attach the segment to it.
9059              * I.e. just reuse the container.
9060              */
9061             if (NULL != my_struct->seg_list)
9062               {
9063                 /*
9064                  * free the container original list
9065                  */
9066                 _DtHelpFreeSegments(
9067                                 _DtCvContainerListOfSeg(my_struct->seg_list),
9068                                 _DtCvTRUE,
9069                                 my_struct->ui_info->destroy_region,
9070                                 my_struct->ui_info->client_data);
9071               }
9072                 else
9073                   {
9074                 /*
9075                  * create a container for the segment.
9076                  */
9077                 if (_DtHelpCeAllocSegment(my_struct->malloc_size,
9078                                 &(my_struct->alloc_size),
9079                                 &(my_struct->block_list),
9080                                 &(my_struct->seg_list)) != 0)
9081                   {
9082                     _DtHelpFreeSegments(addSeg, _DtCvTRUE,
9083                                 my_struct->ui_info->destroy_region,
9084                                 my_struct->ui_info->client_data);
9085                     DestroyFontInfo(my_struct);
9086                     return -1;
9087                   }
9088
9089                 /*
9090                  * set the container flag and initialize its formatting
9091                  * information to the default.
9092                  */
9093                 my_struct->seg_list->type =
9094                         _DtCvSetTypeToContainer(my_struct->seg_list->type);
9095                 _DtCvContainerOfSeg(my_struct->seg_list) = DefFrmtSpecs;
9096                 _DtCvContainerLeadingOfSeg(my_struct->seg_list) =
9097                                                 my_struct->ui_info->leading;
9098               }
9099
9100             _DtCvContainerListOfSeg(my_struct->seg_list) = addSeg;
9101             headEl  = my_struct->seg_list;
9102           }
9103
9104         /*
9105          * there was a empty head, use the abbreviation or the id.
9106          */
9107         else if (_DtCvContainerListOfSeg(headEl) == NULL)
9108           {
9109             char *myPtr = (char *) AbbrevOfSeg(headEl);
9110
9111             if (NULL == myPtr)
9112                 myPtr = _DtCvContainerIdOfSeg(info_seg);
9113
9114             if (MySaveString(&(_DtCvContainerListOfSeg(headEl)), my_struct,
9115                                 myPtr, -1, my_struct->mb_len, False) != 0)
9116               {
9117                 /*
9118                  * free the segments
9119                  */
9120                 _DtHelpFreeSegments(my_struct->seg_list, _DtCvTRUE,
9121                                         my_struct->ui_info->destroy_region,
9122                                         my_struct->ui_info->client_data);
9123                 my_struct->seg_list = NULL;
9124                 DestroyFontInfo(my_struct);
9125                 return -1;
9126               }
9127           }
9128
9129         /*
9130          * Make sure we only use the first head.
9131          * first make sure that the segment list is not the head already.
9132          */
9133         if (headEl != my_struct->seg_list)
9134           {
9135             _DtCvSegment *prevSeg;
9136
9137             /*
9138              * destroy the segments after this one.
9139              */
9140             _DtHelpFreeSegments(_DtCvNextSeg(headEl), _DtCvTRUE,
9141                                         my_struct->ui_info->destroy_region,
9142                                         my_struct->ui_info->client_data);
9143             /*
9144              * break the link to the freed segments
9145              */
9146             _DtCvNextSeg(headEl) = NULL;
9147
9148             /*
9149              * destroy the segments before this one.
9150              */
9151             prevSeg = _DtCvContainerListOfSeg(my_struct->seg_list);
9152             if (prevSeg != headEl)
9153               {
9154                 /*
9155                  * search for the previous segment before the head.
9156                  */
9157                 while (_DtCvNextSeg(prevSeg) != headEl)
9158                     prevSeg = _DtCvNextSeg(prevSeg);
9159
9160                 /*
9161                  * break the link to the head element
9162                  */
9163                 _DtCvNextSeg(prevSeg) = NULL;
9164               }
9165             else
9166                 _DtCvContainerListOfSeg(my_struct->seg_list) = NULL;
9167
9168             /*
9169              * free the segments before the head and virpage container.
9170              */
9171             _DtHelpFreeSegments(my_struct->seg_list, _DtCvTRUE,
9172                                         my_struct->ui_info->destroy_region,
9173                                         my_struct->ui_info->client_data);
9174             my_struct->seg_list = headEl;
9175           }
9176
9177         if (headEl != NULL)
9178           {
9179             int linkIndex = _DtLinkDbAddLink(my_struct->my_links, NULL,
9180                                 _DtCvContainerIdOfSeg(info_seg),
9181                                         _DtCvLinkType_SameVolume,
9182                                         _DtCvWindowHint_CurrentWindow, NULL);
9183
9184             CleanUpToc(my_struct, headEl, level, target);
9185             SetGhostLink(my_struct->my_links, headEl, linkIndex);
9186           }
9187       }
9188
9189     if (result != -1)
9190       {
9191         /*
9192          * now tack this segment onto the end of the list
9193          */
9194         if ((*seg_list) == NULL)
9195             (*seg_list) = my_struct->seg_list;
9196         else
9197             _DtCvNextSeg((*prev_list)) = my_struct->seg_list;
9198
9199         *prev_list = my_struct->seg_list;
9200         while ((*prev_list) != NULL && _DtCvNextSeg((*prev_list)) != NULL)
9201             *prev_list = _DtCvNextSeg((*prev_list));
9202       }
9203
9204     /*
9205      * if the snb for this topic was read, free it now.
9206      */
9207     if (my_struct->snb != NULL)
9208       {
9209         _DtHelpFreeSegments(my_struct->snb, _DtCvTRUE,
9210                                         my_struct->ui_info->destroy_region,
9211                                         my_struct->ui_info->client_data);
9212         my_struct->snb = NULL;
9213       }
9214
9215     /*
9216      * free the font structures allocated
9217      */
9218     DestroyFontInfo(my_struct);
9219
9220     return result;
9221 }
9222
9223 /******************************************************************************
9224  * Function:    int ExpandToc ()
9225  *
9226  * Parameters:
9227  *
9228  * Returns:
9229  *
9230  * Purpose:
9231  *
9232  ******************************************************************************/
9233 static  int
9234 ExpandToc(
9235     FormatStruct        *my_struct,
9236     _DtHelpVolumeHdl     volume,
9237     int                  fd,
9238     char                *lang,
9239     const char          *char_set,
9240     _DtCvSegment        *toss,
9241     int                  level,
9242     char                **path_list,
9243     _DtCvSegment        **id_seg,
9244     _DtCvSegment        **ret_snb,
9245     _DtCvSegment        **seg_list,
9246     _DtCvSegment        **prev_list)
9247 {
9248     int          result   = 0;
9249     int          segLev;
9250     int          tst      = 1;
9251     _DtCvSegment *pEl;
9252     _DtCvValue   done     = False;
9253     _DtCvValue   found    = False;
9254
9255     /*
9256      * skip anything that isn't a virpage and of the correct level.
9257      */
9258     while ((*id_seg) != NULL && _SdlSegToSdlIdInfoType(*id_seg) != SdlIdVirpage
9259                 && _SdlSegToSdlIdInfoLevel(*id_seg) != level)
9260         *id_seg = _DtCvNextSeg((*id_seg));
9261
9262     /*
9263      * process any virpage that has the correct level
9264      */
9265     while ((*id_seg) != NULL && done == False && result == 0)
9266       {
9267         pEl    = (*id_seg);
9268         segLev = _SdlSegToSdlIdInfoLevel(pEl);
9269
9270         if (_SdlSegToSdlIdInfoType(pEl) == SdlIdVirpage)
9271           {
9272             if (segLev == level)
9273               {
9274                 /*
9275                  * If the virpage in the path list has not been found,
9276                  * test the next virpage. Otherwise skip.
9277                  */
9278                 if (found == False && *path_list != NULL &&
9279                                         _DtCvContainerIdOfSeg(pEl) != NULL)
9280                     tst   = _DtCvStrCaseCmpLatin1(*path_list,
9281                                                 _DtCvContainerIdOfSeg(pEl));
9282                         
9283                 /*
9284                  * the only time tst == 0 is when the next item in the
9285                  * path_list matches this element. Check to see if the
9286                  * next item in the path_list is null. If so, that
9287                  * means this is the location the user has desired.
9288                  */
9289                 result = AddEntryToToc(my_struct, volume, fd,
9290                         segLev, lang, char_set, toss, pEl,
9291                         (tst == 0 && path_list[1] == NULL ? True : False),
9292                         ret_snb, seg_list, prev_list);
9293
9294                 /*
9295                  * increment the segment pointer to the next item
9296                  */
9297                 *id_seg = _DtCvNextSeg((*id_seg));
9298
9299                 /*
9300                  * The only time tst is zero is if the current virpage
9301                  * matches the next item in the list. Expand it's children.
9302                  * and set tst to non-zero so that AddEntryToToc does not
9303                  * special case the siblings following this one.
9304                  */
9305                 if (tst == 0)
9306                   {
9307                     result = ExpandToc(my_struct, volume, fd, lang,
9308                                         char_set, toss,
9309                                         segLev + 1,
9310                                         &path_list[1],
9311                                         id_seg, ret_snb, seg_list, prev_list);
9312                     found = True;
9313                     tst   = 1;
9314                   }
9315               }
9316             else if (segLev < level)
9317                 done = True;
9318             else
9319                 *id_seg = _DtCvNextSeg((*id_seg));
9320           }
9321         else
9322             *id_seg = _DtCvNextSeg((*id_seg));
9323       }
9324
9325     return result;
9326
9327 } /* ExpandToc */
9328
9329 /******************************************************************************
9330  * Function:    void CreateTitleChunks ()
9331  *
9332  * Parameters:
9333  *
9334  * Returns:
9335  *
9336  * Purpose:
9337  *
9338  ******************************************************************************/
9339 static  int
9340 CreateTitleChunks(
9341     _DtCvSegment          *toss,
9342     _DtCvSegment          *p_seg,
9343     _DtCvSegment          *snb,
9344     SDLMask               *stop_mask,
9345     const char            *lang,
9346     const char            *char_set,
9347     _DtCvValue          (*resolve_spc)(),
9348     _DtCvPointer          client_data,
9349     int                   *ret_cnt,
9350     void                ***ret_chunks)
9351 {
9352     int          type;
9353     int          cnt;
9354     int          result = 0;
9355     const char  *myLang;
9356     const char  *mySet;
9357     void        *ptr;
9358     _DtHelpDARegion     *daRegion;
9359
9360     while (result != -1 && p_seg != NULL)
9361       {
9362         myLang = lang;
9363         mySet  = char_set;
9364         cnt = *ret_cnt;
9365         if (_DtCvIsSegString(p_seg))
9366           {
9367             if (*ret_cnt == 0)
9368                 *ret_cnt = 1;
9369             else
9370                 cnt--;
9371
9372             *ret_cnt = *ret_cnt + 3;
9373             if (*ret_chunks == NULL)
9374                 *ret_chunks = (void **) malloc (sizeof(void *) * (*ret_cnt));
9375             else
9376                 *ret_chunks = (void **) realloc (*ret_chunks,
9377                                                 sizeof(void *) * (*ret_cnt));
9378             if (*ret_chunks == NULL)
9379                 return -1;
9380
9381             type = DT_HELP_CE_FONT_PTR | DT_HELP_CE_STRING;
9382             ptr  = _DtCvFontOfStringSeg(p_seg);
9383
9384             if (p_seg->next_disp == NULL || _DtCvIsSegNewLine(p_seg))
9385                 type |= DT_HELP_CE_NEWLINE;
9386
9387             (*ret_chunks)[cnt++] = (void *) type;
9388             (*ret_chunks)[cnt++] = (void *) ptr;
9389
9390             if (_DtCvIsSegWideChar(p_seg))
9391               {
9392                 int len = _DtCvStrLen(_DtCvStringOfStringSeg(p_seg), 1)
9393                                                         * MB_CUR_MAX + 1;
9394
9395                 ptr = malloc (sizeof(char *) * len);
9396                 if (NULL != ptr)
9397                     wcstombs((char *) ptr,
9398                                 (wchar_t *) _DtCvStringOfStringSeg(p_seg), len);
9399               }
9400             else
9401                 ptr = strdup(_DtCvStringOfStringSeg(p_seg));
9402
9403             (*ret_chunks)[cnt++] = (void *) ptr;
9404             if ((*ret_chunks)[cnt-1] == NULL)
9405                 return -1;
9406
9407             (*ret_chunks)[cnt++] = (void *) DT_HELP_CE_END;
9408           }
9409         else if (_DtCvIsSegRegion(p_seg))
9410           {
9411             daRegion = (_DtHelpDARegion *) _DtCvInfoOfRegionSeg(p_seg);
9412             if (_DtHelpDASpc == daRegion->type)
9413               {
9414                 if (False == daRegion->inited)
9415                   {
9416                     _DtHelpDASpcInfo *pSpc =
9417                                         (_DtHelpDASpcInfo *) daRegion->handle;
9418                     /*
9419                      * allocate the spc!
9420                      */
9421                     result = (*(resolve_spc))(
9422                                 client_data,
9423                                 _DtHelpFontHintsLang(pSpc->spc_fonts),
9424                                 _DtHelpFontHintsCharSet(pSpc->spc_fonts),
9425                                 pSpc->spc_fonts,
9426                                 pSpc->name,
9427                                 &(_DtCvInfoOfRegionSeg(p_seg)),
9428                                 &(_DtCvWidthOfRegionSeg(p_seg)),
9429                                 &(_DtCvHeightOfRegionSeg(p_seg)),
9430                                 &(_DtCvAscentOfRegionSeg(p_seg)));
9431
9432                     free(pSpc->name);
9433                     _DtHelpFreeFontHints(&(pSpc->spc_fonts));
9434
9435                     free(pSpc);
9436                     free(daRegion);
9437
9438                     if (0 != result)
9439                         return -1;
9440
9441                     daRegion = (_DtHelpDARegion *) _DtCvInfoOfRegionSeg(p_seg);
9442                   }
9443
9444                 if (*ret_cnt == 0)
9445                     *ret_cnt = 1;
9446                 else
9447                     cnt--;
9448
9449                 *ret_cnt = *ret_cnt + 2;
9450                 if (*ret_chunks == NULL)
9451                     *ret_chunks = (void **) malloc (sizeof(void *) * *ret_cnt);
9452                 else
9453                     *ret_chunks = (void **) realloc (*ret_chunks,
9454                                                 sizeof(void *) * *ret_cnt);
9455                 if (*ret_chunks == NULL)
9456                     return -1;
9457
9458                 type = DT_HELP_CE_SPC;
9459                 if (p_seg->next_disp == NULL || _DtCvIsSegNewLine(p_seg))
9460                     type |= DT_HELP_CE_NEWLINE;
9461
9462                 (*ret_chunks)[cnt++] = (void *) type;
9463                 (*ret_chunks)[cnt++] = (void *) daRegion->handle;
9464                 (*ret_chunks)[cnt++] = (void *) DT_HELP_CE_END;
9465               }
9466             result = 0;
9467           }
9468         else if (_DtCvIsSegContainer(p_seg) && !(_DtCvIsSegController(p_seg)))
9469             result = CreateTitleChunks(toss,
9470                                 _DtCvContainerListOfSeg(p_seg), snb,
9471                                 stop_mask,
9472                                 myLang, mySet,
9473                                 resolve_spc,
9474                                 client_data,
9475                                 ret_cnt, ret_chunks);
9476
9477         p_seg = _DtCvNextSeg(p_seg);
9478       }
9479
9480     return result;
9481 }
9482
9483 /******************************************************************************
9484  * Function:    int ProcessSegmentsToChunks ()
9485  *
9486  * Parameters:
9487  *
9488  * Returns:     0 if created a chunk, -1 if errors
9489  *
9490  * Purpose:
9491  *
9492  ******************************************************************************/
9493 static int
9494 ProcessSegmentsToChunks(
9495     _DtCvSegment          *toss,
9496     _DtCvSegment          *head_el,
9497     _DtCvSegment          *snb_el,
9498     SDLMask               *stop_mask,
9499     const char            *lang,
9500     const char            *char_set,
9501     _DtCvValue          (*resolve_spc)(),
9502     _DtCvPointer          client_data,
9503     void                ***ret_chunks)
9504 {
9505     int cnt    = 0;
9506     int result = 0;
9507
9508     result = CreateTitleChunks(toss, _DtCvContainerListOfSeg(head_el),
9509                                         snb_el, stop_mask, lang, char_set,
9510                                         resolve_spc, client_data,
9511                                         &cnt, ret_chunks);
9512     if ((result != 0 || cnt == 0) && NULL != AbbrevOfSeg(head_el)
9513                                 && strlen ((char *) AbbrevOfSeg(head_el)))
9514       {
9515         *ret_chunks   = (void **) malloc (sizeof(void *) * 4);
9516         if (*ret_chunks == NULL)
9517             return -1;
9518
9519         (*ret_chunks)[0] = (void *) DT_HELP_CE_CHARSET;
9520         (*ret_chunks)[1] = (void *) strdup(char_set);
9521         (*ret_chunks)[2] = (void *) strdup(AbbrevOfSeg(head_el));
9522         (*ret_chunks)[3] = (void *) DT_HELP_CE_END;
9523       }
9524
9525     return result;
9526 }
9527
9528 /******************************************************************************
9529  * Function:    _DtCvSegment *GetSdlDocSnb (
9530  *                              _DtHelpVolumeHdl    volume)
9531  * Parameters:
9532  *              volume          Specifies the volume.
9533  *
9534  * Returns:     0 if successful, -1 if errors
9535  *
9536  * Purpose:     If the title has been parsed and it used snrefs,
9537  *              this function will return the snb specified in the
9538  *              sdldoc element.
9539  ******************************************************************************/
9540 static _DtCvSegment *
9541 GetSdlDocSnb(
9542     _DtHelpVolumeHdl     volume)
9543 {
9544     _DtCvSegment        *retEl = NULL;
9545     CESDLVolume *sdlVol;
9546
9547     sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
9548     if (sdlVol != NULL && sdlVol->snb != NULL)
9549         retEl = (sdlVol->snb);
9550
9551     return retEl;
9552 }
9553
9554 /******************************************************************************
9555  * Function:    int GetDocumentTitle (
9556  *                              _DtHelpVolumeHdl    volume,
9557  *                              _DtCvValue        flag,
9558  *                              _DtCvSegment    **ret_seg)
9559  * Parameters:
9560  *              volume          Specifies the volume.
9561  *              flag            Specifies if the toss is needed.
9562  *              ret_seg         Returns sdlVol->title.
9563  *
9564  * Returns:     0 if successful, -1 if errors, -2 if there is no title.
9565  *
9566  * Purpose:     This will fill in the 'title' and 'snb' elements of
9567  *              the CESDLVolume structure and return 'title' in 'ret_seg'.
9568  ******************************************************************************/
9569 static int
9570 GetDocumentTitle(
9571     _DtHelpVolumeHdl     volume,
9572     _FrmtUiInfo         *ui_info,
9573     _SdlFontMode         mode,
9574     _DtCvValue           flag,
9575     _DtCvSegment        **ret_seg)
9576 {
9577     int                  result   = -1;
9578     short                procFlag = True;
9579     CESDLVolume         *sdlVol;
9580     FormatStruct         frmtStruct;
9581     _DtCvSegment                *toss = NULL;
9582     SDLMask              skipMask   [SDL_MASK_LEN] = SDLClearAllBits;
9583     SDLMask              processMask[SDL_MASK_LEN] = SDLSetAllBits;
9584     SDLMask              startExcept[SDL_MASK_LEN] =
9585                                         SDLInitMask(SdlElementNone);
9586
9587     sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
9588     if (sdlVol == NULL)
9589         return -1;
9590
9591     if (sdlVol->title_processed == False)
9592       {
9593         if (flag == True)
9594             toss = _DtHelpCeGetSdlVolToss(volume, -1);
9595
9596         if (SetUp(volume,NULL,&frmtStruct,toss,ui_info,-1,True,False) !=0 )
9597             return -1;
9598
9599         /*
9600          * now set up correct font mode.
9601          */
9602         frmtStruct.resolve_font = mode;
9603
9604         /*
9605          * now get the title.
9606          */
9607         if (_DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume), 0, -1,
9608                                         &(frmtStruct.my_file), NULL) != -1)
9609           {
9610             if (ProcessContent(&frmtStruct, SDLDocumentContent,
9611                                 SdlElementNone, startExcept, skipMask) != -1
9612                 && ProcessSDLMarkup(&frmtStruct, SdlElementVStruct,
9613                                 SdlElementNone, startExcept, skipMask) != -1
9614                 && ProcessContent(&frmtStruct, HeadAndSnb,
9615                                 SdlElementNone, startExcept, processMask) != -1)
9616               {
9617                 sdlVol->title       = frmtStruct.seg_list;
9618                 sdlVol->snb         = frmtStruct.snb;
9619                 sdlVol->client_data = ui_info->client_data;
9620                 sdlVol->destroy_region = ui_info->destroy_region;
9621                 result = 0;
9622
9623                 /*
9624                  * if the volume doesn't have a head, set the
9625                  * appropriate flags.
9626                  */
9627                 if (NULL == sdlVol->title)
9628                   {
9629                     procFlag = -1;      /* processed with no errors */
9630                     result   = -2;      /* but no title             */
9631                   }
9632               }
9633             else /* free the segments */
9634                 _DtHelpFreeSegments(frmtStruct.seg_list, _DtCvFALSE,
9635                                         ui_info->destroy_region,
9636                                         ui_info->client_data);
9637
9638             _DtHelpCeBufFileClose (frmtStruct.my_file, True);
9639           }
9640
9641         /*
9642          * free the font structures allocated
9643          */
9644         DestroyFontInfo(&frmtStruct);
9645
9646         /*
9647          * destroy the link database
9648          */
9649         _DtLinkDbDestroy(frmtStruct.my_links);
9650
9651         sdlVol->title_processed = procFlag;
9652       }
9653
9654     /*
9655      * if we have a title, good
9656      */
9657     else if (sdlVol->title != NULL)
9658         result = 0;
9659
9660     /*
9661      * we haven't processed a title. Is is because the volume
9662      * doesn't have one or because of problems accessing the volume?
9663      */
9664     else if (-1 == sdlVol->title_processed)
9665         result = -2;    /* volume doesn't have a title */
9666
9667     *ret_seg = sdlVol->title;
9668
9669     return result;
9670 }
9671
9672 /******************************************************************************
9673  *
9674  * Semi-Private Functions
9675  *
9676  *****************************************************************************/
9677 /******************************************************************************
9678  * Function:    SDLAttribute *_DtHelpCeGetSdlAttributeList(void)
9679  *
9680  * Parameters:
9681  *
9682  * Returns:     ptr or NULL;
9683  *
9684  * Purpose:
9685  ******************************************************************************/
9686 const SDLAttribute *
9687 _DtHelpCeGetSdlAttributeList(void)
9688 {
9689     const SDLAttribute *ptr = SDLAttributeList;
9690
9691     return ptr;
9692 }
9693
9694 /******************************************************************************
9695  *
9696  * Semi-Public Functions
9697  *
9698  *****************************************************************************/
9699 /******************************************************************************
9700  * Function:    int _DtHelpCeFrmtSDLPathAndChildren (
9701  *                              _DtHelpVolumeHdl volume, char *filename,
9702  *                              int offset, char *id_string,
9703  *                              _DtCvTopicPtr *ret_handle)
9704  *
9705  * Parameters:
9706  *              volume          Specifies the Help Volume the information
9707  *                              is associated with.
9708  *              filename        Specifies the file containing the Help Topic
9709  *                              desired.
9710  *              offset          Specifies the offset into 'filename' to
9711  *                              the Help Topic desired.
9712  *              id_string       Specifies the location id to look for or NULL.
9713  *              ret_handle      Returns a handle to the topic information
9714  *                              including the number of paragraphs and the
9715  *                              id match segment.
9716  *
9717  * Returns:     0 if successful, -1 if errors, 1 if the path is empty.
9718  *
9719  ******************************************************************************/
9720 int
9721 _DtHelpCeFrmtSdlPathAndChildren(
9722     _DtHelpVolumeHdl     volume,
9723     _FrmtUiInfo         *ui_info,
9724     int                  fd,
9725     char                *target_id,
9726     _DtCvTopicPtr       *ret_handle)
9727 {
9728     char                *lang;
9729     const char          *charSet;
9730     char                **topicMap;
9731     int                  result = 0;
9732     int                  pathCnt;
9733     FormatStruct         frmtStruct;
9734     _DtCvTopicInfo      *topicHandle;
9735     _DtCvSegment        *mySegList = NULL;
9736     _DtCvSegment        *myPrevSeg = NULL;
9737     _DtCvSegment        *loids;
9738     _DtCvSegment        *snb    = NULL;
9739     SDLIdInfo           *info;
9740
9741     *ret_handle = NULL;
9742
9743     /*
9744      * look for the heading for each virpage
9745      */
9746     frmtStruct         = DefFormatStruct;
9747     frmtStruct.ui_info = ui_info;
9748     frmtStruct.my_links = _DtLinkDbCreate();
9749     frmtStruct.vol_name = _DtHelpCeGetVolumeName(volume);
9750     frmtStruct.id_string = target_id;
9751
9752     /*
9753      * get the path from the target to the top.
9754      */
9755     pathCnt = _DtHelpCeGetSdlIdPath(volume, target_id, &topicMap);
9756     if (pathCnt == -1)
9757         return -1;
9758
9759     /*
9760      * get the beginning of the path
9761      */
9762     loids = _DtHelpCeMapSdlIdToSegment(volume, *topicMap, fd);
9763     if (loids == NULL)
9764       {
9765         _DtCvFreeArray((void **) topicMap);
9766         return -1;
9767       }
9768     
9769     /*
9770      * format the top topic entry.
9771      */
9772     info = FrmtPrivInfoPtr(loids)->id_info;
9773     if (_SdlIdInfoPtrRlevel(info) > 0)
9774       {
9775         /*
9776          * Put the top topic in the table of contents.
9777          */
9778         lang    = _DtHelpCeGetSdlVolLanguage(volume);
9779         charSet = _DtHelpCeGetSdlVolCharSet(volume);
9780         result  = AddEntryToToc(&frmtStruct, volume, fd,
9781                                 _SdlIdInfoPtrRlevel(info), lang, charSet,
9782                                 _DtHelpCeGetSdlVolToss(volume, fd),
9783                                 loids, (topicMap[1] == NULL ? True : False),
9784                                 &snb, &mySegList, &myPrevSeg);
9785         /*
9786          * format the children.
9787          */
9788         if (result != -1 && _DtCvNextSeg(loids) != NULL)
9789           {
9790             loids  = _DtCvNextSeg(loids);
9791             result = ExpandToc(&frmtStruct, volume, fd, lang, charSet,
9792                                 _DtHelpCeGetSdlVolToss(volume, fd),
9793                                 _SdlIdInfoPtrRlevel(info) + 1,
9794                                 &topicMap[1],
9795                                 &loids, &snb, &mySegList, &myPrevSeg);
9796           }
9797       }
9798
9799     if (result != -1)
9800       {
9801         topicHandle = (_DtCvTopicInfo *) malloc (sizeof(_DtCvTopicInfo));
9802         if (topicHandle != NULL)
9803           {
9804             topicHandle->id_str    = NULL;
9805             topicHandle->mark_list = NULL;
9806             topicHandle->link_data = frmtStruct.my_links;
9807
9808             topicHandle->seg_list  = (void *) mySegList;
9809
9810             /*
9811              * let the top level know that there isn't a path
9812              */
9813             if (NULL == mySegList)
9814                 result = 1;
9815
9816             *ret_handle = (void *) topicHandle;
9817           }
9818         else
9819             result = -1;
9820       }
9821
9822     _DtCvFreeArray((void **) topicMap);
9823     return result;
9824
9825 } /* End _DtHelpCeFrmtSDLPathAndChildren */
9826
9827 /******************************************************************************
9828  * Function:    int _DtHelpCeFrmtSdlVolumeInfo (char *filename,
9829  *                              _DtCvTopicPtr *ret_handle)
9830  *
9831  * Parameters:
9832  *              filename        Specifies the file containing the Help Topic
9833  *                              desired.
9834  *              ret_handle      Returns a handle to the topic information
9835  *                              including the number of paragraphs and the
9836  *                              id match segment.
9837  *
9838  * Returns:     0 if successful, -1 if errors
9839  *
9840  * Purpose:     _DtHelpCeFrmtSdlVolumeInfo processes the SDL volume looking
9841  *              for the generated items.
9842  *
9843  ******************************************************************************/
9844 int
9845 _DtHelpCeFrmtSdlVolumeInfo(
9846     char                *filename,
9847     _DtHelpVolumeHdl     volume,
9848     time_t              *ret_time)
9849 {
9850     int                  result = 0;
9851     char                *numPtr;
9852     CESDLVolume         *sdlVol;
9853     FormatStruct         frmtStruct;
9854     SDLMask              processMask[SDL_MASK_LEN] = SDLSetAllBits;
9855     SDLMask              startExcept[SDL_MASK_LEN] =
9856                                         SDLInitMask(SdlElementNone);
9857
9858     if (SetUp(volume,&sdlVol,&frmtStruct,NULL,&DefUiInfo,-1,True,False) != 0)
9859         return -1;
9860
9861     /*
9862      * now set up correct font mode.
9863      */
9864     frmtStruct.resolve_font = _SdlFontModeNone;
9865
9866     if (result == 0)
9867       {
9868         result = _DtHelpCeFileOpenAndSeek(filename, 0, -1,
9869                                         &(frmtStruct.my_file), ret_time);
9870         if (result != -1)
9871           {
9872             result = ProcessContent(&frmtStruct, SDLDocumentContent,
9873                                 SdlElementNone, startExcept, processMask);
9874
9875             _DtHelpCeBufFileClose (frmtStruct.my_file, True);
9876
9877             if (frmtStruct.remember != NULL)
9878                 free(frmtStruct.remember);
9879           }
9880     
9881         if (result != -1)
9882           {
9883             /*
9884              * attach the information to this volume.
9885              */
9886             sdlVol->sdl_info = (SDLDocInfo *)
9887                         FrmtPrivInfoPtr(frmtStruct.seg_list)->doc_info;
9888
9889             /*
9890              * check the major and minor numbers.
9891              */
9892             numPtr = _SdlDocInfoPtrSdlDtd(sdlVol->sdl_info);
9893
9894             while (*numPtr < '0' || *numPtr > '9')
9895                 numPtr++;
9896
9897             if (atoi(numPtr) != SDL_DTD_VERSION)
9898                 result = -1;
9899             else
9900               {
9901                 while (*numPtr != '.' && *numPtr != '\0')
9902                     numPtr++;
9903
9904                 if (*numPtr == '.')
9905                     numPtr++;
9906
9907                 sdlVol->minor_no = atoi(numPtr);
9908               }
9909
9910             /*
9911              * free the container
9912              */
9913             FrmtPrivInfoPtr(frmtStruct.seg_list)->doc_info = NULL;
9914             _DtHelpFreeSegments(frmtStruct.seg_list, _DtCvFALSE, NULL, NULL);
9915           }
9916       }
9917
9918     _DtLinkDbDestroy(frmtStruct.my_links);
9919
9920     /*
9921      * free the font structures allocated
9922      */
9923     DestroyFontInfo(&frmtStruct);
9924
9925     return result;
9926 }
9927
9928 /******************************************************************************
9929  * Function:    int _DtHelpCeFrmtSDLTitleToAscii (
9930  *                              char *filename,
9931  *                              int offset,
9932  *                              char **ret_title, char **ret_abbrev)
9933  *
9934  * Parameters:
9935  *
9936  * Returns:     0 if successful, -1 if errors
9937  *
9938  * Purpose:
9939  ******************************************************************************/
9940 int
9941 _DtHelpCeFrmtSDLTitleToAscii(
9942     _DtHelpVolumeHdl        volume,
9943     int          offset,
9944     char        **ret_title,
9945     char        **ret_abbrev)
9946 {
9947     int                  result = 0;
9948     FormatStruct         frmtStruct;
9949
9950     if (SetUp(volume,NULL,&frmtStruct,NULL,&DefUiInfo,-1,True,False) != 0)
9951         return -1;
9952
9953     *ret_title = NULL;
9954     if (ret_abbrev != NULL)
9955         *ret_abbrev = NULL;
9956
9957     /*
9958      * now set up correct font mode.
9959      */
9960     frmtStruct.resolve_font = _SdlFontModeNone;
9961
9962     /*
9963      * get the title.
9964      */
9965     result = FormatSDLTitle(frmtStruct.vol_name, offset, -1, &frmtStruct);
9966
9967     if (result != -1 && frmtStruct.seg_list != NULL)
9968       {
9969         _DtCvSegment  *pHeadSeg;
9970         _DtCvValue   nlFlag = False;
9971
9972         pHeadSeg = _DtCvContainerListOfSeg(frmtStruct.seg_list);
9973
9974         if (pHeadSeg != NULL)
9975           {
9976             CreateAsciiString(_DtCvContainerListOfSeg(pHeadSeg),
9977                                 frmtStruct.snb, &nlFlag, ret_title);
9978             CreateAsciiAbbrev(pHeadSeg, ret_abbrev);
9979           }
9980         else
9981             result = -1;
9982       }
9983     else
9984         result = -1;
9985
9986     if (frmtStruct.seg_list != NULL)
9987         _DtHelpFreeSegments(frmtStruct.seg_list, _DtCvFALSE, NULL, NULL);
9988
9989     /*
9990      * free the font structures allocated
9991      */
9992     DestroyFontInfo(&frmtStruct);
9993
9994     return result;
9995
9996 } /* End _DtHelpCeFrmtSDLTitleToAscii */
9997
9998 /******************************************************************************
9999  * Function:    char *_DtHelpCeFrmtSdlVolumeAbstractToAscii(
10000  *                                                      _DtHelpVolumeHdl volume)
10001  *
10002  * Parameters:
10003  *              volume          Specifies the Help Volume the information
10004  *                              is associated with.
10005  *
10006  * Returns:     0 if successful, -1 if errors
10007  *
10008  * Purpose:     _DtHelpCeFrmtSdlVolumeAbstractToAscii formats Help Files
10009  *              with formatting information into a CEVirtualPage
10010  *
10011  ******************************************************************************/
10012 char *
10013 _DtHelpCeFrmtSdlVolumeAbstractToAscii(
10014     _DtHelpVolumeHdl        volume)
10015 {
10016     int                  offset;
10017     char                *abstr = NULL;
10018     _DtCvSegment        *pSeg;
10019     _DtCvSegment        *pSnb;
10020     _DtCvValue           nlFlag = False;
10021     _DtHelpCeLockInfo    lockInfo;
10022
10023     if (_DtHelpCeLockVolume(volume, &lockInfo) != 0)
10024         return NULL;
10025
10026     if (_DtHelpCeFindSdlId(volume,"_abstract",lockInfo.fd,NULL,&offset) == True)
10027       {
10028         int     result = 0;
10029         SDLMask startExcept[SDL_MASK_LEN] = SDLInitMask(SdlElementNone);
10030         SDLMask processMask[SDL_MASK_LEN] = SDLSetAllBits;
10031         FormatStruct     frmtStruct;
10032         CESDLVolume     *sdlVol;
10033
10034         if (SetUp(volume, &sdlVol, &frmtStruct, NULL, &DefUiInfo,
10035                                         lockInfo.fd, True, False) != 0)
10036             return NULL;
10037
10038         /*
10039          * now set up correct font mode.
10040          */
10041         frmtStruct.resolve_font = _SdlFontModeNone;
10042
10043         /*
10044          * open the volume and seek to the virpage
10045          */
10046         result = _DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume),
10047                                         offset, lockInfo.fd,
10048                                         &(frmtStruct.my_file), NULL);
10049         if (result != -1)
10050           {
10051             result = ProcessSDLMarkup (&frmtStruct, SdlElementVirpage,
10052                                 SdlElementNone, startExcept, processMask);
10053             _DtHelpCeBufFileClose (frmtStruct.my_file,
10054                                         (lockInfo.fd == -1 ? True : False));
10055           }
10056
10057         if (result != -1)
10058           {
10059             pSeg = frmtStruct.seg_list;
10060             pSnb = frmtStruct.snb;
10061
10062             CreateAsciiString(pSeg, pSnb, &nlFlag, &abstr);
10063
10064             _DtHelpFreeSegments(frmtStruct.seg_list, _DtCvFALSE, NULL, NULL);
10065             _DtHelpFreeSegments(frmtStruct.snb, _DtCvFALSE, NULL, NULL);
10066           }
10067
10068         /*
10069          * free the font structures allocated
10070          */
10071         DestroyFontInfo(&frmtStruct);
10072
10073       }
10074
10075     _DtHelpCeUnlockVolume(lockInfo);
10076
10077     return abstr;
10078
10079 } /* End _DtHelpCeFrmtSdlVolumeAbstractToAscii */
10080
10081 /******************************************************************************
10082  * Function:    int _DtHelpCeFrmtSDLVolTitleToAscii (
10083  *                              char *filename,
10084  *                              int offset,
10085  *                              char **ret_title, char **ret_abbrev)
10086  *
10087  * Parameters:
10088  *
10089  * Returns:     0 if successful, -1 if errors
10090  *
10091  * Purpose:
10092  ******************************************************************************/
10093 int
10094 _DtHelpCeFrmtSDLVolTitleToAscii(
10095     _DtHelpVolumeHdl volume,
10096     _FrmtUiInfo *ui_info,
10097     char        **ret_title)
10098 {
10099     char                *abbrev  = NULL;
10100     int                  result  = 0;
10101     int                  done    = 0;
10102     _DtCvSegment        *pHeadSeg;
10103     _DtHelpCeLockInfo    lockInfo;
10104
10105     *ret_title = NULL;
10106
10107     /*
10108      * get the head element
10109      */
10110     if (_DtHelpCeLockVolume(volume, &lockInfo) != 0)
10111         return -1;
10112
10113     result = GetDocumentTitle(volume,ui_info, _SdlFontModeNone, False, &pHeadSeg);
10114     _DtHelpCeUnlockVolume(lockInfo);
10115
10116     if (result == 0)
10117       {
10118         /*
10119          * get the abbreviation of the head
10120          */
10121         result = -2;
10122         if (pHeadSeg != NULL)
10123           {
10124             CreateAsciiAbbrev(pHeadSeg, &abbrev);
10125
10126             if (abbrev != NULL && *abbrev != '\0')
10127               {
10128                 *ret_title = abbrev;
10129                 result     = 0;
10130               }
10131           }
10132
10133         /*
10134          * if there wasn't an abbreviation, use the head itself, stripping
10135          * all special items and graphics.
10136          */
10137         if (0 != result && pHeadSeg != NULL &&
10138                                 NULL != _DtCvContainerListOfSeg(pHeadSeg))
10139           {
10140             _DtCvValue   nlFlag = False;
10141
10142             CreateAsciiString(_DtCvContainerListOfSeg(pHeadSeg),
10143                                                 GetSdlDocSnb(volume),
10144                                                 &nlFlag, ret_title);
10145             if (abbrev != NULL)
10146                 free(abbrev);
10147
10148             result = 0;
10149           }
10150       }
10151
10152     /*
10153      * if there isn't an abbreviation on the document, and there isn't
10154      * a head, then try for the title page. After that, try the
10155      * hometopic's title.
10156      */
10157     if (-2 == result)
10158       {
10159         result = 0;
10160         if (_DtHelpGetTopicTitle(volume, "_title", ret_title) != 0)
10161             result = _DtHelpGetTopicTitle(volume, "_hometopic", ret_title);
10162       }
10163
10164     return result;
10165
10166 } /* End _DtHelpCeFrmtSDLVolTitleToAscii */
10167
10168 /******************************************************************************
10169  * Function:    int _DtHelpCeGetSdlTopicTitleChunks (
10170  *
10171  * Parameters:
10172  *
10173  * Returns:     0 if successful, -1 if errors
10174  *
10175  * Purpose:
10176  ******************************************************************************/
10177 int
10178 _DtHelpCeGetSdlTitleChunks(
10179     _DtHelpVolumeHdl      volume,
10180     char                  *loc_id,
10181     _FrmtUiInfo           *ui_info,
10182     void                ***ret_chunks)
10183 {
10184     int                  result = 0;
10185     int                  offset;
10186     FormatStruct         frmtStruct;
10187     CESDLVolume         *sdlVol;
10188     SDLMask              stopMask[SDL_MASK_LEN] =
10189                                         SDLInitMask(SdlElementSubHead);
10190
10191     *ret_chunks = NULL;
10192     if (_DtHelpCeFindSdlId(volume, loc_id, -1, NULL, &offset) != True)
10193         return -1;
10194
10195     if (SetUp(volume, &sdlVol, &frmtStruct, NULL, ui_info, -1, True, True) != 0)
10196         return -1;
10197
10198     result = FormatSDLTitle(frmtStruct.vol_name, offset, -1, &frmtStruct);
10199
10200     if (result != -1 && frmtStruct.seg_list != NULL)
10201       {
10202         _DtCvSegment  *headEl;
10203         _DtCvSegment  *pSnbEl = NULL;
10204
10205         result = -1;
10206         headEl = _DtCvContainerListOfSeg(frmtStruct.seg_list);
10207
10208         /*
10209          * A virpage contains a zero or more heads as it's first
10210          * content.  Therefore, if the the first item is not a
10211          * container and a controller (heads get the controller flag
10212          * put on them), then this virpage does not have a title.
10213          */
10214         if (NULL != headEl && _DtCvIsSegContainer(headEl) &&
10215                                                 _DtCvIsSegController(headEl))
10216           {
10217             result = ProcessSegmentsToChunks(frmtStruct.toss,
10218                                         headEl,
10219                                         pSnbEl, stopMask,
10220                                         _DtHelpCeGetSdlVolLanguage(volume),
10221                                         _DtHelpCeGetSdlVolCharSet(volume),
10222                                         ui_info->resolve_spc,
10223                                         ui_info->client_data,
10224                                         ret_chunks);
10225           }
10226       }
10227     else
10228         result = -1;
10229
10230     if (frmtStruct.seg_list != NULL)
10231         _DtHelpFreeSegments(frmtStruct.seg_list, _DtCvFALSE,
10232                                                 ui_info->destroy_region,
10233                                                 ui_info->client_data);
10234
10235     if (frmtStruct.snb != NULL)
10236         _DtHelpFreeSegments(frmtStruct.snb, _DtCvFALSE,
10237                                                 ui_info->destroy_region,
10238                                                 ui_info->client_data);
10239
10240     /*
10241      * free the font structures allocated
10242      */
10243     DestroyFontInfo(&frmtStruct);
10244
10245     /*
10246      * destroy the link database
10247      */
10248     _DtLinkDbDestroy(frmtStruct.my_links);
10249
10250     return result;
10251
10252 } /* End _DtHelpCeGetSdlTitleChunks */
10253
10254 /******************************************************************************
10255  * Function:    int _DtHelpCeGetSdlVolTitleChunks (
10256  *
10257  * Parameters:
10258  *
10259  * Returns:     0 if successful, -1 if errors
10260  *
10261  * Purpose:
10262  ******************************************************************************/
10263 int
10264 _DtHelpCeGetSdlVolTitleChunks(
10265     _DtHelpVolumeHdl     volume_handle,
10266     _FrmtUiInfo         *ui_info,
10267     void                ***ret_chunks)
10268 {
10269     int                  result  = -2;
10270     _DtCvSegment        *pHeadSeg;
10271     CESDLVolume         *sdlVol;
10272     SDLMask              stopMask[SDL_MASK_LEN] =
10273                                         SDLInitMask(SdlElementSubHead);
10274     /*
10275      * get the sdl volume pointer.
10276      */
10277     sdlVol = _DtHelpCeGetSdlVolumePtr(volume_handle);
10278     if (sdlVol ==  NULL)
10279         return -1;
10280
10281     /*
10282      * find the document attributes
10283      */
10284     if (NULL == sdlVol->sdl_info)
10285         return -1;
10286
10287     /*
10288      * get the head element
10289      */
10290     if (GetDocumentTitle(volume_handle, ui_info,
10291                                 _SdlFontModeResolve, True, &pHeadSeg) == -1)
10292         return -1;
10293
10294     /*
10295      * process it
10296      */
10297     if (pHeadSeg != NULL)
10298         result = ProcessSegmentsToChunks(
10299                                 _DtHelpCeGetSdlVolToss(volume_handle, -1),
10300                                 pHeadSeg,
10301                                 GetSdlDocSnb(volume_handle), stopMask,
10302                                 _DtHelpCeGetSdlVolLanguage(volume_handle),
10303                                 _DtHelpCeGetSdlVolCharSet(volume_handle),
10304                                 ui_info->resolve_spc,
10305                                 ui_info->client_data,
10306                                 ret_chunks);
10307     if (result != 0)
10308       {
10309         result = _DtHelpCeGetSdlTitleChunks(volume_handle, "_title",
10310                                                 ui_info, ret_chunks);
10311         if (result != 0)
10312             result = _DtHelpCeGetSdlTitleChunks(volume_handle, "_hometopic",
10313                                                 ui_info, ret_chunks);
10314       }
10315
10316     return result;
10317
10318 } /* End _DtHelpCeGetSdlVolTitleChunks */
10319
10320 /******************************************************************************
10321  * Function:    int _DtHelpCeGetSdlVolToss (
10322  *                              _DtHelpVolumeHdl volume,
10323  * Parameters:
10324  *              volume          Specifies the volume to read/parse.
10325  *
10326  * Returns:     0 if successful, -1 if errors
10327  *
10328  * Purpose:     Get the toss from a volume.
10329  ******************************************************************************/
10330 _DtCvSegment *
10331 _DtHelpCeGetSdlVolToss(
10332     _DtHelpVolumeHdl volume,
10333     int          fd)
10334 {
10335     CESDLVolume         *sdlVol;
10336     FormatStruct         frmtStruct;
10337     SDLMask              skipMask   [SDL_MASK_LEN] = SDLClearAllBits;
10338     SDLMask              startExcept[SDL_MASK_LEN] =
10339                                         SDLInitMask(SdlElementNone);
10340     /*
10341      * get the sdl volume pointer.
10342      */
10343     sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
10344     if (sdlVol == NULL)
10345         return NULL;
10346
10347     if (sdlVol->toss == NULL
10348         && SetUp(volume,NULL,&frmtStruct,NULL,&DefUiInfo,fd,True,False) == 0
10349         && _DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume), 0, fd,
10350                                         &(frmtStruct.my_file), NULL) != -1)
10351       {
10352         if (ProcessContent(&frmtStruct, SDLDocumentContent,
10353                                 SdlElementNone, startExcept, skipMask) != -1
10354             && ProcessSDLMarkup(&frmtStruct, SdlElementVStruct,
10355                                 SdlElementToss, startExcept, skipMask) != -1)
10356             sdlVol->toss = frmtStruct.seg_list;
10357
10358         _DtHelpCeBufFileClose (frmtStruct.my_file, (fd == -1 ? True : False));
10359
10360         /*
10361          * free the font structures allocated
10362          */
10363         DestroyFontInfo(&frmtStruct);
10364
10365         /*
10366          * destroy the link database
10367          */
10368         _DtLinkDbDestroy(frmtStruct.my_links);
10369       }
10370
10371     if (sdlVol->toss != NULL)
10372         return (_DtCvContainerListOfSeg(sdlVol->toss));
10373
10374     return NULL;
10375
10376 } /* End _DtHelpCeGetSdlVolToss */
10377
10378 /******************************************************************************
10379  * Function:    int _DtHelpCeGetSdlVolIndex (
10380  *                              _DtHelpVolumeHdl volume,
10381  * Parameters:
10382  *              volume          Specifies the volume to read/parse.
10383  *
10384  * Returns:     0 if successful, -1 if errors
10385  *
10386  * Purpose:     Get the index from a volume.
10387  ******************************************************************************/
10388 int
10389 _DtHelpCeGetSdlVolIndex(
10390     _DtHelpVolumeHdl volume)
10391 {
10392     int                  result = -1;
10393     CESDLVolume         *sdlVol;
10394     FormatStruct         frmtStruct;
10395     SDLMask              skipMask   [SDL_MASK_LEN] = SDLClearAllBits;
10396     SDLMask              startExcept[SDL_MASK_LEN] =
10397                                         SDLInitMask(SdlElementNone);
10398
10399     sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
10400     if (sdlVol == NULL)
10401         return -1;
10402
10403     if (sdlVol->index != NULL)
10404         return 0;
10405
10406     if (SetUp(volume, NULL, &frmtStruct, NULL, &DefUiInfo, -1, True, True) != 0)
10407         return -1;
10408
10409     /*
10410      * now set up correct font mode.
10411      */
10412     frmtStruct.resolve_font = _SdlFontModeNone;
10413
10414     if (_DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume), 0, -1,
10415                                         &(frmtStruct.my_file), NULL) != -1)
10416       {
10417         if (ProcessContent(&frmtStruct, SDLDocumentContent,
10418                                 SdlElementNone, startExcept, skipMask) != -1
10419             && ProcessSDLMarkup(&frmtStruct, SdlElementVStruct,
10420                                 SdlElementIndex, startExcept, skipMask) != -1)
10421           {
10422             sdlVol->index = frmtStruct.seg_list;
10423             result = 0;
10424           }
10425
10426         _DtHelpCeBufFileClose (frmtStruct.my_file, True);
10427       }
10428
10429     /*
10430      * destroy the link database
10431      */
10432     _DtLinkDbDestroy(frmtStruct.my_links);
10433
10434     /*
10435      * free the font structures allocated
10436      */
10437     DestroyFontInfo(&frmtStruct);
10438
10439     return result;
10440
10441 } /* End _DtHelpCeGetSdlVolIndex */
10442
10443 /******************************************************************************
10444  * Function:    int _DtHelpCeGetSdlVolIds (
10445  *                              _DtHelpVolumeHdl volume,
10446  *                              _DtCvSegment **ret_ids
10447  * Parameters:
10448  *              volume          Specifies the volume to read/parse.
10449  *
10450  * Returns:     0 if successful, -1 if errors
10451  *
10452  * Purpose:     Get the loids from a volume.
10453  ******************************************************************************/
10454 int
10455 _DtHelpCeGetSdlVolIds(
10456     _DtHelpVolumeHdl      volume,
10457     int                   fd,
10458     _DtCvSegment                **ret_ids)
10459 {
10460     int                  result = 0;
10461     CESDLVolume         *sdlVol;
10462     FormatStruct         frmtStruct;
10463     SDLMask              skipMask   [SDL_MASK_LEN] = SDLClearAllBits;
10464     SDLMask              startExcept[SDL_MASK_LEN] =
10465                                         SDLInitMask(SdlElementNone);
10466
10467     *ret_ids = NULL;
10468     sdlVol   = _DtHelpCeGetSdlVolumePtr(volume);
10469     if (sdlVol == NULL)
10470         return -1;
10471
10472     if (sdlVol->loids == NULL)
10473       {
10474         result = -1;
10475         if (SetUp(NULL,NULL,&frmtStruct,NULL,&DefUiInfo,-1,False,False) != -1
10476             && _DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume), 0, fd,
10477                                         &(frmtStruct.my_file), NULL) != -1)
10478           {
10479             if (ProcessContent(&frmtStruct, SDLDocumentContent,
10480                                 SdlElementNone, startExcept, skipMask) != -1)
10481               {
10482                 if (ProcessSDLMarkup(&frmtStruct, SdlElementVStruct,
10483                                 SdlElementLoids, startExcept, skipMask) != -1)
10484                   {
10485                     sdlVol->loids = frmtStruct.seg_list;
10486                     result = 0;
10487                   }
10488               }
10489
10490             /*
10491              * free the font structures allocated
10492              */
10493             DestroyFontInfo(&frmtStruct);
10494
10495             /*
10496              * destroy the link database
10497              */
10498             _DtLinkDbDestroy(frmtStruct.my_links);
10499
10500             _DtHelpCeBufFileClose(frmtStruct.my_file,(fd == -1 ? True : False));
10501           }
10502       }
10503
10504     if (sdlVol->loids != NULL)
10505         *ret_ids = _DtCvContainerListOfSeg(sdlVol->loids);
10506
10507     return result;
10508
10509 } /* End _DtHelpCeGetSdlVolIds */
10510
10511 /******************************************************************************
10512  * Function:    int _DtHelpCeParseSdlTopic (_DtHelpVolumeHdl volume,
10513  *                              int offset, char *id_string,
10514  *                              _DtCvTopicPtr *ret_handle)
10515  *
10516  * Parameters:
10517  *              volume          Specifies the Help Volume the information
10518  *                              is associated with.
10519  *              offset          Specifies the offset into 'filename' to
10520  *                              the Help Topic desired.
10521  *              id_string       Specifies the location id to look for or NULL.
10522  *              ret_handle      Returns a handle to the topic information
10523  *                              including the number of paragraphs and the
10524  *                              id match segment.
10525  *
10526  * Returns:     0 if successful, -1 if errors
10527  *
10528  * Purpose:     _DtHelpCeParseSdlTopic formats Help Files with formatting
10529  *              information into a CEVirtualPage
10530  *
10531  ******************************************************************************/
10532 int
10533 _DtHelpCeParseSdlTopic(
10534     _DtHelpVolumeHdl     volume,
10535     _FrmtUiInfo         *ui_info,
10536     int                  fd,
10537     int                  offset,
10538     char                *id_string,
10539     int                  rich_text,
10540     _DtCvTopicPtr       *ret_handle)
10541 {
10542     int                  result = 0;
10543     SDLMask              startExcept[SDL_MASK_LEN] =
10544                                         SDLInitMask(SdlElementNone);
10545     SDLMask              processMask[SDL_MASK_LEN]  = SDLSetAllBits;
10546     FormatStruct         frmtStruct;
10547     _DtCvTopicInfo      *topicHandle;
10548     CESDLVolume         *sdlVol;
10549
10550     *ret_handle = NULL;
10551
10552     if (SetUp(volume,&sdlVol,&frmtStruct,NULL,ui_info,fd,True,rich_text) != 0)
10553         return -1;
10554
10555     /*
10556      * remember the id for graphics
10557      */
10558     frmtStruct.id_string = id_string;
10559
10560     result = _DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume),
10561                                         offset, fd,
10562                                         &(frmtStruct.my_file), NULL);
10563     if (result != -1)
10564       {
10565         result = ProcessSDLMarkup (&frmtStruct, SdlElementVirpage,
10566                                 SdlElementNone, startExcept, processMask);
10567         _DtHelpCeBufFileClose (frmtStruct.my_file, (fd == -1 ? True : False));
10568       }
10569
10570     /*
10571      * free the async blocks
10572      */
10573     _DtHelpFreeSegments(frmtStruct.async_blks, _DtCvFALSE,
10574                                                 ui_info->destroy_region,
10575                                                 ui_info->client_data);
10576
10577     /*
10578      * free the system notation blocks
10579      */
10580     _DtHelpFreeSegments(frmtStruct.snb, _DtCvFALSE,
10581                                                 ui_info->destroy_region,
10582                                                 ui_info->client_data);
10583
10584     if (result != -1)
10585       {
10586         topicHandle = (_DtCvTopicInfo *) malloc (sizeof(_DtCvTopicInfo));
10587         if (topicHandle != NULL)
10588           {
10589             topicHandle->mark_list = NULL;
10590             topicHandle->id_str    = NULL;
10591             if (id_string != NULL)
10592                 topicHandle->id_str = strdup(id_string);
10593
10594             topicHandle->link_data = frmtStruct.my_links;
10595             topicHandle->seg_list  = frmtStruct.seg_list;
10596             *ret_handle = (void *) topicHandle;
10597           }
10598         else
10599             result = -1;
10600       }
10601
10602     /*
10603      * free the allocated font structures
10604      */
10605     DestroyFontInfo(&frmtStruct);
10606
10607     return result;
10608
10609 } /* End _DtHelpCeParseSdlTopic */