dtcm: make it build
[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 libraries 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                 { int myI;\
3301                   for (myI = 0; myI < SDL_MASK_LEN; myI++) \
3302                       x[myI] = y[myI]; \
3303                 }
3304 #define MergeMasks(x,y) \
3305                 { int myI;\
3306                   for (myI = 0; myI < SDL_MASK_LEN; myI++) \
3307                       x[myI] |= y[myI]; \
3308                 }
3309 #define RemoveMasks(x,y) \
3310                 { int myI;\
3311                   for (myI = 0; myI < SDL_MASK_LEN; myI++) \
3312                       x[myI] &= (~(y[myI])); \
3313                 }
3314 #define MaskToValue(x,y) \
3315                 { int myI;\
3316                   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     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                   {
3857                     free(newData);
3858                     return NULL;
3859                   }
3860
3861                 /*
3862                  * set the match data for toss lookup
3863                  */
3864                 match = SegMatchDataPtr(refItem);
3865
3866                 if (NULL != match && NULL != my_struct->toss)
3867                     _DtHelpCeMergeSdlAttribInfo(
3868                                         _DtHelpCeMatchSemanticStyle(
3869                                                         my_struct->toss,
3870                                                         match->clan,
3871                                                         match->level,
3872                                                         match->ssi),
3873                                         newSeg,
3874                                         my_struct->my_fonts,
3875                                         NULL,
3876                                         NULL,
3877                                         NULL);
3878
3879                 if (0 != MySaveString(&newSeg, my_struct, newData,
3880                                         my_struct->cur_link, my_struct->mb_len,
3881                                         False))
3882                   {
3883                     free(newData);
3884                     return NULL;
3885                   }
3886
3887                 free(newData);
3888               }
3889             else
3890               {
3891                 /*
3892                  * strip the container wrapper from the snbEntry before
3893                  * duplication.
3894                  *
3895                  * Also, include the toss match data for this segment
3896                  * in the snbEntry.
3897                  */
3898                 snbEntry = _DtCvContainerListOfSeg(snbEntry);
3899                 if (NULL != snbEntry)
3900                   {
3901                     SegMatchData(snbEntry) = SegMatchData(refItem);
3902
3903                     newSeg = DuplicateElement(my_struct->ui_info->client_data,
3904                                         my_struct->toss,
3905                                         snbEntry,
3906                                         &(my_struct->prev_data),
3907                                         NULL,
3908                                         my_struct->ui_info->load_font,
3909                                         my_struct->ui_info->resolve_spc,
3910                                         my_struct->ui_info->line_height / 2,
3911                                         my_struct->ui_info->avg_char,
3912                                         *(my_struct->my_fonts),
3913                                         my_struct->cur_link, True);
3914
3915                     SegMatchData(snbEntry) = NULL;
3916
3917                     if (NULL == newSeg)
3918                         return NULL;
3919
3920                     /*
3921                      * if the only item in the list for the snb entry is
3922                      * a region, then assume it is a graphic, video, etc.
3923                      * Check to see if the region is in-line or a figure.
3924                      * If in-line, ignore any heads with the refitem. If a
3925                      * figure, include them (they may be a caption to the
3926                      * region).
3927                      */
3928                     if (_DtCvIsSegRegion(newSeg) && NULL == _DtCvNextSeg(newSeg))
3929                       {
3930                         SdlMatchData *info = SegMatchDataPtr(refItem);
3931
3932                         /*
3933                          * is this a figure?
3934                          */
3935                         if (SdlClassFigure == info->clan)
3936                           {
3937                             _DtCvNextSeg(newSeg) = _DtCvContainerListOfSeg(refItem);
3938                             _DtCvContainerListOfSeg(refItem) = NULL;
3939                           }
3940                       }
3941                   }
3942               }
3943           }
3944
3945         /*
3946          * was there alternate text?
3947          */
3948         else if (NULL != altText && NULL != _DtCvContainerListOfSeg(altText))
3949           {
3950             /*
3951              * the new segment becomes the contents of the <alttext>
3952              * container - why copy? Just null the <alttext> pointer
3953              * to prevent the free from destroying the contents.
3954              */
3955             newSeg = _DtCvContainerListOfSeg(altText);
3956             _DtCvContainerListOfSeg(altText) = NULL;
3957
3958             /*
3959              * load the font for this snref.
3960              */
3961             (my_struct->ui_info->load_font)(my_struct->ui_info->client_data,
3962                                 _DtHelpFontHintsLang(*(my_struct->my_fonts)),
3963                                 _DtHelpFontHintsCharSet(*(my_struct->my_fonts)),
3964                                 *(my_struct->my_fonts),
3965                                 &(_DtCvFontOfStringSeg(newSeg)));
3966           }
3967
3968         if (my_struct->prev_data != NULL)
3969             my_struct->prev_data->next_disp = newSeg;
3970
3971         my_struct->last_was_space = False;
3972         my_struct->last_was_mb    = False;
3973         my_struct->last_was_nl    = False;
3974         if (NULL != newSeg)
3975             my_struct->prev_data      = newSeg;
3976       }
3977     else if (_DtCvTRUE == my_struct->save_snref)
3978       {
3979         int count = my_struct->snref_cnt;
3980
3981         if (NULL == my_struct->un_snrefs)
3982             my_struct->un_snrefs = (UnresSnref *) malloc (sizeof(UnresSnref));
3983         else
3984             my_struct->un_snrefs = (UnresSnref *) realloc (
3985                                         (void *) my_struct->un_snrefs,
3986                                         (sizeof(UnresSnref) * (count + 1)));
3987         if (NULL != my_struct->un_snrefs)
3988           {
3989             my_struct->un_snrefs[count].id       = snref_id;
3990             my_struct->un_snrefs[count].seg      = snref;
3991             my_struct->un_snrefs[count].cur_link = my_struct->cur_link;
3992             my_struct->un_snrefs[count].fonts    = *(my_struct->my_fonts);
3993
3994             my_struct->snref_cnt++;
3995
3996             /*
3997              * return the snref segment as our new segment to act as a
3998              * place holder, otherwise it gets squeezed
3999              * out.
4000              */
4001             newSeg = snref;
4002
4003             if (my_struct->prev_data != NULL)
4004                 my_struct->prev_data->next_disp = newSeg;
4005
4006             my_struct->prev_data      = newSeg;
4007
4008             /*
4009              * make the snref a noop so it gets the proper next/last
4010              * display pointers.
4011              */
4012             newSeg->type = _DtCvSetTypeToNoop(newSeg->type);
4013           }
4014       }
4015
4016     *(my_struct->my_fonts) = saveFonts;
4017     return newSeg;
4018
4019 } /* End ResolveSnref */
4020
4021 /******************************************************************************
4022  * Function:    static CEFontSpecs AllocateFontInfo(my_struct);
4023  *
4024  * Parameters:
4025  *
4026  * Returns:     non-null  if successful, NULL if errors
4027  *
4028  * Purpose:     Allocates a FontInfo structure and intializes it to
4029  *              the current fonts hints.
4030  *
4031  ******************************************************************************/
4032 static  _DtHelpFontHints *
4033 AllocateFontInfo(
4034     FormatStruct *my_struct)
4035 {
4036     _DtHelpFontHints *retFont = NULL;
4037
4038     if (my_struct->free_cnt > 0)
4039         retFont = my_struct->free_fonts[--my_struct->free_cnt];
4040     else
4041       {
4042         /*
4043          * malloc and initialize the starting font information
4044          */
4045         retFont = (_DtHelpFontHints *) malloc (sizeof(_DtHelpFontHints));
4046
4047         if (NULL == retFont)
4048             return NULL;
4049       }
4050
4051     /*
4052      * initialize the font structure
4053      */
4054     if (NULL != my_struct->my_fonts)
4055         *retFont = *(my_struct->my_fonts);
4056     else
4057         *retFont = DefFontInfo;
4058
4059     return retFont;
4060 }
4061
4062 /******************************************************************************
4063  * Function:    static _DtCvSegment **ConvertToList(segs);
4064  *
4065  * Parameters:
4066  *
4067  * Returns:     non-null  if successful, NULL if errors
4068  *
4069  * Purpose:     Allocates a list of null terminated _DtCvSegment pointers.
4070  *
4071  ******************************************************************************/
4072 static  _DtCvSegment **
4073 ConvertToList(_DtCvSegment *segs)
4074 {
4075     _DtCvSegment **ptr  = NULL;
4076
4077     /*
4078      * count the segments
4079      */
4080     while (NULL != segs)
4081       {
4082         _DtCvSegment *next;
4083
4084         ptr = (_DtCvSegment **) _DtCvAddPtrToArray ((void **) ptr,
4085                                                         (void *) segs);
4086         next = _DtCvNextSeg(segs);
4087         _DtCvNextSeg(segs) = NULL;
4088         segs = next;
4089       }
4090
4091     return (ptr);
4092 }
4093
4094 /******************************************************************************
4095  * Function:    static int DestroyFontInfo(my_struct);
4096  *
4097  * Parameters:
4098  *
4099  * Returns:     0 if successful, -1 if errors
4100  *
4101  * Purpose:     Places the font structure in the free list for re-use.
4102  *
4103  ******************************************************************************/
4104 static  void
4105 DestroyFontInfo(
4106     FormatStruct *my_struct)
4107 {
4108     /*
4109      * free the font structures allocated
4110      */
4111     while (0 < my_struct->free_cnt)
4112       {
4113         my_struct->free_cnt--;
4114         free(my_struct->free_fonts[my_struct->free_cnt]);
4115       }
4116
4117     if (NULL != my_struct->free_fonts)
4118         free(my_struct->free_fonts);
4119
4120     my_struct->free_fonts = NULL;
4121
4122     if (NULL != my_struct->my_fonts)
4123         free(my_struct->my_fonts);
4124 }
4125
4126 /******************************************************************************
4127  * Function:    static int FreeFontInfo(my_struct);
4128  *
4129  * Parameters:
4130  *
4131  * Returns:     0 if successful, -1 if errors
4132  *
4133  * Purpose:     Places the font structure in the free list for re-use.
4134  *
4135  ******************************************************************************/
4136 static  int
4137 FreeFontInfo(
4138     FormatStruct *my_struct)
4139 {
4140     if (my_struct->free_cnt >= my_struct->free_max)
4141       {
4142         my_struct->free_max += GROW_SIZE;
4143         if (NULL != my_struct->free_fonts)
4144             my_struct->free_fonts = (_DtHelpFontHints **) realloc (
4145                         my_struct->free_fonts,
4146                         sizeof(_DtHelpFontHints *) * my_struct->free_max);
4147         else
4148             my_struct->free_fonts = (_DtHelpFontHints **) malloc (
4149                         sizeof(_DtHelpFontHints *) * my_struct->free_max);
4150
4151         if (NULL == my_struct->free_fonts)
4152             return -1;
4153       }
4154
4155     my_struct->free_fonts[my_struct->free_cnt++] = my_struct->my_fonts;
4156
4157     return 0;
4158 }
4159
4160 /******************************************************************************
4161  * Function:    static int ResolveAsyncBlock(my_struct, table_seg);
4162  *
4163  * Parameters:
4164  *
4165  * Returns:     0 if successful, -1 if errors
4166  *
4167  * Purpose:     
4168  *
4169  ******************************************************************************/
4170 static  int
4171 ResolveAsyncBlock(
4172     FormatStruct        *my_struct,
4173     _DtCvSegment        *table_seg)
4174 {
4175     char        c;
4176     char       *next;
4177     char       *start  = NULL;
4178     char      **rowIds = _DtCvCellIdsOfTableSeg(table_seg);
4179     _DtCvFrmtOption *colJ;
4180     _DtCvSegment **cellSegs;
4181     _DtCvSegment  *newSeg;
4182     _DtCvSegment  *asyncSegs;
4183     _DtCvValue  found;
4184
4185     while (NULL != rowIds && NULL != *rowIds)
4186       {
4187         /*
4188          * get the start of the row ids
4189          */
4190         next = *rowIds;
4191         colJ = _DtCvColJustifyOfTableSeg(table_seg);
4192         while (NULL != next && '\0' != *next)
4193           {
4194             /*
4195              * skip leading spaces
4196              */
4197             while (' ' == *next) next++;
4198
4199             /*
4200              * set the starting pointer.
4201              */
4202             start = next;
4203
4204             /*
4205              * skip to the next delimitter.
4206              */
4207             while (' ' != *next && '\0' != *next) next++;
4208
4209             /*
4210              * check for the id in the set of segments.
4211              */
4212             if (start != next)
4213               {
4214                 /*
4215                  * save and replace the last character with a null byte.
4216                  */
4217                 c = *next;
4218                 *next = '\0';
4219
4220                 /*
4221                  * get the cells in the table
4222                  */
4223                 cellSegs = _DtCvCellsOfTableSeg(table_seg);
4224
4225                 /*
4226                  * check that one of these cells matches the id
4227                  */
4228                 found   = False;
4229                 if (NULL != cellSegs)
4230                   {
4231                     while (False == found && NULL != *cellSegs)
4232                       {
4233                         if (_DtCvStrCaseCmpLatin1(
4234                                         _DtCvContainerIdOfSeg(*cellSegs),
4235                                                                 start) == 0)
4236                             found = True;
4237                         else
4238                             cellSegs++;
4239                       }
4240                     newSeg = *cellSegs;
4241                   }
4242
4243                 /*
4244                  * the id did not match any of the cells in the table
4245                  * Look in the async list.
4246                  */
4247                 if (False == found)
4248                   {
4249                     asyncSegs = my_struct->async_blks;
4250                     while (False == found && NULL != asyncSegs)
4251                       {
4252                         if (_DtCvStrCaseCmpLatin1(
4253                                         _DtCvContainerIdOfSeg(asyncSegs),
4254                                         start) == 0)
4255                             found = True;
4256                         else
4257                             asyncSegs = _DtCvNextSeg(asyncSegs);
4258                       }
4259
4260                     /*
4261                      * found one in the aysnc blocks
4262                      * Duplicate it.
4263                      */
4264                     if (True == found)
4265                       {
4266                         _DtCvSegment *lastSrc  = NULL;
4267                         _DtCvSegment *lastNext = NULL;
4268
4269                         /*
4270                          * break the link to the next segment
4271                          * or we'll copy this segment and all
4272                          * the next segments.
4273                          */
4274                         _DtCvSegment *nextSeg = _DtCvNextSeg(asyncSegs);
4275                         _DtCvNextSeg(asyncSegs) = NULL;
4276
4277                         /*
4278                          * allocate a new segment for this async block.
4279                          */
4280                         newSeg = DuplicateElement(
4281                                         my_struct->ui_info->client_data,
4282                                         my_struct->toss,
4283                                         asyncSegs, &lastSrc, &lastNext,
4284                                         my_struct->ui_info->load_font,
4285                                         my_struct->ui_info->resolve_spc,
4286                                         my_struct->ui_info->line_height / 2,
4287                                         my_struct->ui_info->avg_char,
4288                                         *(my_struct->my_fonts),
4289                                         -1, False);
4290
4291                         /*
4292                          * restore the async seg linked list
4293                          */
4294                         _DtCvNextSeg(asyncSegs) = nextSeg;
4295
4296                         /*
4297                          * check to see if anything was copied
4298                          */
4299                         if (NULL == newSeg)
4300                             return -1;
4301                         /*
4302                          * now place this segment in the list.
4303                          */
4304                         _DtCvCellsOfTableSeg(table_seg) = (_DtCvSegment **)
4305                                 _DtCvAddPtrToArray(
4306                                 (void **) _DtCvCellsOfTableSeg(table_seg),
4307                                         (void *) newSeg);
4308                       }
4309                   }
4310                /*
4311                 * replace the character.
4312                 */
4313                *next = c;
4314               }
4315
4316             colJ++;
4317           }
4318
4319         /*
4320          * check the next row
4321          */
4322         rowIds++;
4323       }
4324
4325     return 0;
4326 }
4327
4328 /******************************************************************************
4329  * Function:    static int FindSnb(my_struct, id);
4330  *
4331  * Parameters:
4332  *
4333  * Returns:     0 if successful, -1 if errors
4334  *
4335  * Purpose:     
4336  *
4337  ******************************************************************************/
4338 static  _DtCvSegment *
4339 FindSnbEntry(
4340     _DtCvSegment         *snb,
4341     char         *target)
4342 {
4343     char      *id;
4344     _DtCvSegment *retEntry;
4345
4346     if (NULL != snb)
4347       {
4348         retEntry = _DtCvContainerListOfSeg(snb);
4349         while (NULL != retEntry)
4350           {
4351             id = NULL;
4352             if (_DtCvIsSegContainer(retEntry))
4353                 id = _DtCvContainerIdOfSeg(retEntry);
4354
4355             if (NULL != id && _DtCvStrCaseCmpLatin1(target, id) == 0)
4356                 return retEntry;
4357
4358             retEntry = _DtCvNextSeg(retEntry);
4359           }
4360       }
4361
4362     return NULL;
4363 }
4364
4365 /* A little helper function, acts like strcpy
4366  * but safe for overlapping regions.
4367  */
4368 static void *strmove(void *dest, const void *src) {
4369     memmove(dest, src, strlen(src) + 1);
4370 }
4371
4372 /******************************************************************************
4373  * Function:    static int ProcessString(string, int idx);
4374  *
4375  * Parameters:
4376  *
4377  * Returns:     0 if successful, -1 if errors
4378  *
4379  * Purpose:     
4380  *
4381  ******************************************************************************/
4382 static  int
4383 ProcessString(
4384     FormatStruct         *my_struct,
4385     _DtCvValue            last_flag,
4386     _DtCvValue            nl_flag,
4387     _DtCvValue            mod_str,
4388     _DtCvValue            cpy_str,
4389     _DtCvValue            process_flag,
4390     char                 *string,
4391     int                   byte_len,
4392     int                  *idx)
4393 {
4394     if (mod_str == True)
4395         string[*idx] = '\0';
4396
4397     if (process_flag == True && MySaveString(&(my_struct->seg_list),
4398                                     my_struct, string, my_struct->cur_link,
4399                                     byte_len, nl_flag) != 0)
4400       {
4401         MyFree(string);
4402         return -1;
4403       }
4404
4405     my_struct->last_was_space = last_flag;
4406
4407     if (cpy_str == True)
4408       {
4409         strmove (string, &string[*idx+1]);
4410         *idx = -1;
4411       }
4412     return 0;
4413 }
4414
4415 /******************************************************************************
4416  * Function:    static void CompressLinkSeg(seg);
4417  *
4418  * Parameters:
4419  *
4420  * Returns:     nothing
4421  *
4422  * Purpose:     Check to see if there is a blank at the beginning of the
4423  *              segment and if it is needed.
4424  *
4425  ******************************************************************************/
4426 static  void
4427 CompressLinkSeg(
4428     _DtCvSegment *p_seg)
4429 {
4430     void    *pChar;
4431     int      wcFlag;
4432
4433     /*
4434      * check to see if the first segment is a string.
4435      */
4436     while (NULL != p_seg && _DtCvIsSegNoop(p_seg))
4437         p_seg = _DtCvNextSeg(p_seg);
4438
4439     if (NULL == p_seg)
4440         return;
4441
4442     if (_DtCvIsSegString(p_seg))
4443       {
4444         wcFlag = _DtCvIsSegWideChar(p_seg);
4445         pChar  = _DtCvStrPtr(_DtCvStringOfStringSeg(p_seg), wcFlag, 0);
4446
4447         /*
4448          * is this the only segment in the link?
4449          * Is it only one character in size?
4450          */
4451         if (NULL == _DtCvNextDisp(p_seg) && 1 <= _DtCvStrLen(pChar, wcFlag))
4452             return;
4453
4454         /*
4455          * is it a blank? (wide char and single char codes are equal
4456          * for blanks - ISO standard)
4457          */
4458         if ((_DtCvIsSegWideChar(p_seg) && ' ' == *((wchar_t *) pChar)) ||
4459                 (_DtCvIsSegRegChar(p_seg) && ' ' == *((char *) pChar)))
4460           {
4461             /*
4462              * compress out the blank
4463              *
4464              * is this a single byte string? If so, use strcpy to move
4465              * the string.
4466              */
4467             if (_DtCvIsSegRegChar(p_seg))
4468                 strmove(((char *)pChar), &(((char *)pChar)[1]));
4469             else
4470               {
4471                 wchar_t *wcChar = (wchar_t *) pChar;
4472
4473                 while (0 != wcChar[0])
4474                   {
4475                     wcChar[0] = wcChar[1];
4476                     wcChar++;
4477                   }
4478               }
4479           }
4480       }
4481 }
4482
4483 /******************************************************************************
4484  * Function:    static int ProcessNonBreakChar(string, int idx);
4485  *
4486  * Parameters:
4487  *
4488  * Returns:     0 if successful, -1 if errors
4489  *
4490  * Purpose:
4491  *
4492  ******************************************************************************/
4493 static  int
4494 ProcessNonBreakChar(
4495     FormatStruct        *my_struct,
4496     _DtCvValue           process_flag,
4497     char                *break_str,
4498     char                *string,
4499     int                  byte_len,
4500     int                 *idx)
4501 {
4502     if (ProcessString(my_struct, False, False, True, False,
4503                                 process_flag, string, byte_len, idx) != 0)
4504         return -1;
4505
4506     my_struct->flags = _DtCvSetTypeToNonBreak(my_struct->flags);
4507     if (ProcessString(my_struct, False, False, False, False,
4508                                 process_flag, break_str, byte_len, idx) != 0)
4509         return -1;
4510
4511     my_struct->flags = my_struct->flags & ~(_DtCvNON_BREAK);
4512     strmove (string, &string[*idx+1]);
4513     *idx = -1;
4514     return 0;
4515 }
4516
4517 /******************************************************************************
4518  * Function:    static int MoveString(string, int idx);
4519  *
4520  * Parameters:
4521  *
4522  * Returns:     0 if successful, -1 if errors
4523  *
4524  * Purpose:     
4525  *
4526  ******************************************************************************/
4527 static  int
4528 MoveString(
4529     char        **string,
4530     int          *max_len,
4531     int          *idx)
4532 {
4533     int    i     = *idx;
4534     int    myLen = *max_len;
4535     char  *src   = *string;
4536
4537     i--;
4538     if (i == -1)
4539       {
4540         if (strlen(src) == myLen)
4541           {
4542             src = (char *) realloc (src, myLen + 2);
4543             if (src == NULL)
4544                 return -1;
4545
4546             myLen++;
4547             *string  = src;
4548             *max_len = myLen;
4549           }
4550         for (i = myLen; i > 0; i--)
4551             src[i] = src[i-1];
4552       }
4553
4554     *idx = i;
4555     return 0;
4556 }
4557
4558 /******************************************************************************
4559  * Function:    int SetUp (_DtHelpVolumeHdl volume,
4560  *                              CESDLVolume **sdl_vol,
4561  *                              FormatStruct *frmt_struct,
4562  *                              _DtCvSegment *toss,
4563  *                              _DtCvSegment *cur_frmt,
4564  *                              _DtCvValue lang
4565  *
4566  * Parameters:
4567  *              volume          Specifies the volume handle. If non-NULL,
4568  *                              create and return the sdl volume pointer
4569  *                              in 'sdl_vol'.
4570  *              sdl_vol         If not NULL, returns the sdl volume pointer.
4571  *              frmt_struct     Specifies the formatting structure to use.
4572  *              toss            Specifies the toss to use. If NULL and
4573  *                              sdl_vol asked for and flag == True, the
4574  *                              sdl_vol->toss will be used.
4575  *              lang            Specifies if the language/charset should
4576  *                              be set using information from the volume.
4577  *              flag            Specifies if to get/use the sdl_vol->toss
4578  *                              if toss is NULL.
4579  *
4580  * Returns:     0 if no failures, -1 if errors.
4581  *
4582  * Purpose:     Set up the formatting structure to use.
4583  *
4584  *****************************************************************************/
4585 static  int
4586 SetUp (
4587     _DtHelpVolumeHdl      volume,
4588     CESDLVolume         **sdl_vol,
4589     FormatStruct         *frmt_struct,
4590     _DtCvSegment                 *toss,
4591     const _FrmtUiInfo    *ui_info,
4592     int                   fd,
4593     _DtCvValue            lang,
4594     _DtCvValue            flag)
4595 {
4596     *frmt_struct = DefFormatStruct;
4597
4598     frmt_struct->my_links = _DtLinkDbCreate();
4599     if (NULL == frmt_struct->my_links)
4600         return -1;
4601
4602     if (volume != NULL && sdl_vol != NULL)
4603       {
4604         *sdl_vol = _DtHelpCeGetSdlVolumePtr(volume);
4605         if (*sdl_vol == NULL)
4606           {
4607             _DtLinkDbDestroy(frmt_struct->my_links);
4608             return -1;
4609           }
4610       }
4611
4612     /*
4613      * malloc and initialize the starting font information
4614      */
4615     frmt_struct->my_fonts = AllocateFontInfo(frmt_struct);
4616     if (NULL == frmt_struct->my_fonts)
4617       {
4618         _DtLinkDbDestroy(frmt_struct->my_links);
4619         return -1;
4620       }
4621
4622     if (volume != NULL)
4623       {
4624         frmt_struct->vol_name = _DtHelpCeGetVolumeName(volume);
4625
4626         if (toss == NULL && flag == True)
4627             toss = _DtHelpCeGetSdlVolToss(volume, fd);
4628
4629         if (lang == True)
4630           {
4631             _DtHelpFontHintsLang(*(frmt_struct->my_fonts)) =
4632                                 _DtHelpCeGetSdlVolLanguage(volume);
4633             _DtHelpFontHintsCharSet(*(frmt_struct->my_fonts)) =
4634                                 (char *) _DtHelpCeGetSdlVolCharSet(volume);
4635           }
4636       }
4637
4638     /*
4639      * determine mb_len should be based on lang/charset.
4640      */
4641     frmt_struct->mb_len   = _DtHelpCeGetMbLen(
4642                         _DtHelpFontHintsLang(*(frmt_struct->my_fonts)),
4643                         _DtHelpFontHintsCharSet(*(frmt_struct->my_fonts)));
4644     frmt_struct->toss     = toss;
4645     frmt_struct->ui_info  = ui_info;
4646
4647     return 0;
4648 }
4649
4650 /******************************************************************************
4651  * Function:    void AddToAsyncList (_DtCvSegment *seg_list)
4652  *
4653  * Parameters:
4654  *
4655  * Returns      Nothing
4656  *
4657  * Purpose:     Add a segment block to the async list.
4658  *
4659  *****************************************************************************/
4660 static  void
4661 AddToAsyncList (
4662     FormatStruct        *my_struct,
4663     _DtCvSegment        *block_seg)
4664 {
4665
4666     if (my_struct->async_blks != NULL)
4667       {
4668         _DtCvSegment  *pSeg = my_struct->async_blks;
4669
4670         while (_DtCvNextSeg(pSeg) != NULL)
4671             pSeg = _DtCvNextSeg(pSeg);
4672         
4673         _DtCvNextSeg(pSeg) = block_seg;
4674       }
4675     else
4676         my_struct->async_blks = block_seg;
4677
4678 }
4679
4680 /******************************************************************************
4681  * Function:    int CheckOptionList (int attr_value_type, const char *attr,
4682  *                                      _DtCvValue check_flag,
4683  *                                      SdlOption cur_num,
4684  *                                      SdlOption *num);
4685  *
4686  * Parameters:
4687  *
4688  * Returns:     0 if successful, -1 if errors
4689  *
4690  * Purpose:     If found, returns the enum value.
4691  *
4692  ******************************************************************************/
4693 static  int
4694 CheckOptionList(
4695     int          attr_value_type,
4696     const char  *attr,
4697     _DtCvValue   check,
4698     SdlOption    cur_num,
4699     SdlOption   *num)
4700 {
4701     int    i = 0;
4702     int    lowerChar;
4703     int    result = -1;
4704     const OptionList *option;
4705     _DtCvValue  found  = False;
4706     _DtCvValue  cmpFnd = False;
4707
4708     while (SDLOptionsList[i].attr_value != -1 &&
4709                         SDLOptionsList[i].attr_value != attr_value_type)
4710         i++;
4711
4712     if (SDLOptionsList[i].attr_value != -1)
4713       {
4714         option    = SDLOptionsList[i].options;
4715         lowerChar = _DtHelpCeToLower(*attr);
4716
4717         while (option != NULL && option->string != NULL &&
4718                                         (check == True || cmpFnd == False))
4719           {
4720             /*
4721              * check to see if the current option is in the list
4722              * of valid options for this attribute.
4723              */
4724             if (check && cur_num == option->option_value)
4725               {
4726                 /*
4727                  * okay, it's been found, don't check anymore.
4728                  */
4729                 found = True;
4730                 check = False;
4731               }
4732
4733             /*
4734              * otherwise, find out if this value is a valid option
4735              * for the attribute.
4736              */
4737             else if (cmpFnd == False &&
4738                         lowerChar == _DtHelpCeToLower(*(option->string)) &&
4739                         _DtCvStrCaseCmpLatin1(option->string, attr) == 0)
4740               {
4741                 cmpFnd = True;
4742                 *num   = option->option_value;
4743               }
4744             option++;
4745           }
4746       }
4747
4748     /*
4749      * if found is true, means check was originally set to true and
4750      * we found the current value in the option list for this attribute.
4751      */
4752     if (found == True)
4753         *num = cur_num;
4754
4755     /*
4756      * if we found that the current value was valid or that the string
4757      * was a valid option in the list for the attribute, return no error.
4758      */
4759     if (found == True || cmpFnd == True)
4760         result = 0;
4761
4762     return result;
4763 }
4764
4765 /******************************************************************************
4766  * Function:    int CheckFontList (int attr_value_type, char *attr,
4767  *                                      enum CEFontSpec *num);
4768  *
4769  * Parameters:
4770  *
4771  * Returns:     0 if successful, -1 if errors
4772  *
4773  * Purpose:     If found, returns the enum value.
4774  *
4775  ******************************************************************************/
4776 static  int
4777 CheckFontList(
4778     int                  attr_value_type,
4779     char                *attr,
4780     _DtHelpFontValue    *num)
4781 {
4782     int    i = 0;
4783     const FontSpecOption *option;
4784
4785     while (SDLFontList[i].attr_value != -1 &&
4786                         SDLFontList[i].attr_value != attr_value_type)
4787         i++;
4788
4789     if (SDLFontList[i].attr_value != -1)
4790       {
4791         option = SDLFontList[i].options;
4792
4793         while (option != NULL && option->string != NULL)
4794           {
4795             if (_DtCvStrCaseCmpLatin1(option->string, attr) == 0)
4796               {
4797                 *num = option->option_value;
4798                 return 0;
4799               }
4800             option++;
4801           }
4802       }
4803     return -1;
4804 }
4805
4806 /******************************************************************************
4807  * Function:    int LookAhead (FormatStruct my_struct, int token_value,
4808  *                              int remove_flag);
4809  *
4810  * Parameters:
4811  *              my_struct       Specifies the parsing structure.
4812  *              token_value     Specifies the token to match
4813  *              remove_flag     Specifies whether to clear the look ahead
4814  *                              value. If True, will set the look ahead
4815  *                              parsed value to invalid iff token_value
4816  *                              equals the parsed look ahead value.
4817  *
4818  * Returns:      0 if token_value matched parsed value,
4819  *               1 if parsed value is invalid.
4820  *              -1 if parsed value is valid but token_value did not match.
4821  *
4822  * Purpose:
4823  *
4824  ******************************************************************************/
4825 static  int
4826 TestLookAhead(
4827     FormatStruct        *my_struct,
4828     enum SdlElement      token_value,
4829     _DtCvValue           end_flag,
4830     int                  remove_flag)
4831 {
4832     if (my_struct->parsed == SdlElementNone)
4833         return 1;
4834
4835     if (my_struct->parsed == token_value && my_struct->end_flag == end_flag)
4836       {
4837         if (remove_flag == True)
4838           {
4839             my_struct->parsed = SdlElementNone;
4840             if (my_struct->remember != NULL)
4841               {
4842                 free (my_struct->remember);
4843                 my_struct->remember = NULL;
4844               }
4845           }
4846         return 0;
4847       }
4848
4849     return -1;
4850 }
4851
4852 /******************************************************************************
4853  * Function:    int MatchSDLElement (FormatStruct my_struct, sdl_string,
4854  *                                      int sdl_element, sig_chars)
4855  *
4856  * Parameters:
4857  *
4858  * Returns:     0 if successful, -1 if errors
4859  *
4860  * Purpose:     Looks for the specific element.
4861  *
4862  ******************************************************************************/
4863 static  int
4864 MatchSDLElement(
4865     FormatStruct        *my_struct,
4866     const char          *sdl_string,
4867     enum SdlElement      sdl_element,
4868     int                  sig_chars,
4869     _DtCvValue           end_flag)
4870 {
4871     int    i;
4872
4873     i = TestLookAhead(my_struct, sdl_element, end_flag, True);
4874
4875     if ( i != 1)
4876         return i;
4877
4878     return (_DtHelpCeMatchSdlElement(my_struct->my_file,sdl_string,sig_chars));
4879 }
4880
4881 /******************************************************************************
4882  * Function:    void SetAttributeFlag (
4883  *
4884  ******************************************************************************/
4885 static  void
4886 SetAttributeFlag(
4887     ElementInfoPtr      cur_info,
4888     unsigned long       attr_define)
4889 {
4890     unsigned long  flag = attr_define & ~(VALUE_MASK);
4891
4892     switch (attr_define & VALUE_MASK)
4893       {
4894         case ENUM_VALUE:
4895                 cur_info->enum_values |= flag;
4896                 break;
4897         case STRING1_VALUE:
4898                 cur_info->str1_values |= flag;
4899                 break;
4900         case STRING2_VALUE:
4901                 cur_info->str2_values |= flag;
4902                 break;
4903         case NUMBER_VALUE:
4904                 cur_info->num_values |= flag;
4905                 break;
4906
4907       }
4908 }
4909
4910 /******************************************************************************
4911  * Function:    void InitAttributes(SDLAttrStruct *as,
4912  *                                              SDLElementAttrList *attr_list)
4913  *
4914  * Parameters:
4915  *
4916  * Returns:     Attribute Processed if successful, -1 if errors
4917  *
4918  * Purpose:     Looks for the virtual page beginning.
4919  *
4920  ******************************************************************************/
4921 static  void
4922 InitAttributes(
4923     _DtCvSegment        *p_seg,
4924     _DtHelpFontHints    *font_specs,
4925     ElementInfo         *element_info,
4926     const SDLElementAttrList    *attr_list)
4927 {
4928    char         **strPtr1;
4929    char          *varOffset1 = NULL;
4930    SDLNumber     *numPtr1;
4931    SdlOption     *enumPtr1;
4932    SdlOption      defNum = _DtCvOPTION_BAD;
4933    const SDLAttribute *pAttr;
4934
4935    while (attr_list->sdl_attr_define != -1)
4936      {
4937         if (attr_list->def_string != NULL ||
4938                                 attr_list->sdl_value == SdlAttrValueImpliedDef)
4939           {
4940             pAttr = SDLAttributeList;
4941             while (pAttr->data_type != SdlAttrDataTypeInvalid &&
4942                     !(ATTRS_EQUAL(pAttr->data_type,
4943                         pAttr->sdl_attr_define, attr_list->sdl_attr_define)))
4944                 pAttr++;
4945
4946             if (pAttr->struct_type != SdlIgnore &&
4947                 pAttr->data_type != SdlAttrDataTypeInvalid &&
4948                 SDLIsAttrSet(*element_info, pAttr->sdl_attr_define) == False)
4949               {
4950                 /*
4951                  * determine which structure the information goes in
4952                  */
4953                 if (pAttr->struct_type == SdlFontSpecific)
4954                     varOffset1 = ((char *) font_specs);
4955                 else if (pAttr->struct_type == SdlContainerSpecific)
4956                     varOffset1 = ((char *)_SdlContainerPtrOfSeg(p_seg));
4957                 else if (pAttr->struct_type == SdlElementSpecific)
4958                     varOffset1 = ((char *) element_info);
4959                 else if (pAttr->struct_type == SdlTableSpecific)
4960                     varOffset1 = ((char *) element_info->w.table_info);
4961
4962                 varOffset1 = varOffset1 + pAttr->field_ptr;
4963                 if (pAttr->data_type == SdlAttrDataTypeNumber)
4964                   {
4965                     numPtr1  = (SDLNumber *) varOffset1;
4966                     *numPtr1 = ((SDLNumber)atoi(attr_list->def_string));
4967                   }
4968                 else if (pAttr->data_type == SdlAttrDataTypeEnum)
4969                   {
4970                     enumPtr1  = (SdlOption *) varOffset1;
4971                     (void) CheckOptionList (attr_list->sdl_attr_define,
4972                                         attr_list->def_string,
4973                 ((attr_list->sdl_attr_define & SDL_ATTR_CLASS) ? True : False),
4974                                         ElInfoClan(element_info),
4975                                         &defNum);
4976                     if ((attr_list->sdl_attr_define & SDL_ATTR_CLASS & ~(VALUE_MASK))
4977                                         && ElInfoClan(element_info) != defNum)
4978                         SetAttributeFlag(element_info,
4979                                                 attr_list->sdl_attr_define);
4980                     *enumPtr1 = defNum;
4981                   }
4982                 else if (SDLIsString1(pAttr->sdl_attr_define)
4983                                         ||
4984                          SDLIsString2(pAttr->sdl_attr_define))
4985                   {
4986                     strPtr1  = (char **) varOffset1;
4987                     *strPtr1 = (char *) attr_list->def_string;
4988                   }
4989               }
4990           }
4991        attr_list++;
4992      }
4993 }
4994
4995 #ifdef  DEBUG
4996 static char *
4997 ElToName(enum SdlElement el)
4998 {
4999     switch (el)
5000       {
5001         case SdlElementNone: return ("None");
5002         case SdlElementComment: return ("Comment");
5003         case SdlElementSdlDoc: return ("SdlDoc");
5004         case SdlElementVStruct: return ("VStruct");
5005         case SdlElementVirpage: return ("Virpage");
5006         case SdlElementHead: return ("Head");
5007         case SdlElementSubHead: return ("SubHead");
5008         case SdlElementSnb: return ("Snb");
5009         case SdlElementBlock: return ("Block");
5010         case SdlElementForm: return ("Form");
5011         case SdlElementPara: return ("Para");
5012         case SdlElementCPara: return ("CPara");
5013         case SdlElementFdata: return ("Fdata");
5014         case SdlElementFstyle: return ("Fstyle");
5015         case SdlElementFrowvec: return ("Frowvec");
5016         case SdlElementKey: return ("Key");
5017         case SdlElementCdata: return ("Cdata");
5018         case SdlElementGraphic: return ("Graphic");
5019         case SdlElementText: return ("Text");
5020         case SdlElementAudio: return ("Audio");
5021         case SdlElementVideo: return ("Video");
5022         case SdlElementAnimate: return ("Animate");
5023         case SdlElementCrossDoc: return ("CrossDoc");
5024         case SdlElementManPage: return ("ManPage");
5025         case SdlElementTextFile: return ("TextFile");
5026         case SdlElementSysCmd: return ("SysCmd");
5027         case SdlElementCallback: return ("Callback");
5028         case SdlElementScript: return ("Script");
5029         case SdlElementAnchor: return ("Anchor");
5030         case SdlElementLink: return ("Link");
5031         case SdlElementSwitch: return ("Switch");
5032         case SdlElementSnRef: return ("SnRef");
5033         case SdlElementRefItem: return ("RefItem");
5034         case SdlElementAltText: return ("AltText");
5035         case SdlElementSphrase: return ("Sphrase");
5036         case SdlElementRev: return ("Rev");
5037         case SdlElementSpc: return ("Spc");
5038         case SdlElementIf: return ("If");
5039         case SdlElementCond: return ("Cond");
5040         case SdlElementThen: return ("Then");
5041         case SdlElementElse: return ("Else");
5042         case SdlElementDocument: return ("Document");
5043         case SdlElementSgml: return ("Sgml");
5044         case SdlElementDocType: return ("DocType");
5045         case SdlElementLoids: return ("Loids");
5046         case SdlElementToss: return ("Toss");
5047         case SdlElementLoPhrases: return ("LoPhrases");
5048         case SdlElementPhrase: return ("Phrase");
5049         case SdlElementIndex: return ("Index");
5050         case SdlElementEntry: return ("Entry");
5051         case SdlElementRelDocs: return ("RelDocs");
5052         case SdlElementRelFile: return ("RelFile");
5053         case SdlElementNotes: return ("Notes");
5054         case SdlElementKeyStyle: return ("KeyStyle");
5055         case SdlElementHeadStyle: return ("HeadStyle");
5056         case SdlElementFormStyle: return ("FormStyle");
5057         case SdlElementFrmtStyle: return ("FrmtStyle");
5058         case SdlElementGrphStyle: return ("GrphStyle");
5059         case SdlElementId: return ("Id");
5060         case SdlElementBlockAsync: return ("BlockAsync");
5061         case SdlElementTitle: return ("Title");
5062         case SdlPcDataFollows: return ("Follows");
5063       }
5064     return ("Unknown");
5065 }
5066 #endif /* DEBUG */
5067
5068 /******************************************************************************
5069  * Function:    int ProcessSDLAttribute(FormatStruct my_struct,
5070  *                                              SDLAttrStruct *cur_attr,
5071  *                                              SDLElementAttrList *attr_list,
5072  *                                              char     *attr_name,
5073  *
5074  * Parameters:
5075  *
5076  * Returns:     0 if successful, -1 if errors
5077  *
5078  * Purpose:     Looks for the virtual page beginning.
5079  *
5080  ******************************************************************************/
5081 static  int
5082 ProcessSDLAttribute(
5083     FormatStruct        *my_struct,
5084     _DtCvSegment                *p_seg,
5085     _DtHelpFontHints    *font_specs,
5086     ElementInfo         *element_info,
5087     const SDLElementAttrList    *attr_list,
5088     char                *attr_name)
5089 {
5090     int          result;
5091     char        *attrValue;
5092     char        **strPtr;
5093     char         numBuf[DTD_NAMELEN+1];
5094     char        *varOffset1;
5095     SDLNumber   *numPtr1;
5096     SdlOption   *enumPtr1;
5097     SdlOption    attrNum;
5098     _DtHelpFontValue     fontNum;
5099     _DtHelpFontValue    *fontPtr1;
5100     const SDLAttribute *pAttr = SDLAttributeList;
5101
5102     /*
5103      * find the attribute in the list of SDL attributes
5104      * assumes that 'attr_name' has been lower cased, since all the
5105      * attribute names in SDLAttributeList are already lower case.
5106      */
5107     while (pAttr->data_type != SdlAttrDataTypeInvalid &&
5108               (*(pAttr->name) != *attr_name || strcmp(pAttr->name, attr_name)))
5109         pAttr++;
5110
5111     if (pAttr->data_type != SdlAttrDataTypeInvalid)
5112       {
5113
5114         /*
5115          * Check to see if this element contains an attribute with
5116          * the found value.
5117          */
5118         while (attr_list->sdl_attr_define != -1 &&
5119                         !ATTRS_EQUAL(pAttr->data_type, pAttr->sdl_attr_define,
5120                                                 attr_list->sdl_attr_define))
5121             attr_list++;
5122
5123         if (attr_list->sdl_attr_define == -1)
5124             return -1;
5125       }
5126
5127     /*
5128      * check it against the ones that are allowed for this element
5129      */
5130     if (pAttr->data_type != SdlAttrDataTypeInvalid)
5131       {
5132         switch (pAttr->data_type)
5133           {
5134             case SdlAttrDataTypeId:
5135                     result = _DtHelpCeGetSdlId(my_struct->my_file, &attrValue);
5136                     break;
5137
5138             case SdlAttrDataTypeNumber:
5139                     result = _DtHelpCeGetSdlNumber(my_struct->my_file, numBuf);
5140                     break;
5141
5142             case SdlAttrDataTypeCdata:
5143                     result = _DtHelpCeGetSdlAttributeCdata(my_struct->my_file,
5144                                                     False, &attrValue);
5145                     break;
5146
5147             case SdlAttrDataTypeFont:
5148                     result = _DtHelpCeGetSdlAttributeCdata(my_struct->my_file,
5149                                                     False, &attrValue);
5150                     if (result != -1)
5151                         result = CheckFontList (attr_list->sdl_attr_define,
5152                                                      attrValue, &fontNum);
5153                     break;
5154
5155             case SdlAttrDataTypeEnum:
5156                     result = _DtHelpCeGetSdlAttributeCdata(my_struct->my_file,
5157                                                     False, &attrValue);
5158                     if (result != -1)
5159                         result = CheckOptionList (attr_list->sdl_attr_define,
5160                                                     attrValue, False,
5161                                                     (SdlOption) _DtCvOPTION_BAD,
5162                                                     &attrNum);
5163                     break;
5164
5165             default:
5166                     printf ("hit unknown in processing attribute\n");
5167                     result = -1;
5168                     break;
5169           }
5170
5171         if (result == 0)
5172           {
5173             if (pAttr->struct_type != SdlIgnore)
5174               {
5175                 /*
5176                  * determine which structure the information goes in
5177                  */
5178                 if (pAttr->struct_type == SdlFontSpecific)
5179                     varOffset1 = ((char *) font_specs);
5180                 else if (pAttr->struct_type == SdlContainerSpecific)
5181                     varOffset1 = ((char *)_SdlContainerPtrOfSeg(p_seg));
5182                 else if (pAttr->struct_type == SdlElementSpecific)
5183                     varOffset1 = ((char *) element_info);
5184                 else if (pAttr->struct_type == SdlTableSpecific)
5185                     varOffset1 = ((char *) element_info->w.table_info);
5186
5187                 varOffset1 = varOffset1 + pAttr->field_ptr;
5188                 if (pAttr->data_type == SdlAttrDataTypeNumber)
5189                   {
5190                     numPtr1  = (SDLNumber *) varOffset1;
5191                     *numPtr1 = ((SDLNumber) atoi(numBuf));
5192                   }
5193                 else if (pAttr->data_type == SdlAttrDataTypeEnum)
5194                   {
5195                     enumPtr1  = (SdlOption *) varOffset1;
5196                     *enumPtr1 = attrNum;
5197     
5198                     free(attrValue);
5199                   }
5200                 else if (pAttr->data_type == SdlAttrDataTypeFont)
5201                   {
5202                     fontPtr1  = (_DtHelpFontValue *) varOffset1;
5203                     *fontPtr1 = fontNum;
5204     
5205                     free(attrValue);
5206                   }
5207                 else
5208                   {
5209                     strPtr = (char **) varOffset1;
5210                     *strPtr = attrValue;
5211                   }
5212               }
5213             else if (SdlAttrDataTypeNumber != pAttr->data_type)
5214                 free(attrValue);
5215             SetAttributeFlag(element_info, pAttr->sdl_attr_define);
5216           }
5217         return result;
5218       }
5219
5220     return -1;
5221 }
5222
5223 /******************************************************************************
5224  * Function:    int VerifyAttrList (
5225  *                                              SDLElementAttrList *attr_list)
5226  *
5227  * Parameters:
5228  *
5229  * Returns:     Attribute Processed if successful, -1 if errors
5230  *
5231  * Purpose:     Looks for the virtual page beginning.
5232  *
5233  ******************************************************************************/
5234 static  int
5235 VerifyAttrList(
5236     ElementInfoPtr               el_info,
5237     const SDLElementAttrList    *attr_list)
5238 {
5239     long  value = 0;
5240     while (attr_list->sdl_attr_define != -1)
5241       {
5242         if (attr_list->sdl_value == SdlAttrValueRequired)
5243           {
5244             switch (attr_list->sdl_attr_define & VALUE_MASK)
5245               {
5246                 case ENUM_VALUE:
5247                                 /*
5248                                  * mask off the minor number
5249                                  */
5250                                 value = el_info->enum_values & ~(MINOR_MASK);
5251                                 break;
5252                 case STRING1_VALUE:
5253                                 value = el_info->str1_values;
5254                                 break;
5255                 case STRING2_VALUE:
5256                                 value = el_info->str2_values;
5257                                 break;
5258                 case NUMBER_VALUE:
5259                                 value = el_info->num_values;
5260                                 break;
5261               }
5262             if (!(attr_list->sdl_attr_define & value))
5263                 return -1;
5264           }
5265         attr_list++;
5266       }
5267
5268     return 0;
5269 }
5270
5271 /******************************************************************************
5272  * Function:    void MergeTossInfo (
5273  *                              _DtCvSegment *cur_element,
5274  *                              FormatStruct my_struct);
5275  *
5276  * Parameters:
5277  *
5278  * Returns:     nothing
5279  *
5280  * Purpose:     Looks for the virtual page beginning.
5281  *
5282  ******************************************************************************/
5283 static  void
5284 MergeTossInfo(
5285     FormatStruct        *my_struct,
5286     _DtCvSegment                *cur_contain,
5287     _DtHelpFontHints    *font_specs)
5288 {
5289     _DtCvSegment *tossSeg;
5290
5291     if (my_struct->toss == NULL)
5292         return;
5293
5294     tossSeg = _DtHelpCeMatchSemanticStyle (my_struct->toss,
5295                                 ElClan(my_struct),
5296                                 ElLevel(my_struct),
5297                                 ElSsi(my_struct));
5298     _DtHelpCeMergeSdlAttribInfo(tossSeg, cur_contain, font_specs,
5299                                 &(my_struct->el_info),
5300                                 &(my_struct->el_info.str1_values),
5301                                 &(my_struct->el_info.str2_values));
5302
5303     return;
5304 }
5305
5306 \f
5307 /*------------------------- Element Processing ------------------------------*/
5308 /******************************************************************************
5309  * Function:    int ParseElementStart (
5310  *                              FormatStruct my_struct,
5311  *                              int element, _DtCvValue process_flag);
5312  *
5313  * Parameters:
5314  *
5315  * Returns:     0 if successful, -1 if errors
5316  *
5317  * Purpose:     Looks for the virtual page beginning.
5318  *
5319  ******************************************************************************/
5320 static  int
5321 ParseElementStart(
5322     FormatStruct        *my_struct,
5323     SDLElementInfo       element,
5324     _DtCvValue           process_flag)
5325 {
5326     _DtCvSegment  *segPtr;
5327     _DtCvSegment  *newSeg;
5328     FrmtPrivateInfo *priv;
5329
5330     if (MatchSDLElement (my_struct, element.element_str, element.sdl_element,
5331                                         element.str_sig_chars, False) != 0)
5332         return -1;
5333         
5334     /*
5335      * remember what we are currently parsing
5336      */
5337     ElType(my_struct) = element.sdl_element;
5338
5339     /*
5340      * does this element possibly pull in different fonts?
5341      * if so, allocate a new font structure.
5342      */
5343     if (True == process_flag && element.new_fonts)
5344       {
5345         my_struct->my_fonts = AllocateFontInfo(my_struct);
5346         if (NULL == my_struct->my_fonts)
5347             return -1;
5348       }
5349
5350     /*
5351      * if Cdata or skipping information don't do anything else
5352      */
5353     if (element.sdl_to_gen == SdlToNone || process_flag == False)
5354         return 0;
5355
5356     /*
5357      * allocate a segment for this element
5358      */
5359     if (_DtHelpCeAllocSegment(my_struct->malloc_size,
5360                                 &(my_struct->alloc_size),
5361                                 &(my_struct->block_list), &segPtr) != 0)
5362         return -1;
5363
5364     /*
5365      * add this segment to the list when done
5366      */
5367     my_struct->add_seg = segPtr;
5368
5369     /*
5370      * Set the flags and initialize variables depending on the
5371      * type of general segment this element becomes.
5372      */
5373     switch (element.sdl_to_gen)
5374       {
5375         case SdlToContainer:
5376                 /*
5377                  * set the container flag and initialize its formatting
5378                  * information to the default.
5379                  */
5380                 segPtr->type = _DtCvSetTypeToContainer(segPtr->type);
5381                 _DtCvContainerOfSeg(segPtr) = DefFrmtSpecs;
5382                 _DtCvContainerLeadingOfSeg(segPtr) =
5383                                                 my_struct->ui_info->leading;
5384         
5385                 /*
5386                  * if this is a formatting type container, do some more work.
5387                  */
5388                 if (element.formatting)
5389                   {
5390                     const _DtCvContainer *active = my_struct->active_frmt;
5391
5392                     if (NULL == active) active = &DefFrmtSpecs;
5393
5394                     /*
5395                      * The margin information - it gets zero'ed
5396                      */
5397                     _DtCvContainerLMarginOfSeg(segPtr) = 0;
5398                     _DtCvContainerRMarginOfSeg(segPtr) = 0;
5399                     _DtCvContainerFMarginOfSeg(segPtr) = 0;
5400                     _DtCvContainerTMarginOfSeg(segPtr) = 0;
5401                     _DtCvContainerBMarginOfSeg(segPtr) = 0;
5402
5403                     /*
5404                      * inherit some of the formatting directives
5405                      */
5406                     _DtCvContainerVJustifyOfSeg(segPtr) =
5407                                         ContainerPtrToVJustify(active);
5408                     _DtCvContainerJustifyOfSeg(segPtr) =
5409                                         ContainerPtrToJustify(active);
5410                     /*
5411                      * break the connection with the previous data.
5412                      */
5413                     my_struct->prev_data = NULL;
5414                     _DtCvContainerListOfSeg(segPtr) = NULL;
5415         
5416                     /*
5417                      * check to see if these are controllers.
5418                      */
5419                     if (element.sdl_element == SdlElementHead ||
5420                                 SdlElementSubHead == element.sdl_element)
5421                         segPtr->type = _DtCvSetTypeToController(segPtr->type);
5422                     
5423                     /*
5424                      * make this the currently active formatting information
5425                      */
5426                     my_struct->active_frmt = &(_DtCvContainerOfSeg(segPtr));
5427                   }
5428                 break;
5429
5430         case SdlToMarker:
5431                 /*
5432                  * set the type; the attribute processing will set the id.
5433                  */
5434                 segPtr->type = _DtCvSetTypeToMarker(segPtr->type);
5435                 break;
5436
5437         case SdlToSnb:
5438                 /*
5439                  * set the type; the attribute processing will set the id.
5440                  * graphics only exist in a snb. You have to keep the
5441                  * id around until the graphic get resolved. So a graphic
5442                  * is a container with a region.
5443                  */
5444                 segPtr->type = _DtCvSetTypeToContainer(segPtr->type);
5445
5446                 /*
5447                  * remember the refitem type.
5448                  */
5449                 priv = FrmtPrivInfoPtr(segPtr);
5450                 priv->sdl_el_type = ElType(my_struct);
5451                 break;
5452
5453         case SdlToSpc:
5454                 /*
5455                  * set the type; the attribute processing will set the id.
5456                  */
5457                 segPtr->type = _DtCvSetTypeToRegion(segPtr->type);
5458                 break;
5459       }
5460
5461     if (my_struct->cur_link != -1)
5462       {
5463         segPtr->type = _DtCvSetTypeToHyperText(segPtr->type);
5464         segPtr->link_idx = my_struct->cur_link;
5465       }
5466
5467     switch (element.sdl_element)
5468       {
5469         case SdlElementSnb:
5470                 my_struct->resolve_font = _SdlFontModeNone;
5471                 my_struct->snb          = segPtr;
5472                 my_struct->prev_data    = NULL;
5473                 break;
5474
5475         case SdlElementAltText:
5476                 segPtr->type = _DtCvSetTypeToNonBreak(segPtr->type);
5477                 break;
5478
5479         case SdlElementForm:
5480                 /*
5481                  * allocate a table for all the information
5482                  */
5483                 if (_DtHelpCeAllocSegment(my_struct->malloc_size,
5484                                 &(my_struct->alloc_size),
5485                                 &(my_struct->block_list), &newSeg) != 0)
5486                     return -1;
5487
5488                 newSeg->type = _DtCvSetTypeToTable(newSeg->type);
5489                 _DtCvJustifyCharsOfTableSeg(newSeg) = NULL;
5490
5491                 /*
5492                  * set the my_struct pointer to this table so that
5493                  * as the fstyle and frowec elements are parsed, the
5494                  * data goes directly into this table.
5495                  */
5496                 ElTable(my_struct) = newSeg;
5497                 break;
5498       }
5499
5500     return 0;
5501
5502 } /* End ParseElementStart */
5503
5504 /******************************************************************************
5505  * Function:    int ParseElementAttr (
5506  *                                      FormatStruct my_struct,
5507  *                                      SDLElementAttrList *attribs)
5508  *
5509  * Parameters:
5510  *
5511  * Returns:     0 if successful, -1 if errors
5512  *
5513  * Purpose:     Looks for the virtual page attributes.
5514  *
5515  ******************************************************************************/
5516 static  int
5517 ParseElementAttr(
5518     FormatStruct        *my_struct,
5519     enum SdlElement      cur_element,
5520     const SDLElementAttrList    *attribs,
5521     _DtCvValue           flag,
5522     _DtCvValue           process_flag)
5523 {
5524     int           result = 0;
5525     char          attribName[MAX_ATTRIBUTE_LENGTH + 2];
5526     _DtCvSegment *mySeg;
5527
5528     if (attribs == NULL || process_flag == False)
5529       {
5530         /*
5531          * No attributes - is there cdata in here?
5532          */
5533         if (flag || attribs != NULL)
5534             result = _DtHelpCeSkipCdata (my_struct->my_file,
5535                         (cur_element == SdlElementDocType ? True : False));
5536
5537         /*
5538          * get the element's end.
5539          */
5540         if (result != -1)
5541             result = _DtHelpCeGetSdlAttribute(my_struct->my_file,
5542                                                 MAX_ATTRIBUTE_LENGTH,
5543                                                 attribName);
5544
5545         /*
5546          * _DtHelpCeGetSdlAttribute should return 1, meaning it found
5547          * the >
5548          */
5549         if (result != 1)
5550             return -1;
5551         return 0;
5552       }
5553
5554     /*
5555      * clean and initialize the attributes for this element.
5556      */
5557     my_struct->el_info.enum_values = 0;
5558     my_struct->el_info.num_values = 0;
5559     my_struct->el_info.str1_values = 0;
5560     my_struct->el_info.str2_values = 0;
5561
5562     mySeg = my_struct->add_seg;
5563     InitAttributes(mySeg, my_struct->my_fonts, &(my_struct->el_info), attribs);
5564
5565     /*
5566      * clear the colJ and colW
5567      */
5568     if (SdlElementForm == ElType(my_struct))
5569       {
5570         ElTableColJStr(my_struct) = NULL;
5571         ElTableColWStr(my_struct) = NULL;
5572       }
5573
5574     /*
5575      * force the default of subheading orientation to heads as below the head.
5576      */
5577     if (ElType(my_struct) == SdlElementSubHead)
5578         _DtCvContainerVOrientOfSeg(mySeg) = _DtCvJUSTIFY_BOTTOM;
5579
5580     do {
5581         result = _DtHelpCeGetSdlAttribute(my_struct->my_file,
5582                                                 MAX_ATTRIBUTE_LENGTH,
5583                                                 attribName);
5584         if (result == 0)
5585             result = ProcessSDLAttribute(my_struct, mySeg,
5586                                         my_struct->my_fonts,
5587                                         &(my_struct->el_info),
5588                                         attribs,
5589                                         attribName);
5590     } while (result == 0);
5591
5592     if (result != -1)
5593         result = VerifyAttrList(&(my_struct->el_info), attribs);
5594
5595     if (result != -1)
5596       {
5597         if (cur_element == SdlElementVirpage
5598                                 ||
5599             SDLIsAttrSet(my_struct->el_info, SDL_ATTR_CLASS)
5600                                 ||
5601             SDLIsAttrSet(my_struct->el_info, SDL_ATTR_SSI)
5602                                 ||
5603             SDLIsAttrSet(my_struct->el_info, SDL_ATTR_LEVEL))
5604         MergeTossInfo(my_struct, mySeg, my_struct->my_fonts);
5605
5606         if (SDLIsStrAttrSet(my_struct->el_info, SDL_ATTR_LANGUAGE)
5607                 || SDLIsStrAttrSet(my_struct->el_info, SDL_ATTR_CHARSET))
5608             my_struct->mb_len = _DtHelpCeGetMbLen(
5609                         _DtHelpFontHintsLang(*(my_struct->my_fonts)),
5610                         _DtHelpFontHintsCharSet(*(my_struct->my_fonts)));
5611         /*
5612          * Do some specific work for containers.
5613          */
5614         if (NULL != mySeg && _DtCvIsSegContainer(mySeg))
5615           {
5616             /*
5617              * transfer any id or rid that got specified
5618              */
5619             if (SDLIsStrAttrSet(my_struct->el_info, SDL_ATTR_ID) ||
5620                         SDLIsStrAttrSet(my_struct->el_info, SDL_ATTR_RID))
5621               {
5622                 _DtCvContainerIdOfSeg(mySeg) = ElId(my_struct);
5623                 ClearAttrFlag(my_struct->el_info, SDL_ATTR_ID);
5624                 ClearAttrFlag(my_struct->el_info, SDL_ATTR_RID);
5625               }
5626
5627             /*
5628              * set the margins to absolute values
5629              */
5630             if (my_struct->ui_info->avg_char > 0)
5631               {
5632                 _DtCvContainerLMarginOfSeg(mySeg) =
5633                                         _DtCvContainerLMarginOfSeg(mySeg) *
5634                                                 my_struct->ui_info->avg_char;
5635
5636                 _DtCvContainerRMarginOfSeg(mySeg) =
5637                                         _DtCvContainerRMarginOfSeg(mySeg) *
5638                                                 my_struct->ui_info->avg_char;
5639
5640                 _DtCvContainerFMarginOfSeg(mySeg) =
5641                                         _DtCvContainerFMarginOfSeg(mySeg) *
5642                                                 my_struct->ui_info->avg_char;
5643
5644               }
5645             /*
5646              * set the container spacing to absolute values
5647              */
5648             if (my_struct->ui_info->line_height / 2 > 0)
5649               {
5650 /*
5651  * TODO .... take maximum! of spacing.
5652  */
5653                 TMarginOfSeg(mySeg) = TMarginOfSeg(mySeg) *
5654                                         (my_struct->ui_info->line_height / 2);
5655                 BMarginOfSeg(mySeg) = BMarginOfSeg(mySeg) *
5656                                         (my_struct->ui_info->line_height / 2);
5657
5658               }
5659
5660             /*
5661              * set the border width information
5662              */
5663             if (_DtCvBORDER_NONE != _DtCvContainerBorderOfSeg(mySeg))
5664                 _DtCvContainerLineWidthOfSeg(mySeg) =
5665                                                 my_struct->ui_info->line_width;
5666           }
5667       }
5668
5669     if (result == 1)
5670         result = 0;
5671
5672     return result;
5673
5674 } /* End ParseElementAttr */
5675
5676 /******************************************************************************
5677  * Function:    int ParseElementEnd (
5678  *                                      FormatStruct my_struct,
5679  *                                      int el_type);
5680  *
5681  * Parameters:
5682  *
5683  * Returns:     0 if successful, -1 if errors
5684  *
5685  * Purpose:     Looks for the virtual page beginning.
5686  *
5687  ******************************************************************************/
5688 static  int
5689 ParseElementEnd(
5690     FormatStruct        *my_struct,
5691     _DtCvSegment        *if_prev,
5692     SDLElementInfo       element,
5693     _DtCvValue           process_flag,
5694     _DtCvValue           end_flag)
5695 {
5696     char                *id;
5697     _DtCvSegment        *newSeg;
5698     _DtCvSegment        *segList;
5699
5700     if (MatchSDLElement (my_struct, element.element_end_str,
5701                 element.sdl_element, element.end_sig_chars, True) != 0 ||
5702                 (end_flag == False &&
5703                     _DtHelpCeFindSkipSdlElementEnd(my_struct->my_file) != 0))
5704         return -1;
5705
5706     if (process_flag == True)
5707       {
5708         _DtCvSegment  *pElement = my_struct->add_seg;
5709
5710         /*
5711          * if we aren't resolving the fonts for this element,
5712          * we need to save the toss information for later
5713          * when the element gets used in a table or snref.
5714          */
5715         if (_SdlFontModeResolve != my_struct->resolve_font &&
5716                 (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_CLASS)
5717                                 ||
5718                  SDLIsAttrSet(my_struct->el_info, SDL_ATTR_SSI)
5719                                 ||
5720                  SDLIsAttrSet(my_struct->el_info, SDL_ATTR_LEVEL)))
5721           {
5722             SdlMatchData *match;
5723
5724             /*
5725              * was a segment allocated for this element?
5726              * if not, we'll have to put our own special segment
5727              * around the segment list so the correct font inheritance
5728              * occurs. Later, this special segment will have to be
5729              * stripped out when the async blocks or snref item
5730              * is resolved.
5731              */
5732             if (NULL == pElement)
5733               {
5734                 if (_DtHelpCeAllocSegment(1, NULL, NULL, &pElement) != 0)
5735                     return -1;
5736
5737                 pElement->type = _DtCvSetTypeToContainer(pElement->type);
5738                 pElement->type = SetSdlWrapper(pElement->type);
5739                 _DtCvContainerListOfSeg(pElement) = my_struct->seg_list;
5740                 my_struct->seg_list = pElement;
5741               }
5742
5743             /*
5744              * has match data already been allocated for this element?
5745              */
5746             match = SegMatchDataPtr(pElement);
5747             if (NULL == match)
5748               {
5749                 match = (SdlMatchData *) malloc(sizeof(SdlMatchData));
5750                 if (NULL == match)
5751                     return -1;
5752               }
5753
5754             /*
5755              * save the clan, level and ssi of this element.
5756              */
5757             *match = my_struct->el_info.match;
5758             SegMatchData(pElement) = (void *) match;
5759             ClearAttrFlag(my_struct->el_info, SDL_ATTR_SSI);
5760           }
5761
5762         /*
5763          * attach the current segment list to the container's list
5764          */
5765         if (NULL != pElement && _DtCvIsSegContainer(pElement))
5766             _DtCvContainerListOfSeg(pElement) = my_struct->seg_list;
5767
5768         /*
5769          * check to see if the element has any data.
5770          * If not, can it (the element) be eleminated and free up memory?
5771          */
5772         if (NULL != pElement && my_struct->seg_list == NULL
5773             && element.elim_flag == True
5774             && ElType(my_struct) != SdlElementKey
5775             && TMarginOfSeg(pElement) == 0 && BMarginOfSeg(pElement) == 0)
5776           {
5777             _DtHelpFreeSegments(my_struct->add_seg, _DtCvFALSE,
5778                                         my_struct->ui_info->destroy_region,
5779                                         my_struct->ui_info->client_data);
5780
5781             if (ElType(my_struct) == SdlElementLink)
5782                 _DtLinkDbRemoveLink(my_struct->my_links,
5783                                                     my_struct->cur_link);
5784             my_struct->add_seg = NULL;
5785           }
5786         else
5787           {
5788             switch(ElType(my_struct))
5789               {
5790                 case SdlElementSnb:
5791                     my_struct->add_seg = NULL;
5792                     break;
5793
5794                 case SdlElementBlock:
5795                     if (ElTiming(my_struct) == SdlTimingAsync)
5796                       {
5797                         if (NULL != my_struct->add_seg)
5798                             AddToAsyncList(my_struct, my_struct->add_seg);
5799
5800                         my_struct->add_seg = NULL;
5801                       }
5802                     break;
5803
5804                 case SdlElementHead:
5805                 case SdlElementSubHead:
5806                     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_ABBREV)
5807                                 && ElAbbrev(my_struct) != NULL
5808                                 && strlen(ElAbbrev(my_struct)))
5809                       {
5810                         AbbrevOfSeg(my_struct->add_seg) =
5811                                                 (void *) ElAbbrev(my_struct);
5812                         ClearAttrFlag(my_struct->el_info, SDL_ATTR_ABBREV);
5813                       }
5814                     break;
5815
5816                 case SdlElementFdata:
5817                     ElTableList(my_struct) = ConvertToList(my_struct->seg_list);
5818                     break;
5819
5820                 case SdlElementLink:
5821                     CompressLinkSeg(my_struct->seg_list);
5822
5823                 case SdlElementKey:
5824                 case SdlElementSphrase:
5825                     /*
5826                      * move the content of the element up.
5827                      */
5828                     my_struct->add_seg = my_struct->seg_list;
5829
5830                     /*
5831                      * free the no longer needed segments.
5832                      */
5833                     if (NULL != pElement)
5834                       {
5835                         _DtCvContainerListOfSeg(pElement) = NULL;
5836                         _DtHelpFreeSegments(pElement, _DtCvFALSE,
5837                                         my_struct->ui_info->destroy_region,
5838                                         my_struct->ui_info->client_data);
5839                       }
5840                     break;
5841
5842                 case SdlElementForm:
5843                     /*
5844                      * get the segment list.
5845                      */
5846                     newSeg = ElTable(my_struct);
5847
5848                     /*
5849                      * include any async blocks into the table list.
5850                      */
5851                     if (ResolveAsyncBlock(my_struct, newSeg) != 0)
5852                         return -1;
5853
5854                     /*
5855                      * compress the table if possible down to just
5856                      * a container.
5857                      */
5858                     newSeg = CompressTable(my_struct, newSeg);
5859
5860                     /*
5861                      * add the table segment to the form's container list
5862                      * taking into account any heads for the form.
5863                      */
5864                     _DtCvNextSeg(newSeg) = _DtCvContainerListOfSeg(pElement);
5865                     _DtCvContainerListOfSeg(pElement) = newSeg;
5866                     break;
5867
5868                 case SdlElementIf:
5869                     if (ResolveIf (my_struct, if_prev))
5870                         return -1;
5871                     break;
5872
5873                 case SdlElementSnRef:
5874                     /*
5875                      * get the id of snref
5876                      */
5877                     id = NULL;
5878                     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_ID))
5879                         id = _DtCvContainerIdOfSeg(pElement);
5880
5881                     /*
5882                      * Resolve the snref to one of its items
5883                      */
5884                     newSeg = ResolveSnref(my_struct, pElement, id);
5885
5886                     /*
5887                      * if the snref got resolved, process
5888                      * otherwise, let it pass through. We'll try to
5889                      * resolve it later.
5890                      */
5891                     if (newSeg != pElement)
5892                       {
5893                         /*
5894                          * remember the segment list that we want
5895                          * to free. This includes the snref.
5896                          */
5897                         segList = pElement;
5898
5899                         /*
5900                          * if this <snref> had an id with it, then
5901                          * expand the <snref> to a marker segment
5902                          * (with the id) and a resolved refitem.
5903                          *
5904                          * Otherwise, eliminate the container.
5905                          */
5906                         if (NULL != id)
5907                           {
5908                             /*
5909                              * remember the segment list of the container.
5910                              * Since we are re-using the snref segment,
5911                              * we want to eliminate just the refitems of
5912                              * the snref and not the actual snref.
5913                              */
5914                             segList = _DtCvContainerListOfSeg(pElement);
5915
5916                             /*
5917                              * Move the refitem to be a sibling of the
5918                              * container.
5919                              */
5920                             _DtCvNextSeg(pElement) = newSeg;
5921
5922                             /*
5923                              * transfer the container id to a marker id
5924                              * and change the container into a marker.
5925                              */
5926                             _DtCvIdOfMarkerSeg(pElement) =
5927                                         _DtCvContainerIdOfSeg(pElement);
5928                             pElement->type =
5929                                         _DtCvSetTypeToMarker(pElement->type);
5930                             newSeg = pElement;
5931                           }
5932
5933                         /*
5934                          * free the no longer needed segments.
5935                          */
5936                         _DtHelpFreeSegments(segList, _DtCvFALSE,
5937                                         my_struct->ui_info->destroy_region,
5938                                         my_struct->ui_info->client_data);
5939                       }
5940
5941                     my_struct->add_seg = newSeg;
5942                     break;
5943               }
5944           }
5945
5946         /*
5947          * free the attributes for this element
5948          */
5949         FreeAttributes(ElType(my_struct),
5950                                 &(my_struct->el_info), my_struct->my_fonts);
5951
5952         /*
5953          * if this element can pull in new fonts, then a new font
5954          * structure was allocated for this element. Since we are
5955          * leaving the element, place the font structure in the
5956          * free list for possible reuse.
5957          */
5958         if (element.new_fonts && FreeFontInfo(my_struct) == -1)
5959             return -1;
5960       }
5961     else
5962         my_struct->add_seg = my_struct->seg_list;
5963
5964     if (element.formatting == True)
5965         my_struct->prev_data = NULL;
5966
5967     return 0;
5968
5969 } /* End ParseElementEnd */
5970 \f
5971 /******************************************************************************
5972  *
5973  * SDL Element Content Functions
5974  *
5975  *****************************************************************************/
5976 /******************************************************************************
5977  * Function:    int FindAndFix (
5978  *                                      _DtCvSegment *toss,
5979  *                                      _DtCvSegment *snb,
5980  *                                      _DtCvSegment *seg_list)
5981  *
5982  * Parameters:
5983  *
5984  * Returns:     0 if successful, -1 if errors
5985  *
5986  * Purpose:
5987  *
5988  ******************************************************************************/
5989 static  int
5990 FindAndFix(
5991     FormatStruct        *my_struct)
5992 {
5993     int           curLink  = my_struct->cur_link;
5994     _DtCvSegment *newSeg;
5995     _DtCvSegment *prevData = my_struct->prev_data;
5996     _DtCvSegment *lastSeg  = my_struct->last_seg;
5997     _DtCvSegment *tmpSeg;
5998
5999     _DtHelpFontHints *oldFonts = my_struct->my_fonts; 
6000
6001     /*
6002      * If the head has an snref in it, get the snb and resolve them
6003      */
6004     if (0 < my_struct->snref_cnt)
6005       {
6006         UnresSnref      *snref = my_struct->un_snrefs;
6007
6008         while (my_struct->snref_cnt)
6009           {
6010             /*
6011              * reset the structure to what it was at the time
6012              * this snref was encountered.
6013              */
6014             my_struct->prev_data = NULL;
6015             my_struct->last_seg  = NULL;
6016             my_struct->my_fonts  = &(snref->fonts);
6017             my_struct->cur_link  = snref->cur_link;
6018
6019             /*
6020              * resolve it.
6021              */
6022             newSeg = ResolveSnref(my_struct, snref->seg, NULL);
6023
6024             /*
6025              * free the snref items
6026              */
6027             _DtHelpFreeSegments(_DtCvContainerListOfSeg(snref->seg), _DtCvFALSE,
6028                                         my_struct->ui_info->destroy_region,
6029                                         my_struct->ui_info->client_data);
6030
6031             /*
6032              * find the end of the new segment's and have it point to
6033              * the next segments that the old segment points to.
6034              */
6035             if (NULL != newSeg)
6036               {
6037                 tmpSeg = newSeg;
6038                 while (NULL != _DtCvNextSeg(tmpSeg))
6039                     tmpSeg = _DtCvNextSeg(tmpSeg);
6040
6041                 _DtCvNextSeg(tmpSeg)  = _DtCvNextSeg(snref->seg);
6042                 _DtCvNextDisp(tmpSeg) = _DtCvNextDisp(snref->seg);
6043               }
6044
6045             /*
6046              * does the snref have an id?
6047              */
6048             if (NULL != snref->id)
6049               {
6050                 /*
6051                  * re-use the old snref, turning it into a marker
6052                  */
6053                 _DtCvIdOfMarkerSeg(snref->seg) = snref->id;
6054                 snref->seg->type = _DtCvSetTypeToMarker(snref->seg->type);
6055
6056                 /*
6057                  * set the next pointers on the old segment to
6058                  * the new segment.
6059                  */
6060                 if (NULL != newSeg)
6061                   {
6062                     _DtCvNextSeg(snref->seg)  = newSeg;
6063                     _DtCvNextDisp(snref->seg) = newSeg;
6064                   }
6065               }
6066
6067             /*
6068              * else move the resolved segment on top of the old snref.
6069              */
6070             else if (NULL != newSeg)
6071               {
6072                 /*
6073                  * free the private information. No longer needed.
6074                  */
6075                 free(snref->seg->client_use);
6076
6077                 /*
6078                  * now trounce the snref segment info.
6079                  */
6080                 *(snref->seg) = *newSeg;
6081
6082                 /*
6083                  * free the duplicate new segment.
6084                  */
6085                 if (_DtCvIsSegContainer(newSeg))
6086                     _DtCvContainerListOfSeg(newSeg) = NULL;
6087
6088                 free(newSeg);
6089               }
6090             /*
6091              * else there was no resolution, leave this segment as a NOOP.
6092              */
6093
6094             /*
6095              * go to the next unresolved snref
6096              */
6097             snref++;
6098             my_struct->snref_cnt--;
6099           }
6100
6101         free(my_struct->un_snrefs);
6102         my_struct->un_snrefs = NULL;
6103       }
6104
6105     my_struct->cur_link  = curLink;
6106     my_struct->prev_data = prevData;
6107     my_struct->last_seg  = lastSeg;
6108     my_struct->my_fonts  = oldFonts;
6109     return 0;
6110 }
6111
6112 /******************************************************************************
6113  * Function:    char *GetInterpCmd (SdlOption interp_type);
6114  *
6115  * Parameters:
6116  *
6117  * Returns:     0 if successful, -1 if errors
6118  *
6119  * Purpose:     Return the command associated with the interpreter type.
6120  *
6121  ******************************************************************************/
6122 static char *
6123 GetInterpCmd(SdlOption  interp_type)
6124 {
6125     const _CEInterpData *interp = InterpData;
6126
6127     while (interp->type != _DtCvOPTION_BAD)
6128       {
6129         if (interp->type == interp_type)
6130             return interp->cmd;
6131
6132         interp++;
6133       }
6134
6135     return NULL;
6136
6137 }
6138
6139 /******************************************************************************
6140  * Function:    int CheckForSnb (
6141  *                                              FormatStruct my_struct,
6142  *                                              int element_types,
6143  *                                              int exceptions);
6144  *
6145  * Parameters:
6146  *
6147  * Returns:     0 if successful, -1 if errors
6148  *
6149  * Purpose:     Looks for the virtual page attributes.
6150  *
6151  ******************************************************************************/
6152 static  int
6153 CheckForSnb(
6154     FormatStruct        *my_struct,
6155     SDLMask             *element_types,
6156     enum SdlElement      sig_element,
6157     SDLMask             *exceptions,
6158     SDLMask             *process_mask)
6159 {
6160     int    result = 0;
6161
6162     /*
6163      * If the head has an snref in it, get the snb and resolve them
6164      */
6165     if (my_struct->snref_used == True)
6166       {
6167         _DtCvSegment    *oldSegList = my_struct->seg_list;
6168         _DtCvSegment    *oldAddSeg  = my_struct->add_seg;
6169         _DtCvSegment    *oldPrevSeg = my_struct->prev_data;
6170         _DtCvSegment    *oldLastSeg = my_struct->last_seg;
6171
6172         my_struct->seg_list  = NULL;
6173         my_struct->add_seg   = NULL;
6174         my_struct->prev_data = NULL;
6175         my_struct->last_seg  = NULL;
6176
6177         result = ProcessSDLMarkup(my_struct, SdlElementSnb, SdlElementNone,
6178                                                 exceptions, process_mask);
6179         my_struct->seg_list  = oldSegList;
6180         my_struct->add_seg   = oldAddSeg;
6181         my_struct->prev_data = oldPrevSeg;
6182         my_struct->last_seg  = oldLastSeg;
6183
6184         /*
6185          * if no problems getting the snb, go through the items and
6186          * resolve the snrefs.
6187          */
6188         if (result != -1)
6189             result = FindAndFix(my_struct);
6190       }
6191
6192     return result;
6193
6194 } /* End CheckForSnb */
6195
6196 /******************************************************************************
6197  * Function:    int SetSaveSnref (
6198  *                                              FormatStruct my_struct,
6199  *                                              int element_types,
6200  *                                              int exceptions);
6201  *
6202  * Parameters:
6203  *
6204  * Returns:     0 if successful, -1 if errors
6205  *
6206  * Purpose:     Looks for the virtual page attributes.
6207  *
6208  ******************************************************************************/
6209 static  int
6210 SetSaveSnref(
6211     FormatStruct        *my_struct,
6212     SDLMask             *element_types,
6213     enum SdlElement      sig_element,
6214     SDLMask             *exceptions,
6215     SDLMask             *process_mask)
6216 {
6217     my_struct->save_snref = _DtCvTRUE;
6218     return 0;
6219
6220 } /* End SetSaveSnref */
6221
6222 /******************************************************************************
6223  * Function:    int ClearAndCheckSnref (
6224  *                                              FormatStruct my_struct,
6225  *                                              int element_types,
6226  *                                              int exceptions);
6227  *
6228  * Parameters:
6229  *
6230  * Returns:     0 if successful, -1 if errors
6231  *
6232  * Purpose:     Looks for the virtual page attributes.
6233  *
6234  ******************************************************************************/
6235 static  int
6236 ClearAndCheckSnref(
6237     FormatStruct        *my_struct,
6238     SDLMask             *element_types,
6239     enum SdlElement      sig_element,
6240     SDLMask             *exceptions,
6241     SDLMask             *process_mask)
6242 {
6243     int result = 0;
6244
6245     /*
6246      * reset the flag for saving snref elements
6247      */
6248     my_struct->save_snref = _DtCvFALSE;
6249
6250     /*
6251      * was any snrefs found? If so, resolve them now.
6252      */
6253     if (my_struct->snref_used == True)
6254         result = FindAndFix(my_struct);
6255
6256     return result;
6257
6258 } /* End ClearAndCheckSnref */
6259
6260 /******************************************************************************
6261  * Function:    int CheckType (
6262  *                                              FormatStruct my_struct,
6263  *                                              int element_types,
6264  *                                              int exceptions);
6265  *
6266  * Parameters:
6267  *
6268  * Returns:     0 if successful, -1 if errors
6269  *
6270  * Purpose:     Looks for the virtual page attributes.
6271  *
6272  ******************************************************************************/
6273 static  int
6274 CheckType(
6275     FormatStruct        *my_struct,
6276     SDLMask             *element_types,
6277     enum SdlElement      sig_element,
6278     SDLMask             *exceptions,
6279     SDLMask             *process_mask)
6280 {
6281     SdlOption    newOpt;
6282
6283     /*
6284      * cannot honor newlines in super or sub scripts.
6285      */
6286     newOpt = ElFrmtType(my_struct);
6287     if (SdlTypeLiteral == newOpt)
6288         newOpt = SdlTypeUnlinedLiteral;
6289     else if (SdlTypeLined == newOpt)
6290         newOpt = SdlTypeDynamic;
6291
6292     ElFrmtType(my_struct) = newOpt;
6293     if (SdlTypeDynamic != newOpt)
6294         my_struct->flags = _DtCvSetTypeToNonBreak(my_struct->flags);
6295
6296     if (SdlClassSub == ElClan(my_struct))
6297         my_struct->flags = _DtCvSetTypeToSubScript(my_struct->flags);
6298     else if (SdlClassSuper == ElClan(my_struct))
6299         my_struct->flags = _DtCvSetTypeToSuperScript(my_struct->flags);
6300
6301     /*
6302      * strip hypertext links
6303      */
6304     my_struct->cur_link = -1;
6305
6306     return 0;
6307
6308 } /* End CheckType */
6309
6310 /******************************************************************************
6311  * Function:    int SetType (
6312  *                                              FormatStruct my_struct,
6313  *                                              int element_types,
6314  *                                              int exceptions);
6315  *
6316  * Parameters:
6317  *
6318  * Returns:     0 if successful, -1 if errors
6319  *
6320  * Purpose:     Looks for the virtual page attributes.
6321  *
6322  ******************************************************************************/
6323 static  int
6324 SetType(
6325     FormatStruct        *my_struct,
6326     SDLMask             *element_types,
6327     enum SdlElement      sig_element,
6328     SDLMask             *exceptions,
6329     SDLMask             *process_mask)
6330 {
6331     if (ElType(my_struct) == SdlElementSphrase)
6332       {
6333         ContainerPtrToType(my_struct->active_frmt) =
6334                                    (_DtCvFrmtOption) SdlTypeLiteral;
6335         ElFrmtType(my_struct)                      = SdlTypeLiteral;
6336         my_struct->flags                           = 0;
6337       }
6338     else
6339         ElFrmtType(my_struct) = SdlTypeCdata;
6340
6341     if (SdlElementScript == ElType(my_struct))
6342       {
6343         /*
6344          * remember the interpretor value
6345          */
6346         FrmtPrivateInfo *priv = FrmtPrivInfoPtr(my_struct->add_seg);
6347
6348         priv->interp  = ElInterp(my_struct);
6349       }
6350
6351     return 0;
6352
6353 } /* End SetType */
6354
6355 /******************************************************************************
6356  * Function:    int ElseInfo (
6357  *                                              FormatStruct my_struct,
6358  *                                              int element_types,
6359  *                                              int exceptions);
6360  *
6361  * Parameters:
6362  *
6363  * Returns:     0 if successful, -1 if errors
6364  *
6365  * Purpose:     Looks for the virtual page attributes.
6366  *
6367  ******************************************************************************/
6368 static  int
6369 IfInfo(
6370     FormatStruct        *my_struct,
6371     SDLMask             *element_types,
6372     enum SdlElement      sig_element,
6373     SDLMask             *exceptions,
6374     SDLMask             *process_mask)
6375 {
6376     if (ElType(my_struct) == SdlElementIf)
6377       {
6378         my_struct->then_prev = NULL;
6379         my_struct->else_prev = NULL;
6380       }
6381     else if (ElType(my_struct) == SdlElementThen)
6382         my_struct->then_prev = my_struct->prev_data;
6383     else /* if (ElType(my_struct) == SdlElementElse) */
6384         my_struct->else_prev = my_struct->prev_data;
6385
6386     return 0;
6387
6388 } /* End IfInfo */
6389
6390 /******************************************************************************
6391  * Function:    int MarkFound (
6392  *                                              FormatStruct my_struct,
6393  *                                              int element_types,
6394  *                                              int exceptions);
6395  *
6396  * Parameters:
6397  *
6398  * Returns:     0 if successful, -1 if errors
6399  *
6400  * Purpose:     Looks for the virtual page attributes.
6401  *
6402  ******************************************************************************/
6403 static  int
6404 MarkFound(
6405     FormatStruct        *my_struct,
6406     SDLMask             *element_types,
6407     enum SdlElement      sig_element,
6408     SDLMask             *exceptions,
6409     SDLMask             *process_mask)
6410 {
6411     my_struct->snref_used = True;
6412
6413     /*
6414      * is there a newline hanging around that needs turning into a space?
6415      */
6416     if (SDLSearchMask(process_mask, SdlElementCdata)
6417         && my_struct->last_was_space == False && my_struct->last_was_nl == True)
6418       {
6419         _DtCvSegment *pSeg = my_struct->prev_data;
6420
6421         /*
6422          * tack the space onto the end of previous string if possible.
6423          */
6424         if (pSeg != NULL && _DtCvIsSegString(pSeg) &&
6425                         _DtCvIsSegRegChar(pSeg) && !(_DtCvIsSegNewLine(pSeg)))
6426           {
6427             char *strPtr;
6428             int   len = _DtCvStrLen(_DtCvStringOfStringSeg(pSeg), 0);
6429
6430             _DtCvStringOfStringSeg(pSeg) = (char *) realloc(
6431                                         _DtCvStringOfStringSeg(pSeg), len+2);
6432             if (_DtCvStringOfStringSeg(pSeg) == NULL)
6433                 return -1;
6434
6435              strPtr   = (char *) _DtCvStrPtr(_DtCvStringOfStringSeg(pSeg),
6436                                                                 0, len);
6437             *strPtr++ = ' ';
6438             *strPtr   = '\0';
6439           }
6440         else if (MySaveString(&(my_struct->seg_list), my_struct, " ",
6441                                 my_struct->cur_link, 1, False ) != 0)
6442             return -1;
6443
6444         my_struct->last_was_space = True;
6445         my_struct->last_was_nl    = False;
6446       }
6447
6448     return 0;
6449
6450 } /* End MarkFound */
6451
6452 /******************************************************************************
6453  * Function:    int SaveItemInfo (
6454  *                                              FormatStruct my_struct,
6455  *                                              int element_types,
6456  *                                              int exceptions);
6457  *
6458  * Parameters:
6459  *
6460  * Returns:     0 if successful, -1 if errors
6461  *
6462  * Purpose:     Looks for the virtual page attributes.
6463  *
6464  ******************************************************************************/
6465 static  int
6466 SaveItemInfo(
6467     FormatStruct        *my_struct,
6468     SDLMask             *element_types,
6469     enum SdlElement      sig_element,
6470     SDLMask             *exceptions,
6471     SDLMask             *process_mask)
6472 {
6473     _DtCvSegment         *refItem = my_struct->add_seg;
6474     SdlMatchData *info;
6475
6476     if (SDLSearchMask(process_mask, SdlElementRefItem) == False)
6477         return 0;
6478
6479     info = (SdlMatchData *) malloc (sizeof(SdlMatchData));
6480     if (NULL == info)
6481         return -1;
6482
6483     /*
6484      * save the clan, ssi & level of this refitem
6485      */
6486     *info = my_struct->el_info.match;
6487     SegMatchData(refItem) = (void *) info;
6488
6489     ClearAttrFlag(my_struct->el_info, SDL_ATTR_SSI);
6490
6491     return 0;
6492
6493 } /* End SaveItemInfo */
6494
6495 /******************************************************************************
6496  * Function:    int AllocateBlock (
6497  *                                              FormatStruct my_struct,
6498  *                                              int element_types,
6499  *                                              int exceptions);
6500  * Parameters:
6501  *
6502  * Returns:     0 if successful, -1 if errors
6503  *
6504  * Purpose:
6505  *
6506  ******************************************************************************/
6507 static  int
6508 AllocateBlock(
6509     FormatStruct        *my_struct,
6510     SDLMask             *element_types,
6511     enum SdlElement      sig_element,
6512     SDLMask             *exceptions,
6513     SDLMask             *process_mask)
6514 {
6515     /*
6516      * allocate a block of information all at once for later segments.
6517      * This, hopefully, will save processing time when later freed.
6518      *
6519      * Simply change the malloc_size in the formatting struct.
6520      */
6521     if (my_struct->add_seg != NULL)
6522       {
6523         if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_COUNT))
6524             my_struct->malloc_size = ElCount(my_struct);
6525         else
6526           {
6527             my_struct->malloc_size = 500;
6528             if (ElType(my_struct) == SdlElementToss)
6529                 my_struct->malloc_size = 160;
6530           }
6531       }
6532
6533     return 0;
6534
6535 } /* End AllocateBlock */
6536
6537 /******************************************************************************
6538  * Function:    int CleanUpBlock (
6539  *                                              FormatStruct my_struct,
6540  *                                              int element_types,
6541  *                                              int exceptions);
6542  * Parameters:
6543  *
6544  * Returns:     0 if successful, -1 if errors
6545  *
6546  * Purpose:
6547  *
6548  ******************************************************************************/
6549 static  int
6550 CleanUpBlock(
6551     FormatStruct        *my_struct,
6552     SDLMask             *element_types,
6553     enum SdlElement      sig_element,
6554     SDLMask             *exceptions,
6555     SDLMask             *process_mask)
6556 {
6557     /*
6558      * Go back to piece meal allocation.
6559      */
6560     my_struct->malloc_size = 1;
6561     return 0;
6562
6563 } /* End CleanUpBlock */
6564
6565 /******************************************************************************
6566  * Function:    int RegisterLink (
6567  *                                              FormatStruct my_struct,
6568  *                                              int element_types,
6569  *                                              int exceptions);
6570  *
6571  * Parameters:
6572  *
6573  * Returns:     0 if successful, -1 if errors
6574  *
6575  * Purpose:     Looks for the virtual page attributes.
6576  *
6577  ******************************************************************************/
6578 static  int
6579 RegisterLink(
6580     FormatStruct        *my_struct,
6581     SDLMask             *element_types,
6582     enum SdlElement      sig_element,
6583     SDLMask             *exceptions,
6584     SDLMask             *process_mask)
6585 {
6586     int          winType = _DtCvWindowHint_CurrentWindow;
6587     SDLId        rid     = _DtCvContainerIdOfSeg(my_struct->add_seg);
6588
6589     if (SDLSearchMask(process_mask, SdlElementLink) == False)
6590         return 0;
6591
6592     switch (ElWindow(my_struct))
6593       {
6594         case SdlWindowNew: winType = _DtCvWindowHint_NewWindow;
6595                         break;
6596         case SdlWindowPopup: winType = _DtCvWindowHint_PopupWindow;
6597                         break;
6598       }
6599
6600     my_struct->cur_link = _DtLinkDbAddLink(my_struct->my_links, NULL, rid,
6601                                 _DtCvLinkType_SameVolume, winType, NULL);
6602
6603     if (rid == NULL || my_struct->cur_link < 0)
6604         return -1;
6605
6606     /*
6607      * indicate that at least a blank should be saved for the link
6608      */
6609     my_struct->save_blank = True;
6610
6611     return 0;
6612
6613 } /* End RegisterLink */
6614
6615 /******************************************************************************
6616  * Function:    int ResolveIf (FormatStruct my_struct)
6617  *
6618  * Parameters:
6619  *
6620  * Returns:     0 if successful, -1 if errors
6621  *
6622  * Purpose:     Looks for the virtual page attributes.
6623  *
6624  ******************************************************************************/
6625 static  int
6626 ResolveIf(
6627     FormatStruct        *my_struct,
6628     _DtCvSegment        *prev_data)
6629 {
6630
6631     _DtCvSegment        *ifSeg       = my_struct->add_seg;
6632
6633     _DtCvSegment        *condSeg     = _DtCvContainerListOfSeg(ifSeg);
6634     _DtCvSegment        *condDataSeg = _DtCvContainerListOfSeg(condSeg);
6635
6636     _DtCvSegment        *thenSeg     = _DtCvNextSeg(condSeg);
6637     _DtCvSegment        *elseSeg     = _DtCvNextSeg(thenSeg);
6638
6639     _DtCvSegment        *resolveSeg  = NULL;
6640     _DtCvSegment        *nextDisp    = NULL;
6641     _DtCvSegment        *el          = NULL;
6642     char                *ifData      = NULL;
6643     char                *interpStr;
6644
6645     interpStr = GetInterpCmd(ElInterp(my_struct));
6646     if (NULL == interpStr)
6647         return -1;
6648
6649     if (_DtCvRunInterp(my_struct->ui_info->exec_filter,
6650                                 my_struct->ui_info->client_data,
6651                                 interpStr,
6652                         _DtCvStringOfStringSeg(condDataSeg), &ifData) == 0)
6653       {
6654         /*
6655          * Get the pointer to the next displayable item in the 'then'
6656          * list. This usually will point into the 'then' list,
6657          * but may point into the 'else' list.
6658          */
6659         if (my_struct->then_prev != NULL)
6660             nextDisp = my_struct->then_prev->next_disp;
6661
6662         /*
6663          * use the 'then' data
6664          */
6665         if (atoi (ifData) != 0)
6666           {
6667             el = thenSeg;
6668
6669             /*
6670              * check to make sure that the next_disp is NOT into the
6671              * 'else' list (because it's about to become a dangling
6672              * next_disp if it is!).
6673              */
6674             if (elseSeg != NULL)
6675               {
6676                 /*
6677                  * if the next displayable segment is in the 'else'
6678                  * list, null out the next displayable segement since
6679                  * there isn't anything in the 'then' list.
6680                  */
6681                 if (my_struct->then_prev == my_struct->else_prev)
6682                     nextDisp = NULL;
6683                 else
6684                     /*
6685                      * terminate the displayable segment list
6686                      * before the 'else' list.
6687                      */
6688                     my_struct->else_prev->next_disp = NULL;
6689               }
6690           }
6691         else if (elseSeg != NULL)
6692           {
6693             /*
6694              * use the 'else' data.
6695              */
6696             el = elseSeg;
6697
6698             /*
6699              * Get the next displayable item in the 'else' list.
6700              */
6701             if (my_struct->else_prev != NULL)
6702                 nextDisp = my_struct->else_prev->next_disp;
6703           }
6704
6705         if (el != NULL)
6706           {
6707             resolveSeg   = _DtCvContainerListOfSeg(el);
6708             _DtCvContainerListOfSeg(el) = NULL;
6709           }
6710
6711         free(ifData);
6712       }
6713
6714     /*
6715      * set the true next displayable pointer.
6716      */
6717     if (prev_data != NULL)
6718         prev_data->next_disp = nextDisp;
6719
6720     /*
6721      * set the previous displayable segment to the last displayable
6722      * segment in the 'if' clause; in case more displayable segments
6723      * follow.
6724      */
6725     my_struct->prev_data = nextDisp;
6726
6727     /*
6728      * free the no longer needed if construct
6729      */
6730     _DtHelpFreeSegments(my_struct->add_seg, _DtCvFALSE,
6731                                         my_struct->ui_info->destroy_region,
6732                                         my_struct->ui_info->client_data);
6733
6734     /*
6735      * set the add segment to the result of the if
6736      */
6737     my_struct->add_seg = resolveSeg;
6738
6739     return 0;
6740
6741 } /* End ResolveIf */
6742
6743 /******************************************************************************
6744  * Function:    int ZeroOrOne (
6745  *                                              FormatStruct my_struct,
6746  *                                              int element_types,
6747  *                                              int exceptions);
6748  *
6749  * Parameters:
6750  *
6751  * Returns:     0 if successful, -1 if errors
6752  *
6753  * Purpose:     Looks for the virtual page attributes.
6754  *
6755  ******************************************************************************/
6756 static  int
6757 ZeroOrOne(
6758     FormatStruct        *my_struct,
6759     SDLMask             *element_types,
6760     enum SdlElement      sig_element,
6761     SDLMask             *exceptions,
6762     SDLMask             *process_mask)
6763 {
6764     int    result = 0;
6765
6766     if (my_struct->parsed == SdlElementNone)
6767         result = _DtHelpCeReturnSdlElement(my_struct->my_file, SdlElementList,
6768                         SDLSearchMask(element_types, SdlElementCdata),
6769                                 &(my_struct->parsed), &(my_struct->remember),
6770                                 &(my_struct->end_flag));
6771
6772     if (result == 0 && my_struct->end_flag == False &&
6773                 SDLSearchMask(element_types, my_struct->parsed) == True)
6774       {
6775         /*
6776          * check to make sure this is *not* Cdata or if it is that the
6777          * PcDataFollows flag is *not* set.
6778          */
6779         if (my_struct->parsed != SdlElementCdata ||
6780                 SDLSearchMask(element_types, SdlPcDataFollows) == False)
6781             result = ParseSDL(my_struct, my_struct->parsed, sig_element,
6782                                                 exceptions, process_mask);
6783       }
6784     else if (result == 1) /* eof on compressed entry/file */
6785         result = 0;
6786
6787     return result;
6788 } /* End ZeroOrOne */
6789
6790 /******************************************************************************
6791  * Function:    int ZeroToN (
6792  *                                              FormatStruct my_struct,
6793  *                                              int element_types,
6794  *                                              int exceptions);
6795  *
6796  * Parameters:
6797  *
6798  * Returns:     0 if successful, -1 if errors
6799  *
6800  * Purpose:     Looks for the virtual page attributes.
6801  *
6802  ******************************************************************************/
6803 static  int
6804 ZeroToN(
6805     FormatStruct        *my_struct,
6806     SDLMask             *element_types,
6807     enum SdlElement      sig_element,
6808     SDLMask             *exceptions,
6809     SDLMask             *process_mask)
6810 {
6811     _DtCvValue done   = False;
6812     int       result = 0;
6813
6814     while (result == 0 && !done)
6815       {
6816         if (my_struct->parsed == SdlElementNone)
6817             result = _DtHelpCeReturnSdlElement(my_struct->my_file, SdlElementList,
6818                         SDLSearchMask(element_types, SdlElementCdata),
6819                                 &(my_struct->parsed), &(my_struct->remember),
6820                                 &(my_struct->end_flag));
6821
6822         if (result == 0 && my_struct->end_flag == False &&
6823                 SDLSearchMask(element_types, my_struct->parsed) == True)
6824           {
6825             /*
6826              * check to make sure this is *not* Cdata or if it is that the
6827              * PcDataFollows flag is *not* set.
6828              */
6829             if (my_struct->parsed != SdlElementCdata ||
6830                       SDLSearchMask(element_types, SdlPcDataFollows) == False)
6831                 result = ParseSDL(my_struct, my_struct->parsed,
6832                                         sig_element, exceptions, process_mask);
6833             else
6834                 done = True;
6835           }
6836         else
6837           {
6838             if (result == 1) /* eof on compressed entry/file */
6839                 result = 0;
6840             done   = True;
6841           }
6842       }
6843
6844     return result;
6845
6846 } /* End ZeroToN */
6847
6848 /******************************************************************************
6849  * Function:    int OneToN (
6850  *                                              FormatStruct my_struct,
6851  *                                              int element_types,
6852  *                                              int exceptions);
6853  *
6854  * Parameters:
6855  *
6856  * Returns:     0 if successful, -1 if errors
6857  *
6858  * Purpose:     Looks for the virtual page attributes.
6859  *
6860  ******************************************************************************/
6861 static  int
6862 OneToN(
6863     FormatStruct        *my_struct,
6864     SDLMask             *element_types,
6865     enum SdlElement      sig_element,
6866     SDLMask             *exceptions,
6867     SDLMask             *process_mask)
6868 {
6869     int    found  = False;
6870     int    result = 0;
6871     int    done   = False;
6872
6873     while (result == 0 && !done)
6874       {
6875         if (my_struct->parsed == SdlElementNone)
6876             result = _DtHelpCeReturnSdlElement(my_struct->my_file, SdlElementList,
6877                         SDLSearchMask(element_types, SdlElementCdata),
6878                                 &(my_struct->parsed), &(my_struct->remember),
6879                                 &(my_struct->end_flag));
6880
6881         if (result == 0 && my_struct->end_flag == False &&
6882                 SDLSearchMask(element_types, my_struct->parsed) == True)
6883           {
6884             found = True;
6885             result = ParseSDL(my_struct, my_struct->parsed, sig_element,
6886                                                 exceptions, process_mask);
6887           }
6888         else
6889             done = True;
6890       }
6891
6892     if (!found)
6893         result = -1;
6894
6895     return result;
6896
6897 } /* End OneToN */
6898
6899 /******************************************************************************
6900  * Function:    int OnlyOne (
6901  *                                              FormatStruct my_struct,
6902  *                                              int element_types,
6903  *                                              int exceptions);
6904  *
6905  * Parameters:
6906  *
6907  * Returns:     0 if successful, -1 if errors
6908  *
6909  * Purpose:     Looks for the virtual page attributes.
6910  *
6911  ******************************************************************************/
6912 static  int
6913 OnlyOne(
6914     FormatStruct        *my_struct,
6915     SDLMask             *element_types,
6916     enum SdlElement      sig_element,
6917     SDLMask             *exceptions,
6918     SDLMask             *process_mask)
6919 {
6920     _DtCvValue found  = False;
6921     int       result = 0;
6922
6923     if (my_struct->parsed == SdlElementNone)
6924         result = _DtHelpCeReturnSdlElement(my_struct->my_file, SdlElementList,
6925                         SDLSearchMask(element_types, SdlElementCdata),
6926                                 &(my_struct->parsed), &(my_struct->remember),
6927                                 &(my_struct->end_flag));
6928
6929     if (result == 0 && my_struct->end_flag == False &&
6930                 SDLSearchMask(element_types, my_struct->parsed) == True)
6931       {
6932         found = True;
6933         result = ParseSDL(my_struct, my_struct->parsed, sig_element,
6934                                                 exceptions, process_mask);
6935       }
6936
6937     if (!found)
6938         result = -1;
6939
6940     return result;
6941
6942 } /* End OnlyOne */
6943
6944 /******************************************************************************
6945  * Function:    int OnlyOneEach (
6946  *                                              FormatStruct my_struct,
6947  *                                              int element_types,
6948  *                                              int exceptions);
6949  *
6950  * Parameters:
6951  *
6952  * Returns:     0 if successful, -1 if errors
6953  *
6954  * Purpose:     Looks for the virtual page attributes.
6955  *
6956  ******************************************************************************/
6957 static  int
6958 OnlyOneEach(
6959     FormatStruct        *my_struct,
6960     SDLMask             *element_types,
6961     enum SdlElement      sig_element,
6962     SDLMask             *exceptions,
6963     SDLMask             *process_mask)
6964 {
6965     int       result = 0;
6966     enum SdlElement myEl;
6967     SDLMask     myMask[SDL_MASK_LEN];
6968
6969     SaveRestoreMask(myMask, element_types);
6970
6971     while (result == 0 && SDLCheckMask(myMask))
6972       {
6973         if (my_struct->parsed == SdlElementNone)
6974             result = _DtHelpCeReturnSdlElement(my_struct->my_file, SdlElementList,
6975                         SDLSearchMask(myMask, SdlElementCdata),
6976                                 &(my_struct->parsed), &(my_struct->remember),
6977                                 &(my_struct->end_flag));
6978
6979         if (result == 0 && my_struct->end_flag == False &&
6980                 SDLSearchMask(element_types, my_struct->parsed) == True)
6981           {
6982             myEl   = my_struct->parsed;
6983             result = ParseSDL(my_struct, my_struct->parsed, sig_element,
6984                                                 exceptions, process_mask);
6985
6986             SDLStripFromMask(myMask, myEl);
6987           }
6988         else
6989             result = -1;
6990       }
6991
6992     if (SDLCheckMask(myMask))
6993         result = -1;
6994
6995     return result;
6996
6997 } /* End OnlyOneEach */
6998
6999
7000 /******************************************************************************
7001  * Function:    int Cdata (FormatStruct my_struct,
7002  *                                      int cur_element, exceptions);
7003  *
7004  * Parameters:
7005  *
7006  * Returns:     0 if successful, -1 if errors
7007  *
7008  * Purpose:     Looks for the virtual page attributes.
7009  *
7010  ******************************************************************************/
7011 static  int
7012 Cdata(
7013     FormatStruct        *my_struct,
7014     SDLMask             *cur_element,
7015     enum SdlElement      sig_element,
7016     SDLMask             *exceptions,
7017     SDLMask             *process_mask)
7018 {
7019     int          i;
7020     int          reason;
7021     int          myLen    = 0;
7022     int          curLen   = my_struct->mb_len;
7023     int          multiLen = my_struct->mb_len;
7024     int          saveLen  = my_struct->mb_len;
7025     char         nonBreakChar;
7026     char        *string   = NULL;
7027     char         spaceStr[] = " ";
7028     char         dashStr[]  = "-";
7029     SdlOption type     = ElFrmtType(my_struct);
7030     _DtCvSegment        *pSeg       = NULL;
7031     _DtCvValue   nlToSpace   = True;
7032     _DtCvValue   processFlag = SDLSearchMask(process_mask, SdlElementCdata);
7033
7034     if (my_struct->ui_info->nl_to_space == 0)
7035         nlToSpace = False;
7036
7037     if (type == SdlTypeCdata)
7038       {
7039         /*
7040          * the element requires straight cdata for processing - i.e.
7041          * the data is going to be passed off to an interperter.
7042          * Therefore it doesn't want it broken up into different
7043          * byte length segments.
7044          *
7045          * Therefore, force the string save to put all the data into
7046          * one string.
7047          */
7048         saveLen = 1;
7049       }
7050
7051     if (my_struct->remember != NULL)
7052       {
7053         i   = 0;
7054         string  = my_struct->remember;
7055         myLen   = strlen(string);
7056         while (string[i] != '\0' && i < myLen)
7057           {
7058             if (multiLen != 1)
7059                 curLen = mblen (&string[i], multiLen);
7060
7061             if (curLen == 1)
7062               {
7063                 if (my_struct->last_was_nl == True)
7064                   {
7065                     if (MoveString(&string, &myLen, &i) == -1)
7066                         return -1;
7067
7068                     string[i++] = ' ';
7069                     my_struct->last_was_space = True;
7070                   }
7071
7072                 my_struct->last_was_nl = False;
7073                 my_struct->last_was_mb = False;
7074
7075                 if (string[i] == '\t')
7076                     string[i] = ' ';
7077     
7078                 if (string[i] == '&')
7079                   {
7080                     strmove (&string[i], &string[i+1]);
7081                     if (string[i] == '\0')
7082                       {
7083                         string[i] = BufFileGet(my_struct->my_file);
7084                         if (string[i] == BUFFILEEOF)
7085                             return -1;
7086                         string[i+1] = '\0';
7087                       }
7088     
7089                     /*
7090                      * is this an SGML numeric character reference
7091                      * entity?  if so, it should have the format
7092                      * '&#d[d[d]][;]' where 'ddd' represent characters
7093                      * of '0' to '9'.  The semi-colon is required iff
7094                      * the next character is a numeric character of '0'
7095                      * to '9'.  Otherwise it is optional.
7096                      */
7097                     if (string[i] == '#')
7098                       {
7099                         int j;
7100                         int value;
7101
7102 #define ESC_STRING_LEN  4
7103                         i++;
7104
7105                         /*
7106                          * Is there enough to room to process three digits
7107                          * and a possible semi-colon?
7108                          */
7109                         if (myLen - i < ESC_STRING_LEN)
7110                           {
7111                             /*
7112                              * lengthen the string so that it can contain
7113                              * the information
7114                              */
7115                             myLen  += ESC_STRING_LEN;
7116                             string  = (char *) realloc(string,
7117                                                 sizeof(char) * (myLen + 1));
7118                             if (string == NULL)
7119                                 return -1;
7120                           }
7121
7122                         /*
7123                          * now make sure that the entire numeric entity
7124                          * exists in the string.
7125                          */
7126                         j = i;
7127                         while ('0' <= string[i] && string[i] <= '9')
7128                             i++;
7129
7130                         /*
7131                          * run into the end of string before running
7132                          * into a delimiter? Fill out the escaped
7133                          * numeric character.
7134                          */
7135                         if (string[i] == '\0')
7136                           {
7137                             do
7138                               {
7139                                 string[i] = BufFileGet(my_struct->my_file);
7140                                 if (string[i] == BUFFILEEOF)
7141                                     return -1;
7142                                 i++;
7143                               } while (i < myLen && '0' <= string[i-1]
7144                                                         && string[i-1] <= '9');
7145                             /*
7146                              * end the string and back up to the last
7147                              * character
7148                              */
7149                             string[i] = '\0';
7150                             i--;
7151                           }
7152
7153                         /*
7154                          * the fourth character is a numeric, error
7155                          */
7156                         if ('0' <= string[i] && string[i] <= '9')
7157                             return -1;
7158
7159                         if (string[i] == ';')
7160                             i++;
7161
7162                         value = atoi(&string[j]);
7163                         if (value > 255)
7164                             return -1;
7165
7166                         /*
7167                          * smash over the pound sign with the 'real' value
7168                          * and copy the rest of the string to after it.
7169                          */
7170                         string[j-1] = (char) value;
7171                         strmove (&string[j], &string[i]);
7172                         i = j;
7173                       }
7174
7175                     if (string[i] == '\n')
7176                       {
7177                         if (ProcessString(my_struct, True, True, True,
7178                                         True,
7179                                         processFlag, string, saveLen, &i) != 0)
7180                             return -1;
7181                       }
7182                     else if (string[i] == ' ')
7183                       {
7184                         if (ProcessNonBreakChar(my_struct, processFlag,
7185                                         spaceStr, string, saveLen, &i) != 0)
7186                             return -1;
7187                       }
7188                     else if (string[i] == '-')
7189                       {
7190                         if (ProcessNonBreakChar(my_struct, processFlag,
7191                                         dashStr, string, saveLen, &i) != 0)
7192                             return -1;
7193                       }
7194                     else
7195                         my_struct->last_was_space = False;
7196                     i++;
7197                   }
7198                 else if (string[i] == '\n')
7199                   {
7200                     /*
7201                      * want to keep the newlines
7202                      */
7203                     if (type == SdlTypeCdata)
7204                         i++;
7205                     else if (type == SdlTypeDynamic ||
7206                                                 type == SdlTypeUnlinedLiteral)
7207                       {
7208                         if (my_struct->last_was_space == False)
7209                             my_struct->last_was_nl = True;
7210
7211                         strmove (&string[i], &string[i+1]);
7212                       }
7213                     else
7214                       {
7215                         string[i] = '\0';
7216                         if (processFlag == True &&
7217                                     MySaveString(&(my_struct->seg_list),
7218                                         my_struct, string, my_struct->cur_link,
7219                                         saveLen, True) != 0)
7220                           {
7221                             MyFree(string);
7222                             return -1;
7223                           }
7224     
7225                         strmove (string, &string[i+1]);
7226                         i = 0;
7227                       }
7228                   }
7229                 else if (string[i] == ' ')
7230                   {
7231                     if (False == my_struct->save_blank &&
7232                         type != SdlTypeLiteral && type != SdlTypeUnlinedLiteral
7233                                         && my_struct->last_was_space == True)
7234                         strmove (&string[i], &string[i+1]);
7235                     else
7236                         i++;
7237                     my_struct->last_was_space = True;
7238                   }
7239                 else
7240                   {
7241                     my_struct->last_was_space = False;
7242                     i++;
7243                   }
7244               }
7245             else if (curLen > 0)
7246               {
7247                 if (my_struct->last_was_nl == True)
7248                   {
7249                     if (nlToSpace == True || my_struct->last_was_mb == False)
7250                       {
7251                         if (MoveString(&string, &myLen, &i) == -1)
7252                             return -1;
7253
7254                         string[i++] = ' ';
7255                       }
7256                     else /* the last was a multibyte character, tighten up */
7257                       {
7258                         i--;
7259                         strmove (&string[i], &string[i+1]);
7260                       }
7261                   }
7262
7263                 my_struct->last_was_space = False;
7264                 my_struct->last_was_nl    = False;
7265                 my_struct->last_was_mb    = True;
7266                 i += curLen;
7267               }
7268             else if (curLen == 0)
7269                 return -1;
7270             else /* if (curLen < 0) */
7271               {
7272                 /*
7273                  * must finish up the character
7274                  */
7275                 int  len = i + 1;
7276
7277                 while (curLen < 0 && len - i < multiLen)
7278                   {
7279                     if (myLen <= len)
7280                       {
7281                         string = (char *) realloc(string, myLen + multiLen + 1);
7282                         if (string == NULL)
7283                             return -1;
7284                         myLen += multiLen;
7285                       }
7286
7287                     string[len] = BufFileGet(my_struct->my_file);
7288                     if (string[len++] == BUFFILEEOF)
7289                             return -1;
7290
7291                     string[len] = '\0';
7292                     curLen      = mblen (&string[i], multiLen);
7293                   }
7294
7295                 if (curLen < 0)
7296                     return -1;
7297               }
7298           }
7299
7300         if (processFlag == False)
7301           {
7302             free(string);
7303             string = NULL;
7304             myLen  = 0;
7305           }
7306
7307         my_struct->remember = NULL;
7308       }
7309
7310     do {
7311         my_struct->parsed = SdlElementNone;
7312         reason = _DtHelpCeGetSdlCdata(my_struct->my_file, type, multiLen,
7313                                 nlToSpace,
7314                                 &my_struct->last_was_space,
7315                                 &my_struct->last_was_nl,
7316                                 &my_struct->last_was_mb,
7317                                 &nonBreakChar,
7318                         (processFlag == True ? &string : ((char**)NULL)),
7319                                 &myLen);
7320         if (reason < 0)
7321             return -1;
7322
7323         if (string != NULL && *string != '\0')
7324           {
7325             /*
7326              * save the string.
7327              */
7328             if (MySaveString(&(my_struct->seg_list), my_struct,
7329                         string, my_struct->cur_link, saveLen,
7330                         (1 == reason ? True : False)) != 0)
7331               {
7332                 MyFree(string);
7333                 return -1;
7334               }
7335
7336             /*
7337              * indicate that a string was saved for the current link
7338              */
7339             my_struct->save_blank = False;
7340
7341             /*
7342              * null the temp buffer.
7343              */
7344             string[0] = '\0';
7345  
7346             /*
7347              * reset flags if we stopped because of a newline.
7348              */
7349             if (1 == reason && (SdlTypeLiteral == type || SdlTypeLined == type))
7350               {
7351                 my_struct->last_was_space = True;
7352                 my_struct->last_was_nl    = False;
7353               }
7354           }
7355         else if (reason == 1) /* stopped because of newline */
7356           {
7357             pSeg = my_struct->prev_data;
7358
7359             if (pSeg == NULL || _DtCvIsSegNewLine(pSeg))
7360               {
7361                 if (_DtHelpCeAllocSegment(my_struct->malloc_size,
7362                                 &(my_struct->alloc_size),
7363                                 &(my_struct->block_list), &pSeg) != 0)
7364                     return -1;
7365
7366                 pSeg->type   = _DtCvSetTypeToNoop(pSeg->type);
7367                 if (my_struct->prev_data != NULL)
7368                     my_struct->prev_data->next_disp = pSeg;
7369
7370                 my_struct->prev_data = pSeg;
7371                 _DtHelpCeAddSegToList(pSeg, &(my_struct->seg_list),
7372                                                 &(my_struct->last_seg));
7373               }
7374
7375             pSeg->type = _DtCvSetTypeToNewLine(pSeg->type);
7376
7377             my_struct->last_was_space = True;
7378             my_struct->last_was_nl    = False;
7379           }
7380
7381         /*
7382          * did we stop because of a non-breaking character?
7383          */
7384         if (2 == reason && True == processFlag)
7385           {
7386             /*
7387              * copy the non breaking character into a buffer.
7388              */
7389             if (1 > myLen)
7390               {
7391                 string = (char *) malloc (sizeof(char) * 32);
7392                 myLen  = 32;
7393               }
7394             string[0] = nonBreakChar;
7395             string[1] = '\0';
7396
7397             /*
7398              * save the string.
7399              */
7400             my_struct->flags = _DtCvSetTypeToNonBreak(my_struct->flags);
7401             if (MySaveString(&(my_struct->seg_list), my_struct,
7402                         string, my_struct->cur_link, saveLen, False) != 0)
7403               {
7404                 MyFree(string);
7405                 return -1;
7406               }
7407             my_struct->flags = my_struct->flags & ~(_DtCvNON_BREAK);
7408
7409             /*
7410              * indicate that the non-breaking character is considered
7411              * non-white space.
7412              */
7413             my_struct->last_was_space = False;
7414
7415             /*
7416              * indicate that a string was saved for the current link
7417              */
7418             my_struct->save_blank = False;
7419
7420             /*
7421              * null the temp buffer.
7422              */
7423             string[0] = '\0';
7424           }
7425
7426       } while (reason > 0);
7427
7428     MyFree(string);
7429     return 0;
7430
7431 } /* End Cdata */
7432
7433 /******************************************************************************
7434  * Function:    int ProcessEnterAttr (
7435  *                                      FormatStruct my_struct,
7436  *                                      int cur_element, exceptions);
7437  *
7438  * Parameters:
7439  *
7440  * Returns:     0 if successful, -1 if errors
7441  *
7442  * Purpose:
7443  *
7444  ******************************************************************************/
7445 static  int
7446 ProcessEnterAttr(
7447     FormatStruct        *my_struct,
7448     SDLMask             *cur_element,
7449     enum SdlElement      sig_element,
7450     SDLMask             *exceptions,
7451     SDLMask             *process_mask)
7452 {
7453     /*
7454      * save the enter string as part of this element's segment list
7455      */
7456     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_ENTER) &&
7457         ((int)strlen(ElEnter(my_struct))) > 0 &&
7458         MySaveString(&(my_struct->seg_list), my_struct, ElEnter(my_struct),
7459                         my_struct->cur_link, my_struct->mb_len, False) != 0)
7460             return -1;
7461
7462     return 0;
7463
7464 } /* End ProcessEnterAttr */
7465
7466 /******************************************************************************
7467  * Function:    int ProcessExitAttr (
7468  *                                      FormatStruct my_struct,
7469  *                                      int cur_element, exceptions);
7470  *
7471  * Parameters:
7472  *
7473  * Returns:     0 if successful, -1 if errors
7474  *
7475  * Purpose:
7476  *
7477  ******************************************************************************/
7478 static  int
7479 ProcessExitAttr(
7480     FormatStruct        *my_struct,
7481     SDLMask             *cur_element,
7482     enum SdlElement      sig_element,
7483     SDLMask             *exceptions,
7484     SDLMask             *process_mask)
7485 {
7486     /*
7487      * save the exit string as part of this element's segment list
7488      */
7489     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_EXIT) &&
7490         ((int)strlen(ElExit(my_struct))) > 0 &&
7491         MySaveString(&(my_struct->seg_list), my_struct, ElExit(my_struct),
7492                         my_struct->cur_link, my_struct->mb_len, False) != 0)
7493             return -1;
7494
7495     return 0;
7496
7497 } /* End ProcessExitAttr */
7498
7499 /******************************************************************************
7500  * Function:    int FakeEnd (FormatStruct my_struct,
7501  *                                      int cur_element, exceptions);
7502  *
7503  * Parameters:
7504  *
7505  * Returns:     0 if successful, -1 if errors
7506  *
7507  * Purpose:     Looks for the virtual page attributes.
7508  *
7509  ******************************************************************************/
7510 static  int
7511 FakeEnd(
7512     FormatStruct        *my_struct,
7513     SDLMask             *cur_element,
7514     enum SdlElement      sig_element,
7515     SDLMask             *exceptions,
7516     SDLMask             *process_mask)
7517 {
7518
7519     my_struct->end_flag  = True;
7520     my_struct->faked_end = True;
7521     MaskToValue(cur_element, my_struct->parsed);
7522
7523     return 0;
7524
7525 } /* End FakeEnd */
7526
7527 /******************************************************************************
7528  * Function:    int AddRowToTable (FormatStruct my_struct,
7529  *                                      int cur_element, exceptions);
7530  *
7531  * Parameters:
7532  *
7533  * Returns:     0 if successful, -1 if errors
7534  *
7535  * Purpose:     Looks for the virtual page attributes.
7536  *
7537  ******************************************************************************/
7538 static  int
7539 AddRowToTable(
7540     FormatStruct        *my_struct,
7541     SDLMask             *cur_element,
7542     enum SdlElement      sig_element,
7543     SDLMask             *exceptions,
7544     SDLMask             *process_mask)
7545 {
7546     if (SDLSearchMask(process_mask, SdlElementFrowvec) != False)
7547       {
7548         ElTableCellIds(my_struct) = (char **) _DtCvAddPtrToArray(
7549                                         (void **) ElTableCellIds(my_struct),
7550                                         ElTableCellId(my_struct));
7551
7552         if (NULL == ElTableCellIds(my_struct))
7553             return -1;
7554
7555         ClearAttrFlag(my_struct->el_info, SDL_ATTR_CELLS);
7556       }
7557
7558     return 0;
7559
7560 } /* End AddRowToTable */
7561
7562 /******************************************************************************
7563  * Function:    int SaveLangCharSet (
7564  *                                      FormatStruct my_struct,
7565  *                                      int cur_element, exceptions);
7566  *
7567  * Parameters:
7568  *
7569  * Returns:     0 if successful, -1 if errors
7570  *
7571  * Purpose:     Looks for the virtual page attributes.
7572  *
7573  ******************************************************************************/
7574 static  int
7575 SaveLangCharSet(
7576     FormatStruct        *my_struct,
7577     SDLMask             *cur_element,
7578     enum SdlElement      sig_element,
7579     SDLMask             *exceptions,
7580     SDLMask             *process_mask)
7581 {
7582     char **info;
7583
7584     if (SDLSearchMask(process_mask, SdlElementText) == False ||
7585         !(SDLIsAttrSet(my_struct->el_info, SDL_ATTR_LANGUAGE) ||
7586                 SDLIsAttrSet(my_struct->el_info, SDL_ATTR_CHARSET)))
7587         return 0;
7588
7589     info = (char **) calloc (2, sizeof(char *));
7590     if (NULL == info)
7591         return -1;
7592
7593     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_LANGUAGE))
7594         info[0] = ElLanguage(my_struct);
7595     if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_CHARSET))
7596         info[1] = ElCharSet(my_struct);
7597
7598     ClearAttrFlag(my_struct->el_info, SDL_ATTR_LANGUAGE);
7599     ClearAttrFlag(my_struct->el_info, SDL_ATTR_CHARSET);
7600
7601     _SdlSegLangChar(my_struct->add_seg) = (void *) info;
7602     return 0;
7603
7604 } /* End SaveLangCharSet */
7605
7606 /******************************************************************************
7607  * Function:    int CopyDocInfo (FormatStruct my_struct,
7608  *                                      int cur_element, exceptions);
7609  *
7610  * Parameters:
7611  *
7612  * Returns:     0 if successful, -1 if errors
7613  *
7614  * Purpose:     Looks for the virtual page attributes.
7615  *
7616  ******************************************************************************/
7617 static  int
7618 CopyDocInfo(
7619     FormatStruct        *my_struct,
7620     SDLMask             *cur_element,
7621     enum SdlElement      sig_element,
7622     SDLMask             *exceptions,
7623     SDLMask             *process_mask)
7624 {
7625     SDLDocInfo *docInfo;
7626
7627     if (SDLSearchMask(process_mask, SdlElementSdlDoc) == False)
7628         return 0;
7629
7630     docInfo = (SDLDocInfo *) malloc (sizeof(SDLDocInfo));
7631     if (NULL == docInfo)
7632         return -1;
7633
7634     *(docInfo) = ElDocInfo(my_struct);
7635     _SdlDocInfoPtrLanguage(docInfo) = strdup(ElLanguage(my_struct));
7636     _SdlDocInfoPtrCharSet(docInfo)  = strdup(ElCharSet(my_struct));
7637
7638     ClearAttrFlag(my_struct->el_info, SDL_ATTR_DOCID);
7639     ClearAttrFlag(my_struct->el_info, SDL_ATTR_SDLDTD);
7640     ClearAttrFlag(my_struct->el_info, SDL_ATTR_TIMESTAMP);
7641     ClearAttrFlag(my_struct->el_info, SDL_ATTR_FRST_PG);
7642     ClearAttrFlag(my_struct->el_info, SDL_ATTR_VERSION);
7643
7644     FrmtPrivInfoPtr(my_struct->add_seg)->doc_info = (void *) docInfo;
7645     return 0;
7646
7647 } /* End CopyDocInfo */
7648
7649 /******************************************************************************
7650  * Function:    int CopyAnchorId (FormatStruct my_struct,
7651  *                                      int cur_element, exceptions);
7652  *
7653  * Parameters:
7654  *
7655  * Returns:     0 if successful, -1 if errors
7656  *
7657  * Purpose:     Looks for the virtual page attributes.
7658  *
7659  ******************************************************************************/
7660 static  int
7661 CopyAnchorId(
7662     FormatStruct        *my_struct,
7663     SDLMask             *cur_element,
7664     enum SdlElement      sig_element,
7665     SDLMask             *exceptions,
7666     SDLMask             *process_mask)
7667 {
7668      _DtCvSegment        *mySeg = my_struct->add_seg;
7669
7670     /*
7671      * if we're not suppose to process this, skip.
7672      */
7673     if (SDLSearchMask(process_mask, SdlElementAnchor) == False)
7674         return 0;
7675
7676     /*
7677      * copy the id.
7678      */
7679     _DtCvIdOfMarkerSeg(mySeg) = ElId(my_struct);
7680
7681     /*
7682      * clear the flag so that it don't get freed.
7683      */
7684     ClearAttrFlag(my_struct->el_info, SDL_ATTR_ID);
7685
7686     return 0;
7687
7688 } /* End CopyDocInfo */
7689
7690 /******************************************************************************
7691  * Function:    int LoadGraphic (
7692  *                                      FormatStruct my_struct,
7693  *                                      int cur_element, exceptions);
7694  *
7695  * Parameters:
7696  *
7697  * Returns:     0 if successful, -1 if errors
7698  *
7699  * Purpose:     Looks for the virtual page attributes.
7700  *
7701  ******************************************************************************/
7702 static  int
7703 LoadGraphic(
7704     FormatStruct        *my_struct,
7705     SDLMask             *cur_element,
7706     enum SdlElement      sig_element,
7707     SDLMask             *exceptions,
7708     SDLMask             *process_mask)
7709 {
7710     int result = 0;
7711
7712     if (SDLSearchMask(process_mask, SdlElementGraphic) != False)
7713       {
7714         /*
7715          * get my container segment.
7716          */
7717         _DtCvSegment        *mySeg = my_struct->add_seg;
7718         _DtCvSegment        *cvRegion;  /* Canvas Engine Region */
7719
7720         result = -1;
7721
7722         /*
7723          * allocate a Canvas Engine region.
7724          */
7725         if (_DtHelpCeAllocSegment(1, NULL, NULL, &cvRegion) == 0)
7726           {
7727             /*
7728              * got memory for a region, now fill out the information.
7729              *
7730              * even if the load fails, we should just throw away
7731              * the graphic and continue.
7732              */
7733             result = 0;
7734             if (NULL != my_struct->ui_info->load_graphic &&
7735                 (*(my_struct->ui_info->load_graphic))(
7736                                 my_struct->ui_info->client_data,
7737                                 my_struct->vol_name,
7738                                 my_struct->id_string,
7739                                 ElSnbXid(my_struct),
7740                                 ElSnbFormat(my_struct),
7741                                 ElSnbMethod(my_struct),
7742                                 &(_DtCvWidthOfRegionSeg(cvRegion)),
7743                                 &(_DtCvHeightOfRegionSeg(cvRegion)),
7744                                 &(_DtCvInfoOfRegionSeg(cvRegion))) == 0)
7745               {
7746                 /*
7747                  * set the type on the region! And its ascent!
7748                  */
7749                 cvRegion->type = _DtCvSetTypeToRegion(cvRegion->type);
7750                 _DtCvAscentOfRegionSeg(cvRegion) = -1;
7751
7752                 /*
7753                  * set the seg list for the wrapper container.
7754                  */
7755                 _DtCvContainerListOfSeg(mySeg) = cvRegion;
7756
7757                 /*
7758                  * indicate the link has been fixed up
7759                  */
7760                 my_struct->save_blank = True;
7761               }
7762             else
7763               {
7764                 /*
7765                  * problems loading the graphic. Clean up!
7766                  */
7767                 MyFree(cvRegion);
7768               }
7769           }
7770       }
7771     return result;
7772
7773 } /* End LoadGraphic */
7774
7775 /******************************************************************************
7776  * Function:    int ColInfoToTableInfo (
7777  *                                      FormatStruct my_struct,
7778  *                                      int cur_element, exceptions);
7779  *
7780  * Parameters:
7781  *
7782  * Returns:     0 if successful, -1 if errors
7783  *
7784  * Purpose:     Looks for the virtual page attributes.
7785  *
7786  ******************************************************************************/
7787 static  int
7788 ColInfoToTableInfo(
7789     FormatStruct        *my_struct,
7790     SDLMask             *cur_element,
7791     enum SdlElement      sig_element,
7792     SDLMask             *exceptions,
7793     SDLMask             *process_mask)
7794 {
7795     if (SDLSearchMask(process_mask, SdlElementForm) != False)
7796       {
7797         int            i;
7798         int            mySize = ElTableColNum(my_struct);
7799         const char    *next;
7800         const char    *start     = NULL;
7801         const char    *last      = NULL;
7802         char         **colWidths = NULL;
7803         _DtCvFrmtOption  *colJust;
7804
7805         colWidths = (char **) malloc (sizeof(char *) * mySize);
7806         colJust   = (_DtCvFrmtOption *) malloc (sizeof(_DtCvFrmtOption)*mySize);
7807
7808         if (NULL == colWidths || NULL == colJust)
7809           {
7810             MyFree(colWidths);
7811             MyFree(colJust);
7812             return -1;
7813           }
7814
7815          /*
7816           * now process the column width specification.
7817           */
7818         next = ElTableColWStr(my_struct);
7819         if (NULL == next || '\0' == *next)
7820             next = "1";
7821
7822         for (i = 0; i < mySize; i++)
7823           {
7824             /* skip the leading spaces */
7825             while (' ' == *next) next++;
7826
7827             /* if the string really moved */
7828             if (last != next)
7829                 start = next;
7830
7831             /* go to the end of this specification */
7832             while (' ' != *next && '\0' != *next) next++;
7833
7834             /* duplicate the specification */
7835             colWidths[i] = strdup(start);
7836             if (NULL == colWidths[i])
7837                 return -1;
7838
7839             /* mark the end of the string */
7840             last = next;
7841           }
7842
7843          /*
7844           * now process the column justify specification.
7845           */
7846         next = ElTableColJStr(my_struct);
7847         if (NULL == next || '\0' == *next)
7848             next = NullOption;
7849
7850         for (i = 0; i < mySize; i++)
7851           {
7852             /* skip the leading spaces */
7853             while (' ' == *next) next++;
7854
7855             /* if the string really moved */
7856             if (last != next)
7857                 start = next;
7858
7859             /* go to the end of this specification */
7860             while (' ' != *next && '\0' != *next) next++;
7861
7862             /* determine the justification */
7863             switch (*start)
7864               {
7865                 case 'r':
7866                 case 'R': colJust[i] = _DtCvJUSTIFY_RIGHT;
7867                           break;
7868                 case 'c':
7869                 case 'C': colJust[i] = _DtCvJUSTIFY_CENTER;
7870                           break;
7871                 case 'd':
7872                 case 'D': colJust[i] = _DtCvJUSTIFY_NUM;
7873                           break;
7874                 case 'l':
7875                 case 'L': colJust[i] = _DtCvJUSTIFY_LEFT;
7876                           break;
7877
7878                 default : colJust[i] = _DtCvJUSTIFY_LEFT;
7879                           if (NullOption == start)
7880                               colJust[i] = _DtCvINHERIT;
7881                           break;
7882               }
7883
7884             /* mark the end of the string */
7885             last = next;
7886           }
7887
7888         ElTableColWidths(my_struct) = colWidths;
7889         ElTableColJust(my_struct)   = colJust;
7890       }
7891
7892     return 0;
7893
7894 } /* End ColInfoToTableInfo */
7895
7896 /******************************************************************************
7897  * Function:    int CopyIdInfo (FormatStruct my_struct,
7898  *                                      int cur_element, exceptions);
7899  *
7900  * Parameters:
7901  *
7902  * Returns:     0 if successful, -1 if errors
7903  *
7904  * Purpose:     Looks for the virtual page attributes.
7905  *
7906  ******************************************************************************/
7907 static  int
7908 CopyIdInfo(
7909     FormatStruct        *my_struct,
7910     SDLMask             *cur_element,
7911     enum SdlElement      sig_element,
7912     SDLMask             *exceptions,
7913     SDLMask             *process_mask)
7914 {
7915     SDLIdInfo *idInfo;
7916
7917     if (SDLSearchMask(process_mask, SdlElementId) == False)
7918         return 0;
7919
7920     idInfo = (SDLIdInfo *) malloc (sizeof(SDLIdInfo));
7921     if (NULL == idInfo)
7922         return -1;
7923
7924     *(idInfo) = ElIdInfo(my_struct);
7925     _SdlIdInfoPtrType(idInfo)   = ElFrmtType(my_struct);
7926     _SdlIdInfoPtrOffset(idInfo) = ElOffset(my_struct);
7927     _SdlIdInfoPtrRlevel(idInfo) = ElLevel(my_struct);
7928     _SdlIdInfoPtrRssi(idInfo)   = ElSsi(my_struct);
7929
7930     ClearAttrFlag(my_struct->el_info, SDL_ATTR_RID);
7931     ClearAttrFlag(my_struct->el_info, SDL_ATTR_RSSI);
7932
7933     FrmtPrivInfoPtr(my_struct->add_seg)->id_info = (void *) idInfo;
7934     return 0;
7935
7936 } /* End CopyIdInfo */
7937
7938 /******************************************************************************
7939  * Function:    int RegisterSnbLink (FormatStruct my_struct,
7940  *                                      int cur_element, exceptions);
7941  *
7942  * Parameters:
7943  *
7944  * Returns:     0 if successful, -1 if errors
7945  *
7946  * Purpose:     Looks for the virtual page attributes.
7947  *
7948  ******************************************************************************/
7949 static  int
7950 RegisterSnbLink(
7951     FormatStruct        *my_struct,
7952     SDLMask             *cur_element,
7953     enum SdlElement      sig_element,
7954     SDLMask             *exceptions,
7955     SDLMask             *process_mask)
7956 {
7957     int   linkType;
7958     int   len = 0;
7959     char  buffer[64] = "";
7960     char *fileSpec = NULL;
7961
7962     if (SDLSearchMask(process_mask, ElType(my_struct)) == False)
7963         return 0;
7964
7965     fileSpec = ElSnbXid(my_struct);
7966
7967     switch (ElType(my_struct))
7968       {
7969         case SdlElementCrossDoc:
7970                         linkType = _DtCvLinkType_CrossLink;
7971                         break;
7972
7973         case SdlElementManPage:
7974                         linkType = _DtCvLinkType_ManPage;
7975                         break;
7976
7977         case SdlElementTextFile:
7978                         if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_OFFSET))
7979                           {
7980                             sprintf(buffer, " %d", ElOffset(my_struct));
7981                             len += strlen(buffer);
7982                           }
7983                         if (SDLIsAttrSet(my_struct->el_info, SDL_ATTR_FORMAT))
7984                             len += strlen(ElSnbFormat(my_struct));
7985
7986                         /*
7987                          * create a new file spec for the link
7988                          */
7989                         if (0 < len)
7990                           {
7991                             len += strlen(ElSnbXid(my_struct) + 1);
7992
7993                             fileSpec = malloc(sizeof(char) * len);
7994                             if (NULL == fileSpec)
7995                                 return -1;
7996                         
7997                             strcpy(fileSpec, ElSnbXid(my_struct));
7998                             strcat(fileSpec, buffer);
7999                             strcat(fileSpec, ElSnbFormat(my_struct));
8000                           }
8001                         linkType = _DtCvLinkType_TextFile;
8002                         break;
8003
8004         case SdlElementSysCmd:
8005                         linkType = _DtCvLinkType_Execute;
8006                         break;
8007
8008         case SdlElementCallback:
8009                         linkType = _DtCvLinkType_AppDefine;
8010                         break;
8011
8012         default: return -1;
8013       }
8014
8015     if (0 > _DtLinkDbAddLink(my_struct->my_links,
8016                                 _DtCvContainerIdOfSeg(my_struct->add_seg),
8017                                 fileSpec,
8018                                 linkType,
8019                                 _DtCvWindowHint_Original,
8020                                 NULL))
8021         return -1;
8022
8023     if (fileSpec != ElSnbXid(my_struct))
8024         free(fileSpec);
8025
8026     return 0;
8027
8028 } /* End RegisterSnbLink */
8029
8030 /******************************************************************************
8031  * Function:    int RegisterSwitch (FormatStruct my_struct,
8032  *                                      int cur_element, exceptions);
8033  *
8034  * Parameters:
8035  *
8036  * Returns:     0 if successful, -1 if errors
8037  *
8038  * Purpose:     Looks for the virtual page attributes.
8039  *
8040  ******************************************************************************/
8041 static  int
8042 RegisterSwitch(
8043     FormatStruct        *my_struct,
8044     SDLMask             *cur_element,
8045     enum SdlElement      sig_element,
8046     SDLMask             *exceptions,
8047     SDLMask             *process_mask)
8048 {
8049     int          result = -1;
8050     char        *interpStr;
8051
8052     if (SDLSearchMask(process_mask, ElType(my_struct)) == False)
8053         return 0;
8054
8055     interpStr = GetInterpCmd(ElInterp(my_struct));
8056     if (NULL != interpStr)
8057         interpStr = strdup(interpStr);
8058
8059     if (NULL != interpStr)
8060       {
8061         if (0 == _DtLinkDbAddSwitch(my_struct->my_links,
8062                         _DtCvContainerIdOfSeg(my_struct->add_seg),
8063                         interpStr,
8064                         _DtCvStringOfStringSeg(my_struct->add_seg),
8065                         ElSwitchBranches(my_struct)))
8066             result = 0;
8067
8068         free(my_struct->add_seg);
8069         my_struct->add_seg = NULL;
8070       }
8071
8072     return result;
8073
8074 } /* End RegisterSwitch */
8075
8076 /******************************************************************************
8077  * Function:    int ResolveSpcInfo (FormatStruct my_struct,
8078  *                                      int cur_element, exceptions);
8079  *
8080  * Parameters:
8081  *
8082  * Returns:     0 if successful, -1 if errors
8083  *
8084  * Purpose:     Looks for the virtual page attributes.
8085  *
8086  ******************************************************************************/
8087 static  int
8088 ResolveSpcInfo(
8089     FormatStruct        *my_struct,
8090     SDLMask             *cur_element,
8091     enum SdlElement      sig_element,
8092     SDLMask             *exceptions,
8093     SDLMask             *process_mask)
8094 {
8095     _DtCvSegment  *mySeg = my_struct->add_seg;
8096
8097     if (SDLSearchMask(process_mask, ElType(my_struct)) != False)
8098       {
8099         /*
8100          * set the non break character flag so that the layout routines
8101          * will only wrap this to the next line if there is a space
8102          * before it.
8103          *
8104          * Also set the inline flag so that the layout routines don't
8105          * think that the region is a figure.
8106          */
8107         mySeg->type = _DtCvSetTypeToNonBreak(mySeg->type);
8108         mySeg->type = _DtCvSetTypeToInLine(mySeg->type);
8109
8110         /*
8111          * now establish the proper display linking.
8112          */
8113         if (my_struct->prev_data != NULL)
8114             my_struct->prev_data->next_disp = mySeg;
8115
8116         my_struct->prev_data  = mySeg;
8117         my_struct->save_blank = False;
8118
8119         /*
8120          * resolve the font hints.
8121          */
8122         if (_SdlFontModeResolve == my_struct->resolve_font)
8123             (*(my_struct->ui_info->resolve_spc))(
8124                         my_struct->ui_info->client_data,
8125                         ElLanguage(my_struct),
8126                         ElCharSet(my_struct),
8127                         *(my_struct->my_fonts),
8128                         ElSpcName(my_struct),
8129                         &(_DtCvInfoOfRegionSeg(my_struct->add_seg)),
8130                         &(_DtCvWidthOfRegionSeg(my_struct->add_seg)),
8131                         &(_DtCvHeightOfRegionSeg(my_struct->add_seg)),
8132                         &(_DtCvAscentOfRegionSeg(my_struct->add_seg)));
8133         else
8134           {
8135             _DtHelpDARegion *pReg;
8136             _DtHelpDASpcInfo *spcInfo;
8137
8138             /*
8139              * malloc a structure to hold the spc
8140              */
8141             pReg = (_DtHelpDARegion *) malloc (sizeof(_DtHelpDARegion));
8142             if (NULL == pReg)
8143                 return -1;
8144             
8145             /*
8146              * malloc the structure to hold the information needed to
8147              * create the spc later.
8148              */
8149             spcInfo = (_DtHelpDASpcInfo *) calloc (1, sizeof(_DtHelpDASpcInfo));
8150             if (NULL == spcInfo)
8151               {
8152                 free(pReg);
8153                 return -1;
8154               }
8155
8156             /*
8157              * remember the spc's name and fonts
8158              */
8159             spcInfo->name = ElSpcName(my_struct);
8160             if (_SdlFontModeSave == my_struct->resolve_font)
8161               {
8162                 spcInfo->spc_fonts = *(my_struct->my_fonts);
8163                 _DtHelpFontHintsLang(spcInfo->spc_fonts) =
8164                                                         ElLanguage(my_struct);
8165                 _DtHelpFontHintsCharSet(spcInfo->spc_fonts) =
8166                                                         ElCharSet(my_struct);
8167
8168                 if (-1 == _DtHelpDupFontHints(&(spcInfo->spc_fonts)))
8169                     return -1;
8170               }
8171
8172             /*
8173              * remember the spc's name
8174              */
8175             pReg->inited = False;
8176             pReg->type   = _DtHelpDASpc;
8177             pReg->handle = (_DtCvPointer) spcInfo;
8178
8179             _DtCvInfoOfRegionSeg(mySeg) = (_DtCvPointer) pReg;
8180             ClearAttrFlag(my_struct->el_info, SDL_ATTR_NAME);
8181           }
8182
8183       }
8184
8185     return 0;
8186
8187 } /* End ResolveSpcInfo */
8188
8189 /******************************************************************************
8190  * Function:    int CopyTossInfo (FormatStruct my_struct,
8191  *                                      int cur_element, exceptions);
8192  *
8193  * Parameters:
8194  *
8195  * Returns:     0 if successful, -1 if errors
8196  *
8197  * Purpose:     Looks for the virtual page attributes.
8198  *
8199  ******************************************************************************/
8200 static  int
8201 CopyTossInfo(
8202     FormatStruct        *my_struct,
8203     SDLMask             *cur_element,
8204     enum SdlElement      sig_element,
8205     SDLMask             *exceptions,
8206     SDLMask             *process_mask)
8207 {
8208     SDLTossInfo *tossInfo;
8209
8210     if (SDLSearchMask(process_mask, ElType(my_struct)) == False)
8211         return 0;
8212
8213     tossInfo = (SDLTossInfo *) malloc (sizeof(SDLTossInfo));
8214     if (NULL == tossInfo)
8215         return -1;
8216
8217     /*
8218      * save the flags
8219      */
8220     _SdlTossInfoPtrFlag1(tossInfo)     = ElFlag1(my_struct);
8221     _SdlTossInfoPtrFlag2(tossInfo)     = ElFlag2(my_struct);
8222     _SdlTossInfoPtrFlag3(tossInfo)     = ElFlag3(my_struct);
8223     _SdlTossInfoPtrFlag4(tossInfo)     = ElFlag4(my_struct);
8224
8225     /*
8226      * save the match data - level, ssi and class/clan.
8227      */
8228     _SdlTossInfoPtrRlevel(tossInfo)    = ElLevel(my_struct);
8229     _SdlTossInfoPtrSsi(tossInfo)       = ElSsi(my_struct);
8230     _SdlTossInfoPtrClan(tossInfo)      = ElClan(my_struct);
8231
8232     /*
8233      * save the table information (colj, colw) or the keystyle
8234      * enter/exit data.
8235      */
8236     _SdlTossInfoPtrStr1(tossInfo)      = ElString1(my_struct);
8237     _SdlTossInfoPtrStr2(tossInfo)      = ElString2(my_struct);
8238
8239     /*
8240      * save the element type.
8241      */
8242     _SdlTossInfoPtrType(tossInfo)      = ElType(my_struct);
8243
8244     /*
8245      * save the fonts - even if this toss style doesn't specify fonts.
8246      */
8247     _SdlTossInfoPtrFontSpecs(tossInfo) = *(my_struct->my_fonts);
8248
8249     /*
8250      * now clear string attributes
8251      */
8252     ClearAttrFlag(my_struct->el_info, SDL_ATTR_SSI);
8253
8254     /*
8255      * table specs.
8256      */
8257     ClearAttrFlag(my_struct->el_info, SDL_ATTR_COLW);
8258     ClearAttrFlag(my_struct->el_info, SDL_ATTR_COLJ);
8259
8260     /*
8261      * key style specs.
8262      */
8263     ClearAttrFlag(my_struct->el_info, SDL_ATTR_ENTER);
8264     ClearAttrFlag(my_struct->el_info, SDL_ATTR_EXIT);
8265
8266     /*
8267      * font specs
8268      */
8269     ClearAttrFlag(my_struct->el_info, SDL_ATTR_COLOR);
8270     ClearAttrFlag(my_struct->el_info, SDL_ATTR_XLFD);
8271     ClearAttrFlag(my_struct->el_info, SDL_ATTR_XLFDI);
8272     ClearAttrFlag(my_struct->el_info, SDL_ATTR_XLFDB);
8273     ClearAttrFlag(my_struct->el_info, SDL_ATTR_XLFDIB);
8274     ClearAttrFlag(my_struct->el_info, SDL_ATTR_TYPENAM);
8275     ClearAttrFlag(my_struct->el_info, SDL_ATTR_TYPENAMI);
8276     ClearAttrFlag(my_struct->el_info, SDL_ATTR_TYPENAMB);
8277     ClearAttrFlag(my_struct->el_info, SDL_ATTR_TYPENAMIB);
8278
8279     /*
8280      * set the internal pointer
8281      */
8282     _SdlSegTossInfo(my_struct->add_seg) = (void *) tossInfo;
8283
8284     /*
8285      * now re-initialize the font specifications back to the original
8286      * values
8287      */
8288     *(my_struct->my_fonts) = DefFontInfo;
8289
8290     return 0;
8291
8292 } /* End CopyTossInfo */
8293
8294 /******************************************************************************
8295  * Function:    int CopyEntryInfo (FormatStruct my_struct,
8296  *                                      int cur_element, exceptions);
8297  *
8298  * Parameters:
8299  *
8300  * Returns:     0 if successful, -1 if errors
8301  *
8302  * Purpose:     Looks for the virtual page attributes.
8303  *
8304  ******************************************************************************/
8305 static  int
8306 CopyEntryInfo(
8307     FormatStruct        *my_struct,
8308     SDLMask             *cur_element,
8309     enum SdlElement      sig_element,
8310     SDLMask             *exceptions,
8311     SDLMask             *process_mask)
8312 {
8313     SDLEntryInfo *entryInfo;
8314
8315     if (SDLSearchMask(process_mask, ElType(my_struct)) == False)
8316         return 0;
8317
8318     entryInfo = (SDLEntryInfo *) malloc (sizeof(SDLEntryInfo));
8319     if (NULL == entryInfo)
8320         return -1;
8321
8322     /*
8323      * save the strings.
8324      */
8325     *entryInfo = ElEntryInfo(my_struct);
8326
8327     /*
8328      * now clear the attributes
8329      */
8330     ClearAttrFlag(my_struct->el_info, SDL_ATTR_MAIN);
8331     ClearAttrFlag(my_struct->el_info, SDL_ATTR_LOCS);
8332     ClearAttrFlag(my_struct->el_info, SDL_ATTR_SYNS);
8333     ClearAttrFlag(my_struct->el_info, SDL_ATTR_SORT);
8334
8335     /*
8336      * set the internal pointer
8337      */
8338     _SdlSegEntryInfo(my_struct->add_seg) = (void *) entryInfo;
8339
8340     return 0;
8341
8342 } /* End CopyEntryInfo */
8343
8344 /******************************************************************************
8345  * Function:    int InitLast (FormatStruct my_struct,
8346  *                                      int cur_element, exceptions);
8347  *
8348  * Parameters:
8349  *
8350  * Returns:     0 if successful, -1 if errors
8351  *
8352  * Purpose:     Looks for the virtual page attributes.
8353  *
8354  ******************************************************************************/
8355 static  int
8356 InitLast(
8357     FormatStruct        *my_struct,
8358     SDLMask             *cur_element,
8359     enum SdlElement      sig_element,
8360     SDLMask             *exceptions,
8361     SDLMask             *process_mask)
8362 {
8363     /*
8364      * set the parsing flags
8365      */
8366     my_struct->last_was_space = True;
8367     my_struct->last_was_mb    = False;
8368     my_struct->last_was_nl    = False;
8369
8370     /*
8371      * set the container type correctly.
8372      */
8373     if (NULL != my_struct->add_seg &&
8374         (SdlTypeLiteral == ElFrmtType(my_struct) ||
8375                                         SdlTypeLined == ElFrmtType(my_struct)))
8376         _DtCvContainerTypeOfSeg(my_struct->add_seg) = _DtCvLITERAL;
8377
8378     return 0;
8379
8380 } /* End InitLast */
8381
8382 /******************************************************************************
8383  * Function:    int SetTransit (FormatStruct my_struct,
8384  *                                      int cur_element, exceptions);
8385  *
8386  * Parameters:
8387  *
8388  * Returns:     0 if successful, -1 if errors
8389  *
8390  * Purpose:     Looks for the virtual page attributes.
8391  *
8392  ******************************************************************************/
8393 static  int
8394 SetTransit(
8395     FormatStruct        *my_struct,
8396     SDLMask             *cur_element,
8397     enum SdlElement      sig_element,
8398     SDLMask             *exceptions,
8399     SDLMask             *process_mask)
8400 {
8401     if (ElTiming(my_struct) == SdlTimingAsync)
8402         my_struct->resolve_font = _SdlFontModeNone;
8403
8404     return 0;
8405
8406 } /* End SetTransit */
8407
8408 \f
8409 /******************************************************************************
8410  *
8411  * Main Parsing Functions
8412  *
8413  *****************************************************************************/
8414 /******************************************************************************
8415  * Function:    int ParseSDL (FormatStruct my_struct,
8416  *                              int cur_element, int cur_execpt);
8417  *
8418  * Parameters:
8419  *
8420  * Returns:     0 if successful, -1 if errors
8421  *
8422  * Purpose:     Parses a set of rules.
8423  *
8424  ******************************************************************************/
8425 static  int
8426 ParseSDL(
8427     FormatStruct        *my_struct,
8428     enum SdlElement      cur_element,
8429     enum SdlElement      sig_element,
8430     SDLMask             *cur_except,
8431     SDLMask             *process_mask)
8432 {
8433     int    i = 0;
8434     int    result  = 0;
8435     int    oldLink = my_struct->cur_link;
8436     enum SdlElement      oldElType   = ElType(my_struct);
8437     _DtCvSegment        *oldCurSeg   = my_struct->last_seg;
8438     _DtCvSegment        *oldSeglist  = my_struct->seg_list;
8439     _DtCvSegment        *oldAddSeg   = my_struct->add_seg;
8440     _DtCvSegment        *ifPrevData  = my_struct->prev_data;
8441     _SdlFontMode         saveFontMode = my_struct->resolve_font;
8442     ElementInfo          saveElInfo  = my_struct->el_info;
8443     _DtHelpFontHints    *oldFontInfo = my_struct->my_fonts;
8444     const SDLContent    *content;
8445     _DtCvContainer      *activeFrmt = my_struct->active_frmt;
8446     SDLMask              oldMask[SDL_MASK_LEN];
8447     SDLMask              oldExcept[SDL_MASK_LEN];
8448     _DtCvValue           oldBlank    = my_struct->save_blank;
8449     _DtCvValue           processFlag =
8450                                 SDLSearchMask(process_mask, SdlElementCdata);
8451
8452     /*
8453      * While this element is allowed normally in the content of
8454      * the parent element, it it currently allowed?
8455      */
8456     if (SDLSearchMask(cur_except, cur_element) == True)
8457         return -1;
8458
8459     /*
8460      * special processing for CDATA elements
8461      */
8462     if (cur_element != SdlElementCdata)
8463       {
8464         my_struct->seg_list = NULL;
8465         my_struct->last_seg = NULL;
8466         my_struct->add_seg  = NULL;
8467       }
8468
8469     /*
8470      * look in the master list for this element
8471      */
8472     while (i < MaxSDLElements && SdlElementList[i].sdl_element != cur_element)
8473         i++;
8474
8475     /*
8476      * Didn't find this element in the master list.
8477      */
8478     if (i >= MaxSDLElements)
8479         return -1;
8480
8481     /*
8482      * merge this element's exceptions with parent's list.
8483      * save the old process mask.
8484      */
8485     SaveRestoreMask(oldExcept, cur_except);
8486     MergeMasks(cur_except, SdlElementList[i].exceptions);
8487     SaveRestoreMask(oldMask, process_mask);
8488
8489     /*
8490      * the content for this element is...
8491      */
8492     content = SdlElementList[i].content;
8493
8494     /*
8495      * check to see if we want to process this element
8496      * If sig_element is set, parse the element and its content.
8497      */
8498     if (sig_element != SdlElementNone)
8499       {
8500         processFlag = False;
8501         if (sig_element == cur_element)
8502           {
8503             processFlag  = True;
8504             sig_element  = SdlElementNone;
8505             SaveRestoreMask(process_mask, AllMaskSet);
8506           }
8507       }
8508
8509     /*
8510      * If not CDATA, then have to get the element start string, attributes
8511      * and ending markup tag.
8512      */
8513     if (cur_element != SdlElementCdata)
8514       {
8515         if (ParseElementStart(my_struct,SdlElementList[i],processFlag) != 0
8516                                 ||
8517                 ParseElementAttr(my_struct,
8518                                         cur_element,
8519                                         SdlElementList[i].attrib_list,
8520                                         SdlElementList[i].cdata_flag,
8521                                         processFlag) != 0)
8522             result = -1;
8523       }
8524
8525     /*
8526      * now parse the element's content
8527      */
8528     my_struct->faked_end = False;
8529     ElType(my_struct) = cur_element;
8530     while (result == 0 && content != NULL &&
8531                         SDLSearchMask(content->mask, SdlElementNone) == False)
8532       {
8533         result = (*(content->model))(my_struct, content->mask,
8534                                         sig_element, cur_except, process_mask);
8535         content++;
8536       }
8537
8538     /*
8539      * If not CDATA, get the element end markup and adjust some pointers
8540      */
8541     SaveRestoreMask(process_mask, oldMask);
8542     SaveRestoreMask(cur_except  , oldExcept);
8543     if (cur_element != SdlElementCdata)
8544       {
8545         if (result == 0 && SdlElementList[i].element_end_str != NULL)
8546             result = ParseElementEnd(my_struct, ifPrevData,
8547                                                         SdlElementList[i],
8548                                                         processFlag,
8549                                                         my_struct->faked_end);
8550         else
8551           {
8552             /*
8553              * free the attributes for this element.
8554              */
8555             FreeAttributes(ElType(my_struct),
8556                                 &(my_struct->el_info), my_struct->my_fonts);
8557
8558             if (SdlElementList[i].new_fonts && FreeFontInfo(my_struct) == -1)
8559                 result = -1;
8560           }
8561
8562
8563         my_struct->last_seg = oldCurSeg;
8564         my_struct->seg_list = oldSeglist;
8565
8566         if (result == 0 && my_struct->add_seg != NULL)
8567             _DtHelpCeAddSegToList(my_struct->add_seg, &(my_struct->seg_list),
8568                                                 &(my_struct->last_seg));
8569
8570         my_struct->add_seg   = oldAddSeg;
8571         my_struct->cur_link  = oldLink;
8572         if (SdlElementLink == cur_element)
8573             my_struct->save_blank = oldBlank;
8574
8575         my_struct->el_info  = saveElInfo;
8576         my_struct->my_fonts = oldFontInfo;
8577       }
8578
8579     my_struct->active_frmt  = activeFrmt;
8580     my_struct->resolve_font = saveFontMode;
8581     ElType(my_struct) = oldElType;
8582     return result;
8583
8584 } /* End ParseSDL */
8585
8586 /******************************************************************************
8587  * Function:    int ProcessSDLMarkup (FormatStruct my_struct,
8588  *                              int cur_element, int cur_execpt);
8589  *
8590  * Parameters:
8591  *
8592  * Returns:     0 if successful, -1 if errors
8593  *
8594  * Purpose:     Parses a set of rules, looks through the result and changes
8595  *              bad options into good.
8596  *
8597  ******************************************************************************/
8598 static  int
8599 ProcessSDLMarkup(
8600     FormatStruct        *my_struct,
8601     enum SdlElement      cur_element,
8602     enum SdlElement      sig_element,
8603     SDLMask             *cur_except,
8604     SDLMask             *process_mask)
8605 {
8606     int result = ParseSDL (my_struct, cur_element, sig_element, cur_except,
8607                                                                 process_mask);
8608
8609     if (-1 != result)
8610         PropagateJustification(my_struct->seg_list, _DtCvJUSTIFY_LEFT);
8611
8612     return result;
8613 }
8614
8615 /******************************************************************************
8616  * Function:    int ProcessContent (
8617  *                              FormatStruct *my_struct,
8618  *                              const SDLContent *content,
8619  *                              SDLMask *exceptions,
8620  *                              SDLMask *process_mask);
8621  *
8622  * Parameters:
8623  *              my_struct       Specifies specific informationg for this parse.
8624  *              content         Specifies the content model to parse.
8625  *              exceptions      Specifies the current elements excepted
8626  *                              from being in the current content.
8627  *              process_mask    Specifies which elements to save in memory.
8628  *
8629  * Returns:     0 if successful, -1 if errors
8630  *
8631  * Purpose:
8632  ******************************************************************************/
8633 static int
8634 ProcessContent(
8635     FormatStruct        *my_struct,
8636     const SDLContent    *content,
8637     enum SdlElement      sig_element,
8638     SDLMask             *exceptions,
8639     SDLMask             *process_mask)
8640 {
8641     int   result = 0;
8642
8643     while (result == 0 && content != NULL &&
8644                         SDLSearchMask(content->mask, SdlElementNone) == False)
8645       {
8646         result = (*(content->model))(my_struct, content->mask,
8647                                         sig_element, exceptions, process_mask);
8648         content++;
8649       }
8650
8651     if (-1 != result)
8652         PropagateJustification(my_struct->seg_list, _DtCvJUSTIFY_LEFT);
8653
8654     return result;
8655 }
8656
8657 /******************************************************************************
8658  * Function:    int SearchForController (_DtCvSegment p_seg, 
8659  *
8660  * Parameters:
8661  *
8662  * Returns:     0 if successful, -1 if errors
8663  *
8664  * Purpose:     Parses a set of rules.
8665  *
8666  ******************************************************************************/
8667 static  _DtCvSegment *
8668 SearchForController(
8669     _DtCvSegment                *p_seg)
8670 {
8671     while (NULL != p_seg &&
8672                 !(_DtCvIsSegContainer(p_seg) && _DtCvIsSegController(p_seg)))
8673         p_seg = _DtCvNextSeg(p_seg);
8674
8675     return p_seg;
8676
8677 } /* End SearchForController */
8678
8679 /******************************************************************************
8680  * Function:    int FormatSDLTitle (
8681  *
8682  * Parameters:
8683  *
8684  * Returns:     0 if successful, -1 if errors
8685  *
8686  * Purpose:     Parses a set of rules.
8687  *
8688  ******************************************************************************/
8689 static  int
8690 FormatSDLTitle(
8691     char                *filename,
8692     int                  offset,
8693     int                  fd,
8694     FormatStruct        *my_struct)
8695 {
8696     int         result = 0;
8697     SDLMask      processMask[SDL_MASK_LEN] = SDLSetAllBits;
8698 /*
8699     SDLMask     processMask[SDL_MASK_LEN] = SDLInitMaskEleven( \
8700                                 SdlElementTitle  , SdlElementHead   , \
8701                                 SdlElementKey    , SdlElementSphrase, \
8702                                 SdlElementRev    , SdlElementIf     , \
8703                                 SdlElementSpc    , SdlElementAnchor , \
8704                                 SdlElementLink   , SdlElementSnRef  , \
8705                                 SdlElementCdata);
8706 */
8707
8708     SDLMask     startExcept[SDL_MASK_LEN] = SDLInitMask(SdlElementNone);
8709
8710     /*
8711      * set the volume name for the graphics.
8712      */
8713     my_struct->vol_name = filename;
8714
8715     /*
8716      * can we seek to the correct place?
8717      */
8718     result = _DtHelpCeFileOpenAndSeek(filename, offset, fd,
8719                                         &(my_struct->my_file), NULL);
8720     if (result != -1)
8721       {
8722         result = ProcessSDLMarkup (my_struct, SdlElementTitle, SdlElementNone,
8723                                     startExcept, processMask);
8724         _DtHelpCeBufFileClose (my_struct->my_file, (fd == -1 ? True : False));
8725       }
8726
8727     return result;
8728
8729 } /* End FormatSDLTitle */
8730
8731 /******************************************************************************
8732  * Function:    void SetGhostLink (
8733  *
8734  * Parameters:
8735  *
8736  * Returns:
8737  *
8738  * Purpose:
8739  *
8740  ******************************************************************************/
8741 static  int
8742 SetGhostLink(
8743     _DtCvLinkDb          link_data,
8744     _DtCvSegment        *segments,
8745     int                  link_idx)
8746 {
8747     while (segments != NULL)
8748       {
8749         if (!(_DtCvIsSegContainer(segments)))
8750           {
8751             if (_DtCvIsSegHyperText(segments))
8752               {
8753                 _DtLinkDbRemoveLink(link_data, segments->link_idx);
8754                 segments->type = ClearSegLinks(segments);
8755               }
8756
8757             segments->type   = _DtCvSetTypeToGhostLink(segments->type);
8758             segments->link_idx = link_idx;
8759           }
8760         else /* if (_DtCvIsSegContainer(segments)) */
8761             SetGhostLink (link_data, _DtCvContainerListOfSeg(segments),
8762                                                                 link_idx);
8763         segments = _DtCvNextSeg(segments);
8764       }
8765
8766 } /* End SetGhostLink */
8767
8768 /******************************************************************************
8769  * Function:    void CreateAsciiString ()
8770  *
8771  * Parameters:
8772  *
8773  * Returns:
8774  *
8775  * Purpose:
8776  *
8777  ******************************************************************************/
8778 static  void
8779 CreateAsciiString(
8780     _DtCvSegment         *p_seg,
8781     _DtCvSegment         *snb,
8782     _DtCvValue           *nl_flag,
8783     char                **ret_string)
8784 {
8785     int          newLen;
8786     int          len;
8787
8788     while (p_seg != NULL)
8789       {
8790         len = 1;
8791         if (_DtCvIsSegString(p_seg))
8792           {
8793             if (*nl_flag == True)
8794               {
8795                 if (*ret_string != NULL &&
8796                                     (*ret_string)[strlen(*ret_string)-1] != ' ')
8797                   len++;
8798                 else
8799                   *nl_flag = False;
8800               }
8801
8802             newLen = _DtCvStrLen(_DtCvStringOfStringSeg(p_seg),
8803                                                 _DtCvIsSegWideChar(p_seg));
8804             if (_DtCvIsSegWideChar(p_seg))
8805                 newLen = newLen * MB_CUR_MAX;
8806
8807             len += newLen;
8808
8809             if (*ret_string == NULL)
8810               {
8811                 *ret_string  = (char *) malloc (len);
8812                 **ret_string = '\0';
8813               }
8814             else
8815               {
8816                 len += strlen(*ret_string);
8817                 *ret_string = (char *) realloc (*ret_string, len);
8818               }
8819
8820             if (*nl_flag == True)
8821                 strcat(*ret_string, " ");
8822
8823             /*
8824              * back up to the insertion point.
8825              */
8826             len -= newLen;
8827             len--;
8828
8829             /*
8830              * wide char or single byte?
8831              */
8832             if (_DtCvIsSegWideChar(p_seg))
8833                 wcstombs(&((*ret_string)[len]),
8834                                 (wchar_t *) _DtCvStringOfStringSeg(p_seg),
8835                                 newLen + 1);
8836             else
8837                 strcpy (&((*ret_string)[len]), _DtCvStringOfStringSeg(p_seg));
8838
8839             *nl_flag = False;
8840             if (p_seg->next_disp == NULL)
8841                 *nl_flag = True;
8842           }
8843         else if (_DtCvIsSegContainer(p_seg) && !(_DtCvIsSegController(p_seg)))
8844             CreateAsciiString(_DtCvContainerListOfSeg(p_seg),
8845                                         snb, nl_flag, ret_string);
8846
8847         p_seg = _DtCvNextSeg(p_seg);
8848       }
8849 }
8850
8851 /******************************************************************************
8852  * Function:    void CreateAsciiAbbrev ()
8853  *
8854  * Parameters:
8855  *
8856  * Returns:
8857  *
8858  * Purpose:
8859  *
8860  ******************************************************************************/
8861 static  void
8862 CreateAsciiAbbrev(
8863     _DtCvSegment         *p_el,
8864     char                **ret_abbrev)
8865 {
8866   *ret_abbrev = NULL;
8867   if (NULL != AbbrevOfSeg(p_el) && strlen ((char *) AbbrevOfSeg(p_el)))
8868         *ret_abbrev = strdup((char *) AbbrevOfSeg(p_el));
8869 }
8870
8871 /******************************************************************************
8872  * Function:    void CleanUpToc ()
8873  *
8874  * Parameters:
8875  *              my_struct       Specifies current formatting information.
8876  *              p_seg           Specifies the current segment list to modify.
8877  *              level           Specifes the parent element's level.
8878  *              lnk_indx        Specifies the link index to use for the
8879  *                              ghost link.
8880  *
8881  * Returns:     nothing
8882  *
8883  * Purpose:     Modifies the formatting information for conform to what
8884  *              it should be for a TOC and sets the ghost link.
8885  *
8886  ******************************************************************************/
8887 static  void
8888 CleanUpToc(
8889     FormatStruct        *my_struct,
8890     _DtCvSegment                *p_seg,
8891     int                  level,
8892     _DtCvValue           target)
8893 {
8894     level--;
8895     if (level < 0)
8896         level = 0;
8897
8898     while (p_seg != NULL)
8899       {
8900         if (_DtCvIsSegNewLine(p_seg))
8901             p_seg->type = p_seg->type & ~(_DtCvNEW_LINE);
8902
8903         if (_DtCvIsSegContainer(p_seg))
8904           {
8905             _DtCvContainerPercentOfSeg(p_seg)   = DefPercent;
8906             _DtCvContainerOrientOfSeg(p_seg)    = _DtCvJUSTIFY_LEFT_MARGIN;
8907             _DtCvContainerFlowOfSeg(p_seg)      = _DtCvWRAP_NONE;
8908             _DtCvContainerTypeOfSeg(p_seg)      = _DtCvLITERAL;
8909             _DtCvContainerVJustifyOfSeg(p_seg)  = _DtCvJUSTIFY_TOP;
8910             _DtCvContainerJustifyOfSeg(p_seg)   = _DtCvJUSTIFY_LEFT;
8911             _DtCvContainerFMarginOfSeg(p_seg)   = 0;
8912             _DtCvContainerLMarginOfSeg(p_seg)   =
8913                                 level * 2 * my_struct->ui_info->avg_char;
8914             _DtCvContainerRMarginOfSeg(p_seg)   = 0;
8915             _DtCvContainerTMarginOfSeg(p_seg)   = 0;
8916             _DtCvContainerBMarginOfSeg(p_seg)   = 0;
8917
8918             CleanUpToc(my_struct, _DtCvContainerListOfSeg(p_seg),
8919                                                         level, target);
8920           }
8921         else if (_DtCvIsSegString(p_seg))
8922           {
8923             _DtHelpFontHints *font_specs = (_DtHelpFontHints *)_DtCvFontOfStringSeg(p_seg);
8924
8925             _DtHelpFontPtrPtSize(font_specs) = 10;
8926             _DtHelpFontPtrWeight(font_specs) = _DtHelpFontWeightMedium;
8927
8928             if (target == True)
8929                 _DtHelpFontPtrWeight(font_specs) = _DtHelpFontWeightBold;
8930
8931             (my_struct->ui_info->load_font)(my_struct->ui_info->client_data,
8932                                 _DtHelpFontHintsLang(*font_specs),
8933                                 _DtHelpFontHintsCharSet(*font_specs),
8934                                 *font_specs,
8935                                 &(_DtCvFontOfStringSeg(p_seg)));
8936             free(font_specs);
8937           }
8938         else if (_DtCvIsSegRegion(p_seg))
8939           {
8940             int              result;
8941             _DtHelpDARegion *pReg = (_DtHelpDARegion *) _DtCvInfoOfRegionSeg(p_seg);
8942
8943             if (_DtHelpDASpc == pReg->type)
8944               {
8945                 _DtHelpDASpcInfo *pSpc = (_DtHelpDASpcInfo *) pReg->handle;
8946
8947                 _DtHelpFontHintsPtSize(pSpc->spc_fonts) = 10;
8948                 _DtHelpFontHintsWeight(pSpc->spc_fonts) =
8949                                                         _DtHelpFontWeightMedium;
8950
8951                 if (True == target)
8952                     _DtHelpFontHintsWeight(pSpc->spc_fonts) =
8953                                                         _DtHelpFontWeightBold;
8954
8955                 result = (*(my_struct->ui_info->resolve_spc))(
8956                                 my_struct->ui_info->client_data,
8957                                 _DtHelpFontHintsLang(pSpc->spc_fonts),
8958                                 _DtHelpFontHintsCharSet(pSpc->spc_fonts),
8959                                 pSpc->spc_fonts,
8960                                 pSpc->name,
8961                                 &(_DtCvInfoOfRegionSeg(p_seg)),
8962                                 &(_DtCvWidthOfRegionSeg(p_seg)),
8963                                 &(_DtCvHeightOfRegionSeg(p_seg)),
8964                                 &(_DtCvAscentOfRegionSeg(p_seg)));
8965                 if (0 != result)
8966                     p_seg->type = _DtCvSetTypeToNoop(p_seg->type);
8967
8968                 free(pSpc->name);
8969                 _DtHelpFreeFontHints(&(pSpc->spc_fonts));
8970
8971                 free(pSpc);
8972                 free(pReg);
8973               }
8974           }
8975
8976         p_seg = _DtCvNextSeg(p_seg);
8977       }
8978 }
8979
8980 /******************************************************************************
8981  * Function:    int AddEntryToToc ()
8982  *
8983  * Parameters:
8984  *
8985  * Returns:
8986  *
8987  * Purpose:
8988  *
8989  ******************************************************************************/
8990 static  int
8991 AddEntryToToc(
8992     FormatStruct        *my_struct,
8993     _DtHelpVolumeHdl     volume,
8994     int                  fd,
8995     int                  level,
8996     char                *lang,
8997     const char          *char_set,
8998     _DtCvSegment        *toss,
8999     _DtCvSegment        *info_seg,
9000     _DtCvValue           target,
9001     _DtCvSegment        **ret_snb,
9002     _DtCvSegment        **seg_list,
9003     _DtCvSegment        **prev_list)
9004 {
9005     int         result = 0;
9006     _DtCvLinkDb saveLinks;
9007     SDLIdInfo   *info;
9008
9009     /*
9010      * initialize the structure
9011      * save some information that's going to be destroyed in the setup.
9012      */
9013     saveLinks    = my_struct->my_links;
9014
9015     if (SetUp(NULL,NULL,my_struct,toss,my_struct->ui_info,fd,False,False) != 0)
9016         return -1;
9017
9018     /*
9019      * Initialize the standard/default to use
9020      */
9021     _DtHelpFontHintsLang(*(my_struct->my_fonts))    = lang;
9022     _DtHelpFontHintsCharSet(*(my_struct->my_fonts)) = (char *) char_set;
9023
9024     /*
9025      * free the new link database and restore the old one.
9026      * set font mode to save and the id for graphics.
9027      */
9028     _DtLinkDbDestroy(my_struct->my_links);
9029     my_struct->my_links     = saveLinks;
9030     my_struct->resolve_font = _SdlFontModeSave;
9031
9032     info = FrmtPrivInfoPtr(info_seg)->id_info;
9033     result = FormatSDLTitle(_DtHelpCeGetVolumeName(volume),
9034                                 _SdlIdInfoPtrOffset(info), fd, my_struct);
9035     /*
9036      * if no errors, continue
9037      */
9038     if (result != -1)
9039       {
9040         _DtCvSegment *headEl  = NULL;
9041
9042         /*
9043          * find the actual head element
9044          */
9045         if (my_struct->seg_list != NULL)
9046             headEl = SearchForController(
9047                                 _DtCvContainerListOfSeg(my_struct->seg_list));
9048
9049         /*
9050          * If there isn't a head element, use the id.
9051          */
9052         if (headEl == NULL)
9053           {
9054             _DtCvSegment *addSeg = NULL;
9055
9056             if (MySaveString(&(addSeg), my_struct,
9057                                         _DtCvContainerIdOfSeg(info_seg),
9058                                         -1, my_struct->mb_len, False) != 0)
9059               {
9060                 /*
9061                  * free the segments
9062                  */
9063                 _DtHelpFreeSegments(my_struct->seg_list, _DtCvTRUE,
9064                                         my_struct->ui_info->destroy_region,
9065                                         my_struct->ui_info->client_data);
9066                 my_struct->seg_list = NULL;
9067                 DestroyFontInfo(my_struct);
9068                 return -1;
9069               }
9070
9071             /*
9072              * if there is a virpage, attach the segment to it.
9073              * I.e. just reuse the container.
9074              */
9075             if (NULL != my_struct->seg_list)
9076               {
9077                 /*
9078                  * free the container original list
9079                  */
9080                 _DtHelpFreeSegments(
9081                                 _DtCvContainerListOfSeg(my_struct->seg_list),
9082                                 _DtCvTRUE,
9083                                 my_struct->ui_info->destroy_region,
9084                                 my_struct->ui_info->client_data);
9085               }
9086                 else
9087                   {
9088                 /*
9089                  * create a container for the segment.
9090                  */
9091                 if (_DtHelpCeAllocSegment(my_struct->malloc_size,
9092                                 &(my_struct->alloc_size),
9093                                 &(my_struct->block_list),
9094                                 &(my_struct->seg_list)) != 0)
9095                   {
9096                     _DtHelpFreeSegments(addSeg, _DtCvTRUE,
9097                                 my_struct->ui_info->destroy_region,
9098                                 my_struct->ui_info->client_data);
9099                     DestroyFontInfo(my_struct);
9100                     return -1;
9101                   }
9102
9103                 /*
9104                  * set the container flag and initialize its formatting
9105                  * information to the default.
9106                  */
9107                 my_struct->seg_list->type =
9108                         _DtCvSetTypeToContainer(my_struct->seg_list->type);
9109                 _DtCvContainerOfSeg(my_struct->seg_list) = DefFrmtSpecs;
9110                 _DtCvContainerLeadingOfSeg(my_struct->seg_list) =
9111                                                 my_struct->ui_info->leading;
9112               }
9113
9114             _DtCvContainerListOfSeg(my_struct->seg_list) = addSeg;
9115             headEl  = my_struct->seg_list;
9116           }
9117
9118         /*
9119          * there was a empty head, use the abbreviation or the id.
9120          */
9121         else if (_DtCvContainerListOfSeg(headEl) == NULL)
9122           {
9123             char *myPtr = (char *) AbbrevOfSeg(headEl);
9124
9125             if (NULL == myPtr)
9126                 myPtr = _DtCvContainerIdOfSeg(info_seg);
9127
9128             if (MySaveString(&(_DtCvContainerListOfSeg(headEl)), my_struct,
9129                                 myPtr, -1, my_struct->mb_len, False) != 0)
9130               {
9131                 /*
9132                  * free the segments
9133                  */
9134                 _DtHelpFreeSegments(my_struct->seg_list, _DtCvTRUE,
9135                                         my_struct->ui_info->destroy_region,
9136                                         my_struct->ui_info->client_data);
9137                 my_struct->seg_list = NULL;
9138                 DestroyFontInfo(my_struct);
9139                 return -1;
9140               }
9141           }
9142
9143         /*
9144          * Make sure we only use the first head.
9145          * first make sure that the segment list is not the head already.
9146          */
9147         if (headEl != my_struct->seg_list)
9148           {
9149             _DtCvSegment *prevSeg;
9150
9151             /*
9152              * destroy the segments after this one.
9153              */
9154             _DtHelpFreeSegments(_DtCvNextSeg(headEl), _DtCvTRUE,
9155                                         my_struct->ui_info->destroy_region,
9156                                         my_struct->ui_info->client_data);
9157             /*
9158              * break the link to the freed segments
9159              */
9160             _DtCvNextSeg(headEl) = NULL;
9161
9162             /*
9163              * destroy the segments before this one.
9164              */
9165             prevSeg = _DtCvContainerListOfSeg(my_struct->seg_list);
9166             if (prevSeg != headEl)
9167               {
9168                 /*
9169                  * search for the previous segment before the head.
9170                  */
9171                 while (_DtCvNextSeg(prevSeg) != headEl)
9172                     prevSeg = _DtCvNextSeg(prevSeg);
9173
9174                 /*
9175                  * break the link to the head element
9176                  */
9177                 _DtCvNextSeg(prevSeg) = NULL;
9178               }
9179             else
9180                 _DtCvContainerListOfSeg(my_struct->seg_list) = NULL;
9181
9182             /*
9183              * free the segments before the head and virpage container.
9184              */
9185             _DtHelpFreeSegments(my_struct->seg_list, _DtCvTRUE,
9186                                         my_struct->ui_info->destroy_region,
9187                                         my_struct->ui_info->client_data);
9188             my_struct->seg_list = headEl;
9189           }
9190
9191         if (headEl != NULL)
9192           {
9193             int linkIndex = _DtLinkDbAddLink(my_struct->my_links, NULL,
9194                                 _DtCvContainerIdOfSeg(info_seg),
9195                                         _DtCvLinkType_SameVolume,
9196                                         _DtCvWindowHint_CurrentWindow, NULL);
9197
9198             CleanUpToc(my_struct, headEl, level, target);
9199             SetGhostLink(my_struct->my_links, headEl, linkIndex);
9200           }
9201       }
9202
9203     if (result != -1)
9204       {
9205         /*
9206          * now tack this segment onto the end of the list
9207          */
9208         if ((*seg_list) == NULL)
9209             (*seg_list) = my_struct->seg_list;
9210         else
9211             _DtCvNextSeg((*prev_list)) = my_struct->seg_list;
9212
9213         *prev_list = my_struct->seg_list;
9214         while ((*prev_list) != NULL && _DtCvNextSeg((*prev_list)) != NULL)
9215             *prev_list = _DtCvNextSeg((*prev_list));
9216       }
9217
9218     /*
9219      * if the snb for this topic was read, free it now.
9220      */
9221     if (my_struct->snb != NULL)
9222       {
9223         _DtHelpFreeSegments(my_struct->snb, _DtCvTRUE,
9224                                         my_struct->ui_info->destroy_region,
9225                                         my_struct->ui_info->client_data);
9226         my_struct->snb = NULL;
9227       }
9228
9229     /*
9230      * free the font structures allocated
9231      */
9232     DestroyFontInfo(my_struct);
9233
9234     return result;
9235 }
9236
9237 /******************************************************************************
9238  * Function:    int ExpandToc ()
9239  *
9240  * Parameters:
9241  *
9242  * Returns:
9243  *
9244  * Purpose:
9245  *
9246  ******************************************************************************/
9247 static  int
9248 ExpandToc(
9249     FormatStruct        *my_struct,
9250     _DtHelpVolumeHdl     volume,
9251     int                  fd,
9252     char                *lang,
9253     const char          *char_set,
9254     _DtCvSegment        *toss,
9255     int                  level,
9256     char                **path_list,
9257     _DtCvSegment        **id_seg,
9258     _DtCvSegment        **ret_snb,
9259     _DtCvSegment        **seg_list,
9260     _DtCvSegment        **prev_list)
9261 {
9262     int          result   = 0;
9263     int          segLev;
9264     int          tst      = 1;
9265     _DtCvSegment *pEl;
9266     _DtCvValue   done     = False;
9267     _DtCvValue   found    = False;
9268
9269     /*
9270      * skip anything that isn't a virpage and of the correct level.
9271      */
9272     while ((*id_seg) != NULL && _SdlSegToSdlIdInfoType(*id_seg) != SdlIdVirpage
9273                 && _SdlSegToSdlIdInfoLevel(*id_seg) != level)
9274         *id_seg = _DtCvNextSeg((*id_seg));
9275
9276     /*
9277      * process any virpage that has the correct level
9278      */
9279     while ((*id_seg) != NULL && done == False && result == 0)
9280       {
9281         pEl    = (*id_seg);
9282         segLev = _SdlSegToSdlIdInfoLevel(pEl);
9283
9284         if (_SdlSegToSdlIdInfoType(pEl) == SdlIdVirpage)
9285           {
9286             if (segLev == level)
9287               {
9288                 /*
9289                  * If the virpage in the path list has not been found,
9290                  * test the next virpage. Otherwise skip.
9291                  */
9292                 if (found == False && *path_list != NULL &&
9293                                         _DtCvContainerIdOfSeg(pEl) != NULL)
9294                     tst   = _DtCvStrCaseCmpLatin1(*path_list,
9295                                                 _DtCvContainerIdOfSeg(pEl));
9296                         
9297                 /*
9298                  * the only time tst == 0 is when the next item in the
9299                  * path_list matches this element. Check to see if the
9300                  * next item in the path_list is null. If so, that
9301                  * means this is the location the user has desired.
9302                  */
9303                 result = AddEntryToToc(my_struct, volume, fd,
9304                         segLev, lang, char_set, toss, pEl,
9305                         (tst == 0 && path_list[1] == NULL ? True : False),
9306                         ret_snb, seg_list, prev_list);
9307
9308                 /*
9309                  * increment the segment pointer to the next item
9310                  */
9311                 *id_seg = _DtCvNextSeg((*id_seg));
9312
9313                 /*
9314                  * The only time tst is zero is if the current virpage
9315                  * matches the next item in the list. Expand it's children.
9316                  * and set tst to non-zero so that AddEntryToToc does not
9317                  * special case the siblings following this one.
9318                  */
9319                 if (tst == 0)
9320                   {
9321                     result = ExpandToc(my_struct, volume, fd, lang,
9322                                         char_set, toss,
9323                                         segLev + 1,
9324                                         &path_list[1],
9325                                         id_seg, ret_snb, seg_list, prev_list);
9326                     found = True;
9327                     tst   = 1;
9328                   }
9329               }
9330             else if (segLev < level)
9331                 done = True;
9332             else
9333                 *id_seg = _DtCvNextSeg((*id_seg));
9334           }
9335         else
9336             *id_seg = _DtCvNextSeg((*id_seg));
9337       }
9338
9339     return result;
9340
9341 } /* ExpandToc */
9342
9343 /******************************************************************************
9344  * Function:    void CreateTitleChunks ()
9345  *
9346  * Parameters:
9347  *
9348  * Returns:
9349  *
9350  * Purpose:
9351  *
9352  ******************************************************************************/
9353 static  int
9354 CreateTitleChunks(
9355     _DtCvSegment          *toss,
9356     _DtCvSegment          *p_seg,
9357     _DtCvSegment          *snb,
9358     SDLMask               *stop_mask,
9359     const char            *lang,
9360     const char            *char_set,
9361     _DtCvValue          (*resolve_spc)(),
9362     _DtCvPointer          client_data,
9363     int                   *ret_cnt,
9364     void                ***ret_chunks)
9365 {
9366     long         type;
9367     int          cnt;
9368     int          result = 0;
9369     const char  *myLang;
9370     const char  *mySet;
9371     void        *ptr;
9372     _DtHelpDARegion     *daRegion;
9373
9374     while (result != -1 && p_seg != NULL)
9375       {
9376         myLang = lang;
9377         mySet  = char_set;
9378         cnt = *ret_cnt;
9379         if (_DtCvIsSegString(p_seg))
9380           {
9381             if (*ret_cnt == 0)
9382                 *ret_cnt = 1;
9383             else
9384                 cnt--;
9385
9386             *ret_cnt = *ret_cnt + 3;
9387             if (*ret_chunks == NULL)
9388                 *ret_chunks = (void **) malloc (sizeof(void *) * (*ret_cnt));
9389             else
9390                 *ret_chunks = (void **) realloc (*ret_chunks,
9391                                                 sizeof(void *) * (*ret_cnt));
9392             if (*ret_chunks == NULL)
9393                 return -1;
9394
9395             type = DT_HELP_CE_FONT_PTR | DT_HELP_CE_STRING;
9396             ptr  = _DtCvFontOfStringSeg(p_seg);
9397
9398             if (p_seg->next_disp == NULL || _DtCvIsSegNewLine(p_seg))
9399                 type |= DT_HELP_CE_NEWLINE;
9400
9401             (*ret_chunks)[cnt++] = (void *) type;
9402             (*ret_chunks)[cnt++] = (void *) ptr;
9403
9404             if (_DtCvIsSegWideChar(p_seg))
9405               {
9406                 int len = _DtCvStrLen(_DtCvStringOfStringSeg(p_seg), 1)
9407                                                         * MB_CUR_MAX + 1;
9408
9409                 ptr = malloc (sizeof(char *) * len);
9410                 if (NULL != ptr)
9411                     wcstombs((char *) ptr,
9412                                 (wchar_t *) _DtCvStringOfStringSeg(p_seg), len);
9413               }
9414             else
9415                 ptr = strdup(_DtCvStringOfStringSeg(p_seg));
9416
9417             (*ret_chunks)[cnt++] = (void *) ptr;
9418             if ((*ret_chunks)[cnt-1] == NULL)
9419                 return -1;
9420
9421             (*ret_chunks)[cnt++] = (void *) DT_HELP_CE_END;
9422           }
9423         else if (_DtCvIsSegRegion(p_seg))
9424           {
9425             daRegion = (_DtHelpDARegion *) _DtCvInfoOfRegionSeg(p_seg);
9426             if (_DtHelpDASpc == daRegion->type)
9427               {
9428                 if (False == daRegion->inited)
9429                   {
9430                     _DtHelpDASpcInfo *pSpc =
9431                                         (_DtHelpDASpcInfo *) daRegion->handle;
9432                     /*
9433                      * allocate the spc!
9434                      */
9435                     result = (*(resolve_spc))(
9436                                 client_data,
9437                                 _DtHelpFontHintsLang(pSpc->spc_fonts),
9438                                 _DtHelpFontHintsCharSet(pSpc->spc_fonts),
9439                                 pSpc->spc_fonts,
9440                                 pSpc->name,
9441                                 &(_DtCvInfoOfRegionSeg(p_seg)),
9442                                 &(_DtCvWidthOfRegionSeg(p_seg)),
9443                                 &(_DtCvHeightOfRegionSeg(p_seg)),
9444                                 &(_DtCvAscentOfRegionSeg(p_seg)));
9445
9446                     free(pSpc->name);
9447                     _DtHelpFreeFontHints(&(pSpc->spc_fonts));
9448
9449                     free(pSpc);
9450                     free(daRegion);
9451
9452                     if (0 != result)
9453                         return -1;
9454
9455                     daRegion = (_DtHelpDARegion *) _DtCvInfoOfRegionSeg(p_seg);
9456                   }
9457
9458                 if (*ret_cnt == 0)
9459                     *ret_cnt = 1;
9460                 else
9461                     cnt--;
9462
9463                 *ret_cnt = *ret_cnt + 2;
9464                 if (*ret_chunks == NULL)
9465                     *ret_chunks = (void **) malloc (sizeof(void *) * *ret_cnt);
9466                 else
9467                     *ret_chunks = (void **) realloc (*ret_chunks,
9468                                                 sizeof(void *) * *ret_cnt);
9469                 if (*ret_chunks == NULL)
9470                     return -1;
9471
9472                 type = DT_HELP_CE_SPC;
9473                 if (p_seg->next_disp == NULL || _DtCvIsSegNewLine(p_seg))
9474                     type |= DT_HELP_CE_NEWLINE;
9475
9476                 (*ret_chunks)[cnt++] = (void *) type;
9477                 (*ret_chunks)[cnt++] = (void *) daRegion->handle;
9478                 (*ret_chunks)[cnt++] = (void *) DT_HELP_CE_END;
9479               }
9480             result = 0;
9481           }
9482         else if (_DtCvIsSegContainer(p_seg) && !(_DtCvIsSegController(p_seg)))
9483             result = CreateTitleChunks(toss,
9484                                 _DtCvContainerListOfSeg(p_seg), snb,
9485                                 stop_mask,
9486                                 myLang, mySet,
9487                                 resolve_spc,
9488                                 client_data,
9489                                 ret_cnt, ret_chunks);
9490
9491         p_seg = _DtCvNextSeg(p_seg);
9492       }
9493
9494     return result;
9495 }
9496
9497 /******************************************************************************
9498  * Function:    int ProcessSegmentsToChunks ()
9499  *
9500  * Parameters:
9501  *
9502  * Returns:     0 if created a chunk, -1 if errors
9503  *
9504  * Purpose:
9505  *
9506  ******************************************************************************/
9507 static int
9508 ProcessSegmentsToChunks(
9509     _DtCvSegment          *toss,
9510     _DtCvSegment          *head_el,
9511     _DtCvSegment          *snb_el,
9512     SDLMask               *stop_mask,
9513     const char            *lang,
9514     const char            *char_set,
9515     _DtCvValue          (*resolve_spc)(),
9516     _DtCvPointer          client_data,
9517     void                ***ret_chunks)
9518 {
9519     int cnt    = 0;
9520     int result = 0;
9521
9522     result = CreateTitleChunks(toss, _DtCvContainerListOfSeg(head_el),
9523                                         snb_el, stop_mask, lang, char_set,
9524                                         resolve_spc, client_data,
9525                                         &cnt, ret_chunks);
9526     if ((result != 0 || cnt == 0) && NULL != AbbrevOfSeg(head_el)
9527                                 && strlen ((char *) AbbrevOfSeg(head_el)))
9528       {
9529         *ret_chunks   = (void **) malloc (sizeof(void *) * 4);
9530         if (*ret_chunks == NULL)
9531             return -1;
9532
9533         (*ret_chunks)[0] = (void *) DT_HELP_CE_CHARSET;
9534         (*ret_chunks)[1] = (void *) strdup(char_set);
9535         (*ret_chunks)[2] = (void *) strdup(AbbrevOfSeg(head_el));
9536         (*ret_chunks)[3] = (void *) DT_HELP_CE_END;
9537       }
9538
9539     return result;
9540 }
9541
9542 /******************************************************************************
9543  * Function:    _DtCvSegment *GetSdlDocSnb (
9544  *                              _DtHelpVolumeHdl    volume)
9545  * Parameters:
9546  *              volume          Specifies the volume.
9547  *
9548  * Returns:     0 if successful, -1 if errors
9549  *
9550  * Purpose:     If the title has been parsed and it used snrefs,
9551  *              this function will return the snb specified in the
9552  *              sdldoc element.
9553  ******************************************************************************/
9554 static _DtCvSegment *
9555 GetSdlDocSnb(
9556     _DtHelpVolumeHdl     volume)
9557 {
9558     _DtCvSegment        *retEl = NULL;
9559     CESDLVolume *sdlVol;
9560
9561     sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
9562     if (sdlVol != NULL && sdlVol->snb != NULL)
9563         retEl = (sdlVol->snb);
9564
9565     return retEl;
9566 }
9567
9568 /******************************************************************************
9569  * Function:    int GetDocumentTitle (
9570  *                              _DtHelpVolumeHdl    volume,
9571  *                              _DtCvValue        flag,
9572  *                              _DtCvSegment    **ret_seg)
9573  * Parameters:
9574  *              volume          Specifies the volume.
9575  *              flag            Specifies if the toss is needed.
9576  *              ret_seg         Returns sdlVol->title.
9577  *
9578  * Returns:     0 if successful, -1 if errors, -2 if there is no title.
9579  *
9580  * Purpose:     This will fill in the 'title' and 'snb' elements of
9581  *              the CESDLVolume structure and return 'title' in 'ret_seg'.
9582  ******************************************************************************/
9583 static int
9584 GetDocumentTitle(
9585     _DtHelpVolumeHdl     volume,
9586     _FrmtUiInfo         *ui_info,
9587     _SdlFontMode         mode,
9588     _DtCvValue           flag,
9589     _DtCvSegment        **ret_seg)
9590 {
9591     int                  result   = -1;
9592     short                procFlag = True;
9593     CESDLVolume         *sdlVol;
9594     FormatStruct         frmtStruct;
9595     _DtCvSegment                *toss = NULL;
9596     SDLMask              skipMask   [SDL_MASK_LEN] = SDLClearAllBits;
9597     SDLMask              processMask[SDL_MASK_LEN] = SDLSetAllBits;
9598     SDLMask              startExcept[SDL_MASK_LEN] =
9599                                         SDLInitMask(SdlElementNone);
9600
9601     sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
9602     if (sdlVol == NULL)
9603         return -1;
9604
9605     if (sdlVol->title_processed == False)
9606       {
9607         if (flag == True)
9608             toss = _DtHelpCeGetSdlVolToss(volume, -1);
9609
9610         if (SetUp(volume,NULL,&frmtStruct,toss,ui_info,-1,True,False) !=0 )
9611             return -1;
9612
9613         /*
9614          * now set up correct font mode.
9615          */
9616         frmtStruct.resolve_font = mode;
9617
9618         /*
9619          * now get the title.
9620          */
9621         if (_DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume), 0, -1,
9622                                         &(frmtStruct.my_file), NULL) != -1)
9623           {
9624             if (ProcessContent(&frmtStruct, SDLDocumentContent,
9625                                 SdlElementNone, startExcept, skipMask) != -1
9626                 && ProcessSDLMarkup(&frmtStruct, SdlElementVStruct,
9627                                 SdlElementNone, startExcept, skipMask) != -1
9628                 && ProcessContent(&frmtStruct, HeadAndSnb,
9629                                 SdlElementNone, startExcept, processMask) != -1)
9630               {
9631                 sdlVol->title       = frmtStruct.seg_list;
9632                 sdlVol->snb         = frmtStruct.snb;
9633                 sdlVol->client_data = ui_info->client_data;
9634                 sdlVol->destroy_region = ui_info->destroy_region;
9635                 result = 0;
9636
9637                 /*
9638                  * if the volume doesn't have a head, set the
9639                  * appropriate flags.
9640                  */
9641                 if (NULL == sdlVol->title)
9642                   {
9643                     procFlag = -1;      /* processed with no errors */
9644                     result   = -2;      /* but no title             */
9645                   }
9646               }
9647             else /* free the segments */
9648                 _DtHelpFreeSegments(frmtStruct.seg_list, _DtCvFALSE,
9649                                         ui_info->destroy_region,
9650                                         ui_info->client_data);
9651
9652             _DtHelpCeBufFileClose (frmtStruct.my_file, True);
9653           }
9654
9655         /*
9656          * free the font structures allocated
9657          */
9658         DestroyFontInfo(&frmtStruct);
9659
9660         /*
9661          * destroy the link database
9662          */
9663         _DtLinkDbDestroy(frmtStruct.my_links);
9664
9665         sdlVol->title_processed = procFlag;
9666       }
9667
9668     /*
9669      * if we have a title, good
9670      */
9671     else if (sdlVol->title != NULL)
9672         result = 0;
9673
9674     /*
9675      * we haven't processed a title. Is is because the volume
9676      * doesn't have one or because of problems accessing the volume?
9677      */
9678     else if (-1 == sdlVol->title_processed)
9679         result = -2;    /* volume doesn't have a title */
9680
9681     *ret_seg = sdlVol->title;
9682
9683     return result;
9684 }
9685
9686 /******************************************************************************
9687  *
9688  * Semi-Private Functions
9689  *
9690  *****************************************************************************/
9691 /******************************************************************************
9692  * Function:    SDLAttribute *_DtHelpCeGetSdlAttributeList(void)
9693  *
9694  * Parameters:
9695  *
9696  * Returns:     ptr or NULL;
9697  *
9698  * Purpose:
9699  ******************************************************************************/
9700 const SDLAttribute *
9701 _DtHelpCeGetSdlAttributeList(void)
9702 {
9703     const SDLAttribute *ptr = SDLAttributeList;
9704
9705     return ptr;
9706 }
9707
9708 /******************************************************************************
9709  *
9710  * Semi-Public Functions
9711  *
9712  *****************************************************************************/
9713 /******************************************************************************
9714  * Function:    int _DtHelpCeFrmtSDLPathAndChildren (
9715  *                              _DtHelpVolumeHdl volume, char *filename,
9716  *                              int offset, char *id_string,
9717  *                              _DtCvTopicPtr *ret_handle)
9718  *
9719  * Parameters:
9720  *              volume          Specifies the Help Volume the information
9721  *                              is associated with.
9722  *              filename        Specifies the file containing the Help Topic
9723  *                              desired.
9724  *              offset          Specifies the offset into 'filename' to
9725  *                              the Help Topic desired.
9726  *              id_string       Specifies the location id to look for or NULL.
9727  *              ret_handle      Returns a handle to the topic information
9728  *                              including the number of paragraphs and the
9729  *                              id match segment.
9730  *
9731  * Returns:     0 if successful, -1 if errors, 1 if the path is empty.
9732  *
9733  ******************************************************************************/
9734 int
9735 _DtHelpCeFrmtSdlPathAndChildren(
9736     _DtHelpVolumeHdl     volume,
9737     _FrmtUiInfo         *ui_info,
9738     int                  fd,
9739     char                *target_id,
9740     _DtCvTopicPtr       *ret_handle)
9741 {
9742     char                *lang;
9743     const char          *charSet;
9744     char                **topicMap;
9745     int                  result = 0;
9746     int                  pathCnt;
9747     FormatStruct         frmtStruct;
9748     _DtCvTopicInfo      *topicHandle;
9749     _DtCvSegment        *mySegList = NULL;
9750     _DtCvSegment        *myPrevSeg = NULL;
9751     _DtCvSegment        *loids;
9752     _DtCvSegment        *snb    = NULL;
9753     SDLIdInfo           *info;
9754
9755     *ret_handle = NULL;
9756
9757     /*
9758      * look for the heading for each virpage
9759      */
9760     frmtStruct         = DefFormatStruct;
9761     frmtStruct.ui_info = ui_info;
9762     frmtStruct.my_links = _DtLinkDbCreate();
9763     frmtStruct.vol_name = _DtHelpCeGetVolumeName(volume);
9764     frmtStruct.id_string = target_id;
9765
9766     /*
9767      * get the path from the target to the top.
9768      */
9769     pathCnt = _DtHelpCeGetSdlIdPath(volume, target_id, &topicMap);
9770     if (pathCnt == -1)
9771         return -1;
9772
9773     /*
9774      * get the beginning of the path
9775      */
9776     loids = _DtHelpCeMapSdlIdToSegment(volume, *topicMap, fd);
9777     if (loids == NULL)
9778       {
9779         _DtCvFreeArray((void **) topicMap);
9780         return -1;
9781       }
9782     
9783     /*
9784      * format the top topic entry.
9785      */
9786     info = FrmtPrivInfoPtr(loids)->id_info;
9787     if (_SdlIdInfoPtrRlevel(info) > 0)
9788       {
9789         /*
9790          * Put the top topic in the table of contents.
9791          */
9792         lang    = _DtHelpCeGetSdlVolLanguage(volume);
9793         charSet = _DtHelpCeGetSdlVolCharSet(volume);
9794         result  = AddEntryToToc(&frmtStruct, volume, fd,
9795                                 _SdlIdInfoPtrRlevel(info), lang, charSet,
9796                                 _DtHelpCeGetSdlVolToss(volume, fd),
9797                                 loids, (topicMap[1] == NULL ? True : False),
9798                                 &snb, &mySegList, &myPrevSeg);
9799         /*
9800          * format the children.
9801          */
9802         if (result != -1 && _DtCvNextSeg(loids) != NULL)
9803           {
9804             loids  = _DtCvNextSeg(loids);
9805             result = ExpandToc(&frmtStruct, volume, fd, lang, charSet,
9806                                 _DtHelpCeGetSdlVolToss(volume, fd),
9807                                 _SdlIdInfoPtrRlevel(info) + 1,
9808                                 &topicMap[1],
9809                                 &loids, &snb, &mySegList, &myPrevSeg);
9810           }
9811       }
9812
9813     if (result != -1)
9814       {
9815         topicHandle = (_DtCvTopicInfo *) malloc (sizeof(_DtCvTopicInfo));
9816         if (topicHandle != NULL)
9817           {
9818             topicHandle->id_str    = NULL;
9819             topicHandle->mark_list = NULL;
9820             topicHandle->link_data = frmtStruct.my_links;
9821
9822             topicHandle->seg_list  = (void *) mySegList;
9823
9824             /*
9825              * let the top level know that there isn't a path
9826              */
9827             if (NULL == mySegList)
9828                 result = 1;
9829
9830             *ret_handle = (void *) topicHandle;
9831           }
9832         else
9833             result = -1;
9834       }
9835
9836     _DtCvFreeArray((void **) topicMap);
9837     return result;
9838
9839 } /* End _DtHelpCeFrmtSDLPathAndChildren */
9840
9841 /******************************************************************************
9842  * Function:    int _DtHelpCeFrmtSdlVolumeInfo (char *filename,
9843  *                              _DtCvTopicPtr *ret_handle)
9844  *
9845  * Parameters:
9846  *              filename        Specifies the file containing the Help Topic
9847  *                              desired.
9848  *              ret_handle      Returns a handle to the topic information
9849  *                              including the number of paragraphs and the
9850  *                              id match segment.
9851  *
9852  * Returns:     0 if successful, -1 if errors
9853  *
9854  * Purpose:     _DtHelpCeFrmtSdlVolumeInfo processes the SDL volume looking
9855  *              for the generated items.
9856  *
9857  ******************************************************************************/
9858 int
9859 _DtHelpCeFrmtSdlVolumeInfo(
9860     char                *filename,
9861     _DtHelpVolumeHdl     volume,
9862     time_t              *ret_time)
9863 {
9864     int                  result = 0;
9865     char                *numPtr;
9866     CESDLVolume         *sdlVol;
9867     FormatStruct         frmtStruct;
9868     SDLMask              processMask[SDL_MASK_LEN] = SDLSetAllBits;
9869     SDLMask              startExcept[SDL_MASK_LEN] =
9870                                         SDLInitMask(SdlElementNone);
9871
9872     if (SetUp(volume,&sdlVol,&frmtStruct,NULL,&DefUiInfo,-1,True,False) != 0)
9873         return -1;
9874
9875     /*
9876      * now set up correct font mode.
9877      */
9878     frmtStruct.resolve_font = _SdlFontModeNone;
9879
9880     if (result == 0)
9881       {
9882         result = _DtHelpCeFileOpenAndSeek(filename, 0, -1,
9883                                         &(frmtStruct.my_file), ret_time);
9884         if (result != -1)
9885           {
9886             result = ProcessContent(&frmtStruct, SDLDocumentContent,
9887                                 SdlElementNone, startExcept, processMask);
9888
9889             _DtHelpCeBufFileClose (frmtStruct.my_file, True);
9890
9891             if (frmtStruct.remember != NULL)
9892                 free(frmtStruct.remember);
9893           }
9894     
9895         if (result != -1)
9896           {
9897             /*
9898              * attach the information to this volume.
9899              */
9900             sdlVol->sdl_info = (SDLDocInfo *)
9901                         FrmtPrivInfoPtr(frmtStruct.seg_list)->doc_info;
9902
9903             /*
9904              * check the major and minor numbers.
9905              */
9906             numPtr = _SdlDocInfoPtrSdlDtd(sdlVol->sdl_info);
9907
9908             while (*numPtr < '0' || *numPtr > '9')
9909                 numPtr++;
9910
9911             if (atoi(numPtr) != SDL_DTD_VERSION)
9912                 result = -1;
9913             else
9914               {
9915                 while (*numPtr != '.' && *numPtr != '\0')
9916                     numPtr++;
9917
9918                 if (*numPtr == '.')
9919                     numPtr++;
9920
9921                 sdlVol->minor_no = atoi(numPtr);
9922               }
9923
9924             /*
9925              * free the container
9926              */
9927             FrmtPrivInfoPtr(frmtStruct.seg_list)->doc_info = NULL;
9928             _DtHelpFreeSegments(frmtStruct.seg_list, _DtCvFALSE, NULL, NULL);
9929           }
9930       }
9931
9932     _DtLinkDbDestroy(frmtStruct.my_links);
9933
9934     /*
9935      * free the font structures allocated
9936      */
9937     DestroyFontInfo(&frmtStruct);
9938
9939     return result;
9940 }
9941
9942 /******************************************************************************
9943  * Function:    int _DtHelpCeFrmtSDLTitleToAscii (
9944  *                              char *filename,
9945  *                              int offset,
9946  *                              char **ret_title, char **ret_abbrev)
9947  *
9948  * Parameters:
9949  *
9950  * Returns:     0 if successful, -1 if errors
9951  *
9952  * Purpose:
9953  ******************************************************************************/
9954 int
9955 _DtHelpCeFrmtSDLTitleToAscii(
9956     _DtHelpVolumeHdl        volume,
9957     int          offset,
9958     char        **ret_title,
9959     char        **ret_abbrev)
9960 {
9961     int                  result = 0;
9962     FormatStruct         frmtStruct;
9963
9964     if (SetUp(volume,NULL,&frmtStruct,NULL,&DefUiInfo,-1,True,False) != 0)
9965         return -1;
9966
9967     *ret_title = NULL;
9968     if (ret_abbrev != NULL)
9969         *ret_abbrev = NULL;
9970
9971     /*
9972      * now set up correct font mode.
9973      */
9974     frmtStruct.resolve_font = _SdlFontModeNone;
9975
9976     /*
9977      * get the title.
9978      */
9979     result = FormatSDLTitle(frmtStruct.vol_name, offset, -1, &frmtStruct);
9980
9981     if (result != -1 && frmtStruct.seg_list != NULL)
9982       {
9983         _DtCvSegment  *pHeadSeg;
9984         _DtCvValue   nlFlag = False;
9985
9986         pHeadSeg = _DtCvContainerListOfSeg(frmtStruct.seg_list);
9987
9988         if (pHeadSeg != NULL)
9989           {
9990             CreateAsciiString(_DtCvContainerListOfSeg(pHeadSeg),
9991                                 frmtStruct.snb, &nlFlag, ret_title);
9992             CreateAsciiAbbrev(pHeadSeg, ret_abbrev);
9993           }
9994         else
9995             result = -1;
9996       }
9997     else
9998         result = -1;
9999
10000     if (frmtStruct.seg_list != NULL)
10001         _DtHelpFreeSegments(frmtStruct.seg_list, _DtCvFALSE, NULL, NULL);
10002
10003     /*
10004      * free the font structures allocated
10005      */
10006     DestroyFontInfo(&frmtStruct);
10007
10008     return result;
10009
10010 } /* End _DtHelpCeFrmtSDLTitleToAscii */
10011
10012 /******************************************************************************
10013  * Function:    char *_DtHelpCeFrmtSdlVolumeAbstractToAscii(
10014  *                                                      _DtHelpVolumeHdl volume)
10015  *
10016  * Parameters:
10017  *              volume          Specifies the Help Volume the information
10018  *                              is associated with.
10019  *
10020  * Returns:     0 if successful, -1 if errors
10021  *
10022  * Purpose:     _DtHelpCeFrmtSdlVolumeAbstractToAscii formats Help Files
10023  *              with formatting information into a CEVirtualPage
10024  *
10025  ******************************************************************************/
10026 char *
10027 _DtHelpCeFrmtSdlVolumeAbstractToAscii(
10028     _DtHelpVolumeHdl        volume)
10029 {
10030     int                  offset;
10031     char                *abstr = NULL;
10032     _DtCvSegment        *pSeg;
10033     _DtCvSegment        *pSnb;
10034     _DtCvValue           nlFlag = False;
10035     _DtHelpCeLockInfo    lockInfo;
10036
10037     if (_DtHelpCeLockVolume(volume, &lockInfo) != 0)
10038         return NULL;
10039
10040     if (_DtHelpCeFindSdlId(volume,"_abstract",lockInfo.fd,NULL,&offset) == True)
10041       {
10042         int     result = 0;
10043         SDLMask startExcept[SDL_MASK_LEN] = SDLInitMask(SdlElementNone);
10044         SDLMask processMask[SDL_MASK_LEN] = SDLSetAllBits;
10045         FormatStruct     frmtStruct;
10046         CESDLVolume     *sdlVol;
10047
10048         if (SetUp(volume, &sdlVol, &frmtStruct, NULL, &DefUiInfo,
10049                                         lockInfo.fd, True, False) != 0)
10050             return NULL;
10051
10052         /*
10053          * now set up correct font mode.
10054          */
10055         frmtStruct.resolve_font = _SdlFontModeNone;
10056
10057         /*
10058          * open the volume and seek to the virpage
10059          */
10060         result = _DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume),
10061                                         offset, lockInfo.fd,
10062                                         &(frmtStruct.my_file), NULL);
10063         if (result != -1)
10064           {
10065             result = ProcessSDLMarkup (&frmtStruct, SdlElementVirpage,
10066                                 SdlElementNone, startExcept, processMask);
10067             _DtHelpCeBufFileClose (frmtStruct.my_file,
10068                                         (lockInfo.fd == -1 ? True : False));
10069           }
10070
10071         if (result != -1)
10072           {
10073             pSeg = frmtStruct.seg_list;
10074             pSnb = frmtStruct.snb;
10075
10076             CreateAsciiString(pSeg, pSnb, &nlFlag, &abstr);
10077
10078             _DtHelpFreeSegments(frmtStruct.seg_list, _DtCvFALSE, NULL, NULL);
10079             _DtHelpFreeSegments(frmtStruct.snb, _DtCvFALSE, NULL, NULL);
10080           }
10081
10082         /*
10083          * free the font structures allocated
10084          */
10085         DestroyFontInfo(&frmtStruct);
10086
10087       }
10088
10089     _DtHelpCeUnlockVolume(lockInfo);
10090
10091     return abstr;
10092
10093 } /* End _DtHelpCeFrmtSdlVolumeAbstractToAscii */
10094
10095 /******************************************************************************
10096  * Function:    int _DtHelpCeFrmtSDLVolTitleToAscii (
10097  *                              char *filename,
10098  *                              int offset,
10099  *                              char **ret_title, char **ret_abbrev)
10100  *
10101  * Parameters:
10102  *
10103  * Returns:     0 if successful, -1 if errors
10104  *
10105  * Purpose:
10106  ******************************************************************************/
10107 int
10108 _DtHelpCeFrmtSDLVolTitleToAscii(
10109     _DtHelpVolumeHdl volume,
10110     _FrmtUiInfo *ui_info,
10111     char        **ret_title)
10112 {
10113     char                *abbrev  = NULL;
10114     int                  result  = 0;
10115     _DtCvSegment        *pHeadSeg;
10116     _DtHelpCeLockInfo    lockInfo;
10117
10118     *ret_title = NULL;
10119
10120     /*
10121      * get the head element
10122      */
10123     if (_DtHelpCeLockVolume(volume, &lockInfo) != 0)
10124         return -1;
10125
10126     result = GetDocumentTitle(volume,ui_info, _SdlFontModeNone, False, &pHeadSeg);
10127     _DtHelpCeUnlockVolume(lockInfo);
10128
10129     if (result == 0)
10130       {
10131         /*
10132          * get the abbreviation of the head
10133          */
10134         result = -2;
10135         if (pHeadSeg != NULL)
10136           {
10137             CreateAsciiAbbrev(pHeadSeg, &abbrev);
10138
10139             if (abbrev != NULL && *abbrev != '\0')
10140               {
10141                 *ret_title = abbrev;
10142                 result     = 0;
10143               }
10144           }
10145
10146         /*
10147          * if there wasn't an abbreviation, use the head itself, stripping
10148          * all special items and graphics.
10149          */
10150         if (0 != result && pHeadSeg != NULL &&
10151                                 NULL != _DtCvContainerListOfSeg(pHeadSeg))
10152           {
10153             _DtCvValue   nlFlag = False;
10154
10155             CreateAsciiString(_DtCvContainerListOfSeg(pHeadSeg),
10156                                                 GetSdlDocSnb(volume),
10157                                                 &nlFlag, ret_title);
10158             if (abbrev != NULL)
10159                 free(abbrev);
10160
10161             result = 0;
10162           }
10163       }
10164
10165     /*
10166      * if there isn't an abbreviation on the document, and there isn't
10167      * a head, then try for the title page. After that, try the
10168      * hometopic's title.
10169      */
10170     if (-2 == result)
10171       {
10172         result = 0;
10173         if (_DtHelpGetTopicTitle(volume, "_title", ret_title) != 0)
10174             result = _DtHelpGetTopicTitle(volume, "_hometopic", ret_title);
10175       }
10176
10177     return result;
10178
10179 } /* End _DtHelpCeFrmtSDLVolTitleToAscii */
10180
10181 /******************************************************************************
10182  * Function:    int _DtHelpCeGetSdlTopicTitleChunks (
10183  *
10184  * Parameters:
10185  *
10186  * Returns:     0 if successful, -1 if errors
10187  *
10188  * Purpose:
10189  ******************************************************************************/
10190 int
10191 _DtHelpCeGetSdlTitleChunks(
10192     _DtHelpVolumeHdl      volume,
10193     char                  *loc_id,
10194     _FrmtUiInfo           *ui_info,
10195     void                ***ret_chunks)
10196 {
10197     int                  result = 0;
10198     int                  offset;
10199     FormatStruct         frmtStruct;
10200     CESDLVolume         *sdlVol;
10201     SDLMask              stopMask[SDL_MASK_LEN] =
10202                                         SDLInitMask(SdlElementSubHead);
10203
10204     *ret_chunks = NULL;
10205     if (_DtHelpCeFindSdlId(volume, loc_id, -1, NULL, &offset) != True)
10206         return -1;
10207
10208     if (SetUp(volume, &sdlVol, &frmtStruct, NULL, ui_info, -1, True, True) != 0)
10209         return -1;
10210
10211     result = FormatSDLTitle(frmtStruct.vol_name, offset, -1, &frmtStruct);
10212
10213     if (result != -1 && frmtStruct.seg_list != NULL)
10214       {
10215         _DtCvSegment  *headEl;
10216         _DtCvSegment  *pSnbEl = NULL;
10217
10218         result = -1;
10219         headEl = _DtCvContainerListOfSeg(frmtStruct.seg_list);
10220
10221         /*
10222          * A virpage contains a zero or more heads as it's first
10223          * content.  Therefore, if the the first item is not a
10224          * container and a controller (heads get the controller flag
10225          * put on them), then this virpage does not have a title.
10226          */
10227         if (NULL != headEl && _DtCvIsSegContainer(headEl) &&
10228                                                 _DtCvIsSegController(headEl))
10229           {
10230             result = ProcessSegmentsToChunks(frmtStruct.toss,
10231                                         headEl,
10232                                         pSnbEl, stopMask,
10233                                         _DtHelpCeGetSdlVolLanguage(volume),
10234                                         _DtHelpCeGetSdlVolCharSet(volume),
10235                                         ui_info->resolve_spc,
10236                                         ui_info->client_data,
10237                                         ret_chunks);
10238           }
10239       }
10240     else
10241         result = -1;
10242
10243     if (frmtStruct.seg_list != NULL)
10244         _DtHelpFreeSegments(frmtStruct.seg_list, _DtCvFALSE,
10245                                                 ui_info->destroy_region,
10246                                                 ui_info->client_data);
10247
10248     if (frmtStruct.snb != NULL)
10249         _DtHelpFreeSegments(frmtStruct.snb, _DtCvFALSE,
10250                                                 ui_info->destroy_region,
10251                                                 ui_info->client_data);
10252
10253     /*
10254      * free the font structures allocated
10255      */
10256     DestroyFontInfo(&frmtStruct);
10257
10258     /*
10259      * destroy the link database
10260      */
10261     _DtLinkDbDestroy(frmtStruct.my_links);
10262
10263     return result;
10264
10265 } /* End _DtHelpCeGetSdlTitleChunks */
10266
10267 /******************************************************************************
10268  * Function:    int _DtHelpCeGetSdlVolTitleChunks (
10269  *
10270  * Parameters:
10271  *
10272  * Returns:     0 if successful, -1 if errors
10273  *
10274  * Purpose:
10275  ******************************************************************************/
10276 int
10277 _DtHelpCeGetSdlVolTitleChunks(
10278     _DtHelpVolumeHdl     volume_handle,
10279     _FrmtUiInfo         *ui_info,
10280     void                ***ret_chunks)
10281 {
10282     int                  result  = -2;
10283     _DtCvSegment        *pHeadSeg;
10284     CESDLVolume         *sdlVol;
10285     SDLMask              stopMask[SDL_MASK_LEN] =
10286                                         SDLInitMask(SdlElementSubHead);
10287     /*
10288      * get the sdl volume pointer.
10289      */
10290     sdlVol = _DtHelpCeGetSdlVolumePtr(volume_handle);
10291     if (sdlVol ==  NULL)
10292         return -1;
10293
10294     /*
10295      * find the document attributes
10296      */
10297     if (NULL == sdlVol->sdl_info)
10298         return -1;
10299
10300     /*
10301      * get the head element
10302      */
10303     if (GetDocumentTitle(volume_handle, ui_info,
10304                                 _SdlFontModeResolve, True, &pHeadSeg) == -1)
10305         return -1;
10306
10307     /*
10308      * process it
10309      */
10310     if (pHeadSeg != NULL)
10311         result = ProcessSegmentsToChunks(
10312                                 _DtHelpCeGetSdlVolToss(volume_handle, -1),
10313                                 pHeadSeg,
10314                                 GetSdlDocSnb(volume_handle), stopMask,
10315                                 _DtHelpCeGetSdlVolLanguage(volume_handle),
10316                                 _DtHelpCeGetSdlVolCharSet(volume_handle),
10317                                 ui_info->resolve_spc,
10318                                 ui_info->client_data,
10319                                 ret_chunks);
10320     if (result != 0)
10321       {
10322         result = _DtHelpCeGetSdlTitleChunks(volume_handle, "_title",
10323                                                 ui_info, ret_chunks);
10324         if (result != 0)
10325             result = _DtHelpCeGetSdlTitleChunks(volume_handle, "_hometopic",
10326                                                 ui_info, ret_chunks);
10327       }
10328
10329     return result;
10330
10331 } /* End _DtHelpCeGetSdlVolTitleChunks */
10332
10333 /******************************************************************************
10334  * Function:    int _DtHelpCeGetSdlVolToss (
10335  *                              _DtHelpVolumeHdl volume,
10336  * Parameters:
10337  *              volume          Specifies the volume to read/parse.
10338  *
10339  * Returns:     0 if successful, -1 if errors
10340  *
10341  * Purpose:     Get the toss from a volume.
10342  ******************************************************************************/
10343 _DtCvSegment *
10344 _DtHelpCeGetSdlVolToss(
10345     _DtHelpVolumeHdl volume,
10346     int          fd)
10347 {
10348     CESDLVolume         *sdlVol;
10349     FormatStruct         frmtStruct;
10350     SDLMask              skipMask   [SDL_MASK_LEN] = SDLClearAllBits;
10351     SDLMask              startExcept[SDL_MASK_LEN] =
10352                                         SDLInitMask(SdlElementNone);
10353     /*
10354      * get the sdl volume pointer.
10355      */
10356     sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
10357     if (sdlVol == NULL)
10358         return NULL;
10359
10360     if (sdlVol->toss == NULL
10361         && SetUp(volume,NULL,&frmtStruct,NULL,&DefUiInfo,fd,True,False) == 0
10362         && _DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume), 0, fd,
10363                                         &(frmtStruct.my_file), NULL) != -1)
10364       {
10365         if (ProcessContent(&frmtStruct, SDLDocumentContent,
10366                                 SdlElementNone, startExcept, skipMask) != -1
10367             && ProcessSDLMarkup(&frmtStruct, SdlElementVStruct,
10368                                 SdlElementToss, startExcept, skipMask) != -1)
10369             sdlVol->toss = frmtStruct.seg_list;
10370
10371         _DtHelpCeBufFileClose (frmtStruct.my_file, (fd == -1 ? True : False));
10372
10373         /*
10374          * free the font structures allocated
10375          */
10376         DestroyFontInfo(&frmtStruct);
10377
10378         /*
10379          * destroy the link database
10380          */
10381         _DtLinkDbDestroy(frmtStruct.my_links);
10382       }
10383
10384     if (sdlVol->toss != NULL)
10385         return (_DtCvContainerListOfSeg(sdlVol->toss));
10386
10387     return NULL;
10388
10389 } /* End _DtHelpCeGetSdlVolToss */
10390
10391 /******************************************************************************
10392  * Function:    int _DtHelpCeGetSdlVolIndex (
10393  *                              _DtHelpVolumeHdl volume,
10394  * Parameters:
10395  *              volume          Specifies the volume to read/parse.
10396  *
10397  * Returns:     0 if successful, -1 if errors
10398  *
10399  * Purpose:     Get the index from a volume.
10400  ******************************************************************************/
10401 int
10402 _DtHelpCeGetSdlVolIndex(
10403     _DtHelpVolumeHdl volume)
10404 {
10405     int                  result = -1;
10406     CESDLVolume         *sdlVol;
10407     FormatStruct         frmtStruct;
10408     SDLMask              skipMask   [SDL_MASK_LEN] = SDLClearAllBits;
10409     SDLMask              startExcept[SDL_MASK_LEN] =
10410                                         SDLInitMask(SdlElementNone);
10411
10412     sdlVol = _DtHelpCeGetSdlVolumePtr(volume);
10413     if (sdlVol == NULL)
10414         return -1;
10415
10416     if (sdlVol->index != NULL)
10417         return 0;
10418
10419     if (SetUp(volume, NULL, &frmtStruct, NULL, &DefUiInfo, -1, True, True) != 0)
10420         return -1;
10421
10422     /*
10423      * now set up correct font mode.
10424      */
10425     frmtStruct.resolve_font = _SdlFontModeNone;
10426
10427     if (_DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume), 0, -1,
10428                                         &(frmtStruct.my_file), NULL) != -1)
10429       {
10430         if (ProcessContent(&frmtStruct, SDLDocumentContent,
10431                                 SdlElementNone, startExcept, skipMask) != -1
10432             && ProcessSDLMarkup(&frmtStruct, SdlElementVStruct,
10433                                 SdlElementIndex, startExcept, skipMask) != -1)
10434           {
10435             sdlVol->index = frmtStruct.seg_list;
10436             result = 0;
10437           }
10438
10439         _DtHelpCeBufFileClose (frmtStruct.my_file, True);
10440       }
10441
10442     /*
10443      * destroy the link database
10444      */
10445     _DtLinkDbDestroy(frmtStruct.my_links);
10446
10447     /*
10448      * free the font structures allocated
10449      */
10450     DestroyFontInfo(&frmtStruct);
10451
10452     return result;
10453
10454 } /* End _DtHelpCeGetSdlVolIndex */
10455
10456 /******************************************************************************
10457  * Function:    int _DtHelpCeGetSdlVolIds (
10458  *                              _DtHelpVolumeHdl volume,
10459  *                              _DtCvSegment **ret_ids
10460  * Parameters:
10461  *              volume          Specifies the volume to read/parse.
10462  *
10463  * Returns:     0 if successful, -1 if errors
10464  *
10465  * Purpose:     Get the loids from a volume.
10466  ******************************************************************************/
10467 int
10468 _DtHelpCeGetSdlVolIds(
10469     _DtHelpVolumeHdl      volume,
10470     int                   fd,
10471     _DtCvSegment                **ret_ids)
10472 {
10473     int                  result = 0;
10474     CESDLVolume         *sdlVol;
10475     FormatStruct         frmtStruct;
10476     SDLMask              skipMask   [SDL_MASK_LEN] = SDLClearAllBits;
10477     SDLMask              startExcept[SDL_MASK_LEN] =
10478                                         SDLInitMask(SdlElementNone);
10479
10480     *ret_ids = NULL;
10481     sdlVol   = _DtHelpCeGetSdlVolumePtr(volume);
10482     if (sdlVol == NULL)
10483         return -1;
10484
10485     if (sdlVol->loids == NULL)
10486       {
10487         result = -1;
10488         if (SetUp(NULL,NULL,&frmtStruct,NULL,&DefUiInfo,-1,False,False) != -1
10489             && _DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume), 0, fd,
10490                                         &(frmtStruct.my_file), NULL) != -1)
10491           {
10492             if (ProcessContent(&frmtStruct, SDLDocumentContent,
10493                                 SdlElementNone, startExcept, skipMask) != -1)
10494               {
10495                 if (ProcessSDLMarkup(&frmtStruct, SdlElementVStruct,
10496                                 SdlElementLoids, startExcept, skipMask) != -1)
10497                   {
10498                     sdlVol->loids = frmtStruct.seg_list;
10499                     result = 0;
10500                   }
10501               }
10502
10503             /*
10504              * free the font structures allocated
10505              */
10506             DestroyFontInfo(&frmtStruct);
10507
10508             /*
10509              * destroy the link database
10510              */
10511             _DtLinkDbDestroy(frmtStruct.my_links);
10512
10513             _DtHelpCeBufFileClose(frmtStruct.my_file,(fd == -1 ? True : False));
10514           }
10515       }
10516
10517     if (sdlVol->loids != NULL)
10518         *ret_ids = _DtCvContainerListOfSeg(sdlVol->loids);
10519
10520     return result;
10521
10522 } /* End _DtHelpCeGetSdlVolIds */
10523
10524 /******************************************************************************
10525  * Function:    int _DtHelpCeParseSdlTopic (_DtHelpVolumeHdl volume,
10526  *                              int offset, char *id_string,
10527  *                              _DtCvTopicPtr *ret_handle)
10528  *
10529  * Parameters:
10530  *              volume          Specifies the Help Volume the information
10531  *                              is associated with.
10532  *              offset          Specifies the offset into 'filename' to
10533  *                              the Help Topic desired.
10534  *              id_string       Specifies the location id to look for or NULL.
10535  *              ret_handle      Returns a handle to the topic information
10536  *                              including the number of paragraphs and the
10537  *                              id match segment.
10538  *
10539  * Returns:     0 if successful, -1 if errors
10540  *
10541  * Purpose:     _DtHelpCeParseSdlTopic formats Help Files with formatting
10542  *              information into a CEVirtualPage
10543  *
10544  ******************************************************************************/
10545 int
10546 _DtHelpCeParseSdlTopic(
10547     _DtHelpVolumeHdl     volume,
10548     _FrmtUiInfo         *ui_info,
10549     int                  fd,
10550     int                  offset,
10551     char                *id_string,
10552     int                  rich_text,
10553     _DtCvTopicPtr       *ret_handle)
10554 {
10555     int                  result = 0;
10556     SDLMask              startExcept[SDL_MASK_LEN] =
10557                                         SDLInitMask(SdlElementNone);
10558     SDLMask              processMask[SDL_MASK_LEN]  = SDLSetAllBits;
10559     FormatStruct         frmtStruct;
10560     _DtCvTopicInfo      *topicHandle;
10561     CESDLVolume         *sdlVol;
10562
10563     *ret_handle = NULL;
10564
10565     if (SetUp(volume,&sdlVol,&frmtStruct,NULL,ui_info,fd,True,rich_text) != 0)
10566         return -1;
10567
10568     /*
10569      * remember the id for graphics
10570      */
10571     frmtStruct.id_string = id_string;
10572
10573     result = _DtHelpCeFileOpenAndSeek(_DtHelpCeGetVolumeName(volume),
10574                                         offset, fd,
10575                                         &(frmtStruct.my_file), NULL);
10576     if (result != -1)
10577       {
10578         result = ProcessSDLMarkup (&frmtStruct, SdlElementVirpage,
10579                                 SdlElementNone, startExcept, processMask);
10580         _DtHelpCeBufFileClose (frmtStruct.my_file, (fd == -1 ? True : False));
10581       }
10582
10583     /*
10584      * free the async blocks
10585      */
10586     _DtHelpFreeSegments(frmtStruct.async_blks, _DtCvFALSE,
10587                                                 ui_info->destroy_region,
10588                                                 ui_info->client_data);
10589
10590     /*
10591      * free the system notation blocks
10592      */
10593     _DtHelpFreeSegments(frmtStruct.snb, _DtCvFALSE,
10594                                                 ui_info->destroy_region,
10595                                                 ui_info->client_data);
10596
10597     if (result != -1)
10598       {
10599         topicHandle = (_DtCvTopicInfo *) malloc (sizeof(_DtCvTopicInfo));
10600         if (topicHandle != NULL)
10601           {
10602             topicHandle->mark_list = NULL;
10603             topicHandle->id_str    = NULL;
10604             if (id_string != NULL)
10605                 topicHandle->id_str = strdup(id_string);
10606
10607             topicHandle->link_data = frmtStruct.my_links;
10608             topicHandle->seg_list  = frmtStruct.seg_list;
10609             *ret_handle = (void *) topicHandle;
10610           }
10611         else
10612             result = -1;
10613       }
10614
10615     /*
10616      * free the allocated font structures
10617      */
10618     DestroyFontInfo(&frmtStruct);
10619
10620     return result;
10621
10622 } /* End _DtHelpCeParseSdlTopic */