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