Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / lib / DtHelp / CCDFUtil.c
1 /* $XConsortium: CCDFUtil.c /main/7 1996/11/01 10:10:08 drk $ */
2 /************************************<+>*************************************
3  ****************************************************************************
4  **
5  **   File:     CCDFUtil.c
6  **
7  **   Project:    Un*x Desktop Help
8  **
9  **  
10  **   Description: Semi private format utility functions for
11  **                formatting CCDF
12  **
13  **
14  **  (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
15  **
16  **  (c) Copyright 1993, 1994 Hewlett-Packard Company
17  **  (c) Copyright 1993, 1994 International Business Machines Corp.
18  **  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
19  **  (c) Copyright 1993, 1994 Novell, Inc.
20  **
21  **
22  ****************************************************************************
23  ************************************<+>*************************************/
24
25 /*
26  * system includes
27  */
28 #include <errno.h>
29 #include <limits.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34
35 #include <X11/Xos.h>
36 #ifdef X_NOT_STDC_ENV
37 extern int errno;
38 #endif
39
40 /*
41  * Canvas Engine includes
42  */
43 #include "CanvasP.h"
44
45 /*
46  * private includes
47  */
48 #include "bufioI.h"
49 #include "CanvasError.h"
50 #include "CCDFUtilI.h"
51 #include "FontAttrI.h"
52 #include "CvStringI.h"
53
54 #ifdef NLS16
55 #endif
56
57 /********    Private Function Declarations    ********/
58 static  int     GetCmdData(
59         BufFilePtr in_file,
60         char      *in_buf,
61         int        in_size,
62         char     **in_ptr,
63         int        cur_mb_len,
64         int        allowed,
65         int        strip,
66         int       *ret_size,
67         int       *ret_max,
68         char     **ret_string );
69 /********    End Private Function Declarations    ********/
70
71 /******************************************************************************
72  *
73  * Private variables and defines.
74  *
75  *****************************************************************************/
76 #define MIN_GROW        16
77 #define REALLOC_INCR 10
78 #define CMD_NOT_ALLOWED         -1000
79
80 typedef struct {
81         char *cmd;
82         int   type;
83         int   significant;
84 } FormatCmds;
85
86 static const FormatCmds  CcdfFormatCmds[] =
87   {
88         { "abbrev"      , CCDF_ABBREV_CMD   , 2 },
89         { "angle"       , CCDF_FONT_CMD     , 2 },
90         { "characterset", CCDF_FONT_CMD     , 1 },
91         { "figure"      , CCDF_FIGURE_CMD   , 1 },
92         { "graphic"     , CCDF_GRAPHIC_CMD  , 1 },
93         { "id"          , CCDF_ID_CMD       , 1 },
94         { "label"       , CCDF_LABEL_CMD    , 2 },
95         { "link"        , CCDF_LINK_CMD     , 2 },
96         { "newline"     , CCDF_NEWLINE_CMD  , 1 },
97         { "paragraph"   , CCDF_PARAGRAPH_CMD, 1 },
98         { "size"        , CCDF_FONT_CMD     , 2 },
99         { "spacing"     , CCDF_FONT_CMD     , 2 },
100         { "title"       , CCDF_TITLE_CMD    , 2 },
101         { "topic"       , CCDF_TOPIC_CMD    , 2 },
102         { "type"        , CCDF_FONT_CMD     , 2 },
103         { "weight"      , CCDF_FONT_CMD     , 1 },
104         { "0x"          , CCDF_OCTAL_CMD    , 2 },
105         /* always leave this one as the last entry */
106         { "/"           , CCDF_FORMAT_END   , 1 }
107   };
108
109 /******************************************************************************
110  *
111  * Semi Public variables.
112  *
113  *****************************************************************************/
114 /******************************************************************************
115  *
116  * Private Functions
117  *
118  *****************************************************************************/
119 /******************************************************************************
120  * Function: static int GetCmdData (FILE *in_file, char *in_buf, int in_size,
121  *                              char **in_ptr, int allowed, int strip,
122  *                              int *ret_size, int *ret_max, char **ret_string)
123  *
124  * Parameters:
125  *              in_file         Specifies a stream to read from.
126  *              in_buf          Specifies the buffer where new information
127  *                                      is placed.
128  *              in_size         Specifies the maximum size of 'in_buf'.
129  *              in_ptr          Specifies the pointer into 'in_buf' to
130  *                                      start processing.
131  *                              Returns the new location in 'in_buf' to
132  *                                      continue processing.
133  *              allowed         Specifies the formatting commands allowed
134  *                              in the data.
135  *              strip           Specifies the formatting commands to strip.
136  *                              from the data.
137  *              ret_size        Specifies the current size of
138  *                                      'ret_string'.
139  *                              Returns the new size of 'ret_string'.
140  *              ret_max         Specifies the current maximum size of
141  *                                      'ret_string'
142  *                              Returns the new size of 'ret_string'.
143  *              ret_string      Returns the data found.
144  *                              
145  *
146  * Returns:     0 if successful, -1 if errors.
147  *
148  * errno Values:
149  *              read (2)        Errors set via a read call.
150  *              EINVAL
151  *              CEErrorMalloc
152  *              CEErrorIllegalInfo
153  *              CEErrorReadEmpty
154  *
155  * 
156  * Purpose:     Gets a string containing font change tags
157  *              Incoming source:
158  *                      "data with font change tags </>"
159  *
160  *****************************************************************************/
161 static int
162 GetCmdData(
163         BufFilePtr in_file,
164         char      *in_buf,
165         int        in_size,
166         char     **in_ptr,
167         int        cur_mb_len,
168         int        allowed,
169         int        strip,
170         int       *ret_size,
171         int       *ret_max,
172         char     **ret_string )
173 {
174     int       size;
175     int       fontType;
176     int       charSize = 1;
177     int       result = 0;
178     char     *myBufPtr   = *in_ptr;
179     char     *tmpPtr;
180     int   skipString = False;
181     int   endToken;
182     int   stripCmd;
183
184     if (!ret_string)
185         skipString = True;
186
187     while (!result)
188       {
189         if (cur_mb_len != 1)
190             charSize = mblen(myBufPtr, cur_mb_len);
191
192         if (charSize == 1)
193           {
194             /*
195               * Do we need to read more information?
196               */
197             if (((int) strlen (myBufPtr)) < 3 &&
198                 _DtHelpCeGetNxtBuf(in_file,in_buf,&myBufPtr,in_size) == -1)
199                  return -1;
200
201             switch (*myBufPtr)
202               {
203                 case '<':
204                         /*
205                          * Go to the next character.
206                          */
207                         myBufPtr++;
208                         endToken = True;
209                         stripCmd = False;
210
211                         /*
212                          * end token
213                          */
214                         if (*myBufPtr == '/')
215                           {
216                             *in_ptr = myBufPtr;
217                             return _DtHelpCeGetCcdfEndMark (in_file, in_buf,
218                                                 in_ptr, in_size,cur_mb_len);
219                           }
220
221                         fontType = _DtHelpCeGetCcdfFontType (myBufPtr);
222                         if (fontType == -1)
223                           {
224                             switch (_DtCvToLower (*myBufPtr))
225                               {
226                                 /*
227                                  * <0xff>
228                                  */
229                                 case '0':
230                                     if ((!skipString &&
231                                                 _DtHelpCeAddOctalToBuf (
232                                                         myBufPtr,
233                                                         ret_string, ret_size,
234                                                         ret_max, 0) == -1)
235                                                 ||
236                                         _DtHelpCeGetCcdfEndMark (in_file, in_buf,
237                                                 &myBufPtr,in_size,cur_mb_len) == -1)
238                                         return -1;
239
240                                     endToken = False;
241                                     break;
242
243                                 /*
244                                  * <abbrev>
245                                  */
246                                 case 'a':
247                                     myBufPtr++;
248                                     if (_DtCvToLower (*myBufPtr) == 'b')
249                                       {
250                                         if (CCDF_NOT_ALLOW_CMD (allowed,
251                                                         CCDF_ABBREV_CMD))
252                                           {
253                                             errno = CMD_NOT_ALLOWED;
254                                             return -1;
255                                           }
256                                         else if (CCDF_NOT_ALLOW_CMD (strip,
257                                                         CCDF_ABBREV_CMD))
258                                             stripCmd = True;
259                                       }
260                                     else
261                                       {
262                                         errno = CEErrorFormattingCmd;
263                                         return -1;
264                                       }
265
266                                     break;
267                                         
268
269                                 /*
270                                  * <figure>
271                                  */
272                                 case 'f':
273                                     if (CCDF_NOT_ALLOW_CMD (allowed,
274                                                         CCDF_FIGURE_CMD))
275                                       {
276                                         errno = CMD_NOT_ALLOWED;
277                                         return -1;
278                                       }
279                                     else if (CCDF_NOT_ALLOW_CMD (strip,
280                                                         CCDF_FIGURE_CMD))
281                                         stripCmd = True;
282
283                                     break;
284                                         
285                                 /*
286                                  * <graphic>
287                                  */
288                                 case 'g':
289                                     if (CCDF_NOT_ALLOW_CMD (allowed,
290                                                         CCDF_GRAPHIC_CMD))
291                                       {
292                                         errno = CMD_NOT_ALLOWED;
293                                         return -1;
294                                       }
295
296                                     if (_DtHelpCeGetCcdfEndMark (in_file, in_buf,
297                                                 &myBufPtr,in_size,cur_mb_len) == -1)
298                                         return -1;
299
300                                     endToken = False;
301                                     break;
302
303                                 /*
304                                  * <id>
305                                  */
306                                 case 'i':
307                                     if (CCDF_NOT_ALLOW_CMD (allowed,
308                                                         CCDF_ID_CMD))
309                                       {
310                                         errno = CMD_NOT_ALLOWED;
311                                         return -1;
312                                       }
313                                     else if (CCDF_NOT_ALLOW_CMD (strip,
314                                                         CCDF_ID_CMD))
315                                         stripCmd = True;
316                                     break;
317
318                                 /*
319                                  * <label>
320                                  * <link>
321                                  */
322                                 case 'l':
323                                     myBufPtr++;
324                                     if (_DtCvToLower (*myBufPtr) == 'a')
325                                       {
326                                         if (CCDF_NOT_ALLOW_CMD (allowed,
327                                                         CCDF_LABEL_CMD))
328                                           {
329                                             errno = CMD_NOT_ALLOWED;
330                                             return -1;
331                                           }
332                                         else if (CCDF_NOT_ALLOW_CMD (strip,
333                                                         CCDF_LABEL_CMD))
334                                             stripCmd = True;
335                                       }
336                                     else if (_DtCvToLower (*myBufPtr) == 'i')
337                                       {
338                                         if (CCDF_NOT_ALLOW_CMD (allowed,
339                                                         CCDF_LINK_CMD))
340                                           {
341                                             errno = CMD_NOT_ALLOWED;
342                                             return -1;
343                                           }
344                                         else if (CCDF_NOT_ALLOW_CMD (strip,
345                                                         CCDF_LINK_CMD))
346                                             stripCmd = True;
347                                       }
348                                     else
349                                       {
350                                         errno = CEErrorFormattingCmd;
351                                         return -1;
352                                       }
353
354                                     break;
355
356                                 /*
357                                  * <newline>
358                                  */
359                                 case 'n':
360                                     if (CCDF_NOT_ALLOW_CMD (allowed,
361                                                         CCDF_NEWLINE_CMD))
362                                       {
363                                         errno = CMD_NOT_ALLOWED;
364                                         return -1;
365                                       }
366
367                                     if (_DtHelpCeGetCcdfEndMark (in_file, in_buf,
368                                                 &myBufPtr,in_size,cur_mb_len) == -1)
369                                         return -1;
370
371                                     endToken = False;
372                                     break;
373
374                                 /*
375                                  * <paragraph>
376                                  */
377                                 case 'p':
378                                     if (CCDF_NOT_ALLOW_CMD (allowed,
379                                                         CCDF_PARAGRAPH_CMD))
380                                       {
381                                         errno = CMD_NOT_ALLOWED;
382                                         return -1;
383                                       }
384                                     else if (CCDF_NOT_ALLOW_CMD (strip,
385                                                         CCDF_PARAGRAPH_CMD))
386                                         stripCmd = True;
387                                     break;
388
389                                 /*
390                                  * <title>
391                                  * <topic>
392                                  */
393                                 case 't':
394                                     myBufPtr++;
395                                     if (_DtCvToLower (*myBufPtr) == 'o')
396                                       {
397                                         if (CCDF_NOT_ALLOW_CMD (allowed,
398                                                         CCDF_TOPIC_CMD))
399                                           {
400                                             errno = CMD_NOT_ALLOWED;
401                                             return -1;
402                                           }
403                                         else if (CCDF_NOT_ALLOW_CMD (strip,
404                                                         CCDF_TOPIC_CMD))
405                                             stripCmd = True;
406                                       }
407                                     else if (_DtCvToLower (*myBufPtr) == 'i')
408                                       {
409                                         if (CCDF_NOT_ALLOW_CMD (allowed,
410                                                         CCDF_TITLE_CMD))
411                                           {
412                                             errno = CMD_NOT_ALLOWED;
413                                             return -1;
414                                           }
415                                         else if (CCDF_NOT_ALLOW_CMD (strip,
416                                                         CCDF_TITLE_CMD))
417                                             stripCmd = True;
418                                       }
419                                     else
420                                       {
421                                         errno = CEErrorFormattingCmd;
422                                         return -1;
423                                       }
424
425                                     break;
426
427                                 default:
428                                     errno = CEErrorFormattingCmd;
429                                     return -1;
430                               }
431                           }
432                         else if (CCDF_NOT_ALLOW_CMD (allowed, CCDF_FONT_CMD))
433                           {
434                             errno = CMD_NOT_ALLOWED;
435                             return -1;
436                           }
437                         else if (CCDF_NOT_ALLOW_CMD (strip, CCDF_FONT_CMD))
438                             stripCmd = True;
439
440                         if (endToken)
441                           {
442                             /*
443                              * This is a <token>....</token> construct.
444                              * pass over the <token> part.
445                              */
446                             if (_DtHelpCeGetCcdfEndMark (in_file, in_buf,
447                                         &myBufPtr, in_size,cur_mb_len) == -1 ||
448                                 GetCmdData (in_file, in_buf, in_size,
449                                         &myBufPtr, cur_mb_len, allowed, strip,
450                                         ret_size, ret_max, ret_string) == -1)
451                                 return -1;
452                           }
453                         break;
454
455                 case ' ':
456                 case '\n':
457                         /*
458                          * Put a space in the segment
459                          */
460                         if (!skipString)
461                           {
462                             tmpPtr = " ";
463                             result = _DtHelpCeAddCharToBuf (&tmpPtr,
464                                 ret_string, ret_size, ret_max, MIN_GROW);
465                           }
466                         myBufPtr++;
467                         break;
468
469                 case '\\':
470                         myBufPtr++;
471
472                         /*
473                          * Save the escaped character
474                          */
475                         if (!skipString)
476                             result = _DtHelpCeAddCharToBuf (&myBufPtr,
477                                 ret_string, ret_size, ret_max, MIN_GROW);
478                         else
479                             myBufPtr++;
480                         break;
481
482                 default:
483                         /*
484                          * Put the information in the buffer
485                          */
486                         result = _DtHelpCeStrcspn (myBufPtr, "<\\\n ",
487                                                         cur_mb_len, &size);
488                         /*
489                          * If _DtHelpCeStrcspn found an invalid character
490                          * we don't want to quit yet. Allow another pass
491                          * to try to read another buffer of information.
492                          */
493                         result = 0;
494
495                         if (!skipString && size)
496                             result = _DtHelpCeAddStrToBuf (&myBufPtr,
497                                 ret_string, ret_size, ret_max, size, 0);
498                         else
499                             myBufPtr += size;
500               }
501           }
502         else if (charSize > 1)
503           {
504             result = _DtHelpCeStrcspn (myBufPtr, "<\\\n ", cur_mb_len, &size);
505
506             /*
507              * If _DtHelpCeStrcspn found an invalid character
508              * we don't want to quit yet. Allow another pass
509              * to try to read another buffer of information.
510              */
511             result = 0;
512
513             if (!skipString && size)
514                 result = _DtHelpCeAddStrToBuf (&myBufPtr,
515                                 ret_string, ret_size, ret_max, size, 0);
516             else
517                 myBufPtr += size;
518           }
519         else /* if (charSize < 1) */
520           {
521             if (*myBufPtr == '\0' || ((int) strlen (in_buf)) < cur_mb_len)
522                 result = _DtHelpCeGetNxtBuf(in_file,in_buf,&myBufPtr,in_size);
523             else
524               {
525                 errno = CEErrorIllegalInfo;
526                 result = -1;
527               }
528           }
529       }
530     return result;
531 }
532
533 /******************************************************************************
534  * Function: int GetTitleCmd (FILE *in_file, char in_buf, int in_size,
535  *                              char **in_ptr, char **ret_string)
536  * 
537  * Parameters:
538  *              in_file         Specifies a stream to read from.
539  *              in_buf          Specifies the buffer where new information
540  *                                      is placed.
541  *              in_size         Specifies the maximum size of 'in_buf'.
542  *              in_ptr          Specifies the pointer into 'in_buf' to
543  *                                      start processing.
544  *                              Returns the new location in 'in_buf' to
545  *                                      continue processing.
546  *              ret_string      Returns the data found.
547  *
548  * Returns:     0 if successful, -1 if errors
549  *
550  * errno Values:
551  *              read (2)        Errors set via a read call.
552  *              EINVAL
553  *              CEErrorIllegalInfo
554  *              CEErrorReadEmpty
555  *
556  * Purpose:     Determine if the next formatting command is
557  *                      <ABBREV ...>.
558  *              Returns the data found between <ABBREV> and its ending </>.
559  *
560  * Note:        The only formatting command allowed between <ABBREV> and
561  *              its </> is the <NEWLINE> command. And it is stripped.
562  *
563  *****************************************************************************/
564 static int
565 GetTitleCmd(
566         BufFilePtr in_file,
567         char      *in_buf,
568         int        in_size,
569         int        cur_mb_len,
570         char     **in_ptr,
571         char     **ret_string )
572 {
573     int       result;
574     int       junkSize  = 0;
575     int       junkMax  = 0;
576
577     /*
578      * null the return string
579      */
580     if (ret_string)
581         *ret_string = NULL;
582
583     /*
584      * check for the token
585      */
586     result = _DtHelpCeCheckNextCcdfCmd ("ti", in_file, in_buf, in_size, cur_mb_len, in_ptr);
587     if (result != 0)
588       {
589         if (result == -2)
590             errno = CEErrorMissingTitleCmd;
591         return -1;
592       }
593
594     if (_DtHelpCeGetCcdfEndMark(in_file,in_buf,in_ptr,in_size,cur_mb_len) != 0)
595         return -1;
596
597     result = GetCmdData (in_file, in_buf, in_size, in_ptr, cur_mb_len,
598                         (CCDF_NEWLINE_CMD | CCDF_GRAPHIC_CMD |
599                                 CCDF_LINK_CMD | CCDF_FONT_CMD | CCDF_ID_CMD),
600                         (CCDF_NEWLINE_CMD | CCDF_GRAPHIC_CMD |
601                                 CCDF_LINK_CMD | CCDF_FONT_CMD | CCDF_ID_CMD),
602                         &junkSize, &junkMax, ret_string);
603
604     if (result == -1 && errno == CMD_NOT_ALLOWED)
605         errno = CEErrorTitleSyntax;
606
607     return result;
608 }
609
610 /******************************************************************************
611  *
612  * Semi Public Functions
613  *
614  *****************************************************************************/
615 /******************************************************************************
616  * Function:    int _DtHelpCeGetCcdfEndMark (FILE *file, char *buffer,
617  *                              char **buf_ptr, int buf_size, int flag)
618  *
619  * Parameters:
620  *              file            Specifies a stream to read from.
621  *              buffer          Specifies the buffer where new information
622  *                                      is placed.
623  *              buf_ptr         Specifies the pointer into 'buffer' to
624  *                                      start processing.
625  *                              Returns the new location in 'buffer' to
626  *                                      continue processing.
627  *              buf_size        Specifies the maximum size of 'buffer'.
628  *
629  *
630  * Return Value: 0 if successful, -1 if a failure occurs
631  *
632  * errno Values:
633  *              read (2)        Errors set via a read call.
634  *              EINVAL
635  *              CEErrorIllegalInfo
636  *              CEErrorReadEmpty
637  *
638  * Purpose:     Find the end of tag marker '>'.
639  *
640  ******************************************************************************/
641 int 
642 _DtHelpCeGetCcdfEndMark (
643      BufFilePtr   file,
644      char        *buffer,
645      char       **buf_ptr,
646      int          buf_size,
647      int          cur_mb_len)
648 {
649     int      len;
650     int      result;
651     char    *ptr;
652     int  done = False;
653
654     ptr = *buf_ptr;
655     do
656       {
657         /*
658          * Find the end of marker or end of topic
659          */
660         result = _DtHelpCeStrcspn (ptr, "\\>", cur_mb_len, &len);
661         ptr += len;
662
663         if (result == 0)
664           {
665             /*
666              * found either a backslash or the end marker,
667              * update the pointer and if it was the '>'
668              * say we're done.
669              */
670             if (*ptr == '>')
671                 done = True;
672             else
673                 ptr++;
674             ptr++;
675           }
676         else /* result == -1 || result == 1 */
677           {
678             /*
679              * nothing here - get the next buffer and keep looking
680              * unless getting the next buffer has problems/eof
681              */
682             if (((int) strlen(ptr)) >=  cur_mb_len)
683               {
684                 errno = CEErrorIllegalInfo;
685                 return -1;
686               }
687
688             if (_DtHelpCeGetNxtBuf (file, buffer, &ptr, buf_size) == -1)
689                 return -1;
690           }
691       } while (!done);
692
693     *buf_ptr = ptr;
694     return 0;
695 }
696
697 /******************************************************************************
698  * Function: int _DtHelpCeGetCcdfStrParam (FILE *in_file, char *in_buf,
699  *                              int in_size, char **in_ptr, int flag,
700  *                              int eat_escape, Boolean ignore_quotes,
701  *                              int less_test, char **ret_string)
702  * 
703  * Parameters:
704  *              in_file         Specifies a stream to read from.
705  *              in_buf          Specifies the buffer where new information
706  *                                      is placed.
707  *              in_size         Specifies the maximum size of 'in_buf'.
708  *              in_ptr          Specifies the pointer into 'in_buf' to
709  *                                      start processing.
710  *                              Returns the new location in 'in_buf' to
711  *                                      continue processing.
712  *              flag            Specifies whether the routine returns
713  *                                      a -1 if '>' is the next token.
714  *              eat_secape      Specifies whether the backslash is not
715  *                                      placed in the returned string.
716  *                                      True - it is skipped.
717  *                                      False - it is saved in 'ret_string'.
718  *              ignore_quotes   Specifies whether quotes are to be included
719  *                                      in the returned string.
720  *              less_test       Specifies whether the routine should
721  *                                      stop when it finds a '<' character.
722  *              ret_string      If NULL, throws the information away.
723  *                              Otherwise, returns the string found.
724  *
725  * Returns:     0 if successful, -1 if errors, 1 if 'flag' is false and
726  *              the next token is '>'.
727  *
728  * errno Values:
729  *              read (2)        Errors set via a read call.
730  *              EINVAL
731  *              CEErrorMalloc
732  *              CEErrorIllegalInfo
733  *              CEErrorReadEmpty
734  *
735  * Purpose:     Skip the rest of the current token.
736  *              Get the next token. A token is defined as being one or
737  *                      more strings between single or double quotes,
738  *                      or a string bounded by spaces or ended by the
739  *                      end token '>'.
740  *
741  *****************************************************************************/
742 int
743 _DtHelpCeGetCcdfStrParam(
744         BufFilePtr in_file,
745         char      *in_buf,
746         int        in_size,
747         int        cur_mb_len,
748         char     **in_ptr,
749     _DtCvValue    flag,
750     _DtCvValue    eat_escape,
751     _DtCvValue    ignore_quotes,
752     _DtCvValue    less_test,
753         char     **ret_string )
754 {
755     int          copySize;
756     int          result = 0;
757     int          spnResult;
758     int          stringSize = 0;
759     int          stringMax  = 0;
760     char        *stringPtr  = NULL;
761     char        *myBufPtr;
762     char        *mySpace;
763     int      done = False;
764     int      singleQuotes = False;
765     int      doubleQuotes = False;
766     int      skipString   = False;
767     int      testMB       = False;
768     
769     if (cur_mb_len != 1)
770         testMB = True;
771
772     /*
773      * do we want to skip the string or read it.
774      */
775     if (!ret_string)
776         skipString = True;
777
778     /*
779      * skip to the next parameter or > character. If flag is true,
780      * we want another parameter, so error if the > character is found.
781      */
782     if (_DtHelpCeSkipToNextCcdfToken (in_file, in_buf, in_size, cur_mb_len, in_ptr, flag) != 0)
783         return -1; 
784
785     myBufPtr = *in_ptr;
786
787     /*
788      * see if there is another parameter
789      */
790     if (_DtCvFALSE == flag && *myBufPtr == '>')
791         return 1;
792
793     /*
794      * Initialize the global buffer.
795      */
796     if (_DtCvFALSE == ignore_quotes &&
797                                 (!testMB || mblen (myBufPtr, cur_mb_len) == 1))
798       {
799         if (*myBufPtr == '\"')
800           {
801             doubleQuotes = True;
802             myBufPtr++;
803           }
804         else if (*myBufPtr == '\'')
805           {
806             singleQuotes = True;
807             myBufPtr++;
808           }
809       }
810
811     while (!done)
812       {
813         spnResult = _DtHelpCeStrcspn (myBufPtr, " <>\'\"\\\n",
814                                                 cur_mb_len, &copySize);
815         /*
816          * Either skip the string or place it in storage
817          */
818         if (skipString)
819             myBufPtr += copySize;
820         else if (_DtHelpCeAddStrToBuf (&myBufPtr, &stringPtr, &stringSize,
821                                         &stringMax, copySize, 0) == -1)
822             return -1;
823
824         /*
825          * If spnResult is non-zero, read the next buffer of information
826          */
827         if (spnResult)
828           {
829             if (spnResult == -1 && ((int)strlen(myBufPtr)) >= cur_mb_len)
830               {
831                 errno = CEErrorIllegalInfo;
832                 return -1;
833               }
834
835             if (_DtHelpCeGetNxtBuf(in_file,in_buf,&myBufPtr,in_size) == -1)
836                 return -1;
837           }
838
839         /*
840          * Otherwise _DtHelpCeStrcspn stopped at a character we want
841          */
842         else
843           {
844             switch (*myBufPtr)
845               {
846                 case '\\':
847                     if (_DtCvTRUE == eat_escape || skipString)
848                         myBufPtr++;
849                     else if (_DtHelpCeAddCharToBuf (&myBufPtr, &stringPtr,
850                                 &stringSize, &stringMax, MIN_GROW) == -1)
851                         return -1;
852
853                     if (*myBufPtr == '\0' && _DtHelpCeGetNxtBuf(in_file,
854                                         in_buf,&myBufPtr,in_size) == -1)
855                         return -1;
856
857                     if (skipString)
858                         myBufPtr++;
859                     else if (_DtHelpCeAddCharToBuf (&myBufPtr, &stringPtr,
860                                 &stringSize, &stringMax, MIN_GROW) == -1)
861                         return -1;
862                     break;
863
864                 case '\n':
865                     if (!doubleQuotes && !singleQuotes)
866                         done = True;
867                     else if (skipString)
868                         myBufPtr++;
869                     else
870                       {
871                         mySpace = " ";
872                         if (_DtHelpCeAddCharToBuf (&mySpace, &stringPtr,
873                                 &stringSize, &stringMax, MIN_GROW) == -1)
874                             return -1;
875                       }
876                     break;
877
878                 case '<':
879                     if (_DtCvTRUE == less_test)
880                         done = True;
881                     else if (skipString)
882                         myBufPtr++;
883                     else if (_DtHelpCeAddCharToBuf (&myBufPtr, &stringPtr,
884                                 &stringSize, &stringMax, MIN_GROW) == -1)
885                         return -1;
886                     break;
887
888                 case '>':
889                 case ' ':
890                     if (!doubleQuotes && !singleQuotes)
891                         done = True;
892                     else if (skipString)
893                         myBufPtr++;
894                     else if (_DtHelpCeAddCharToBuf (&myBufPtr, &stringPtr,
895                                 &stringSize, &stringMax, MIN_GROW) == -1)
896                         return -1;
897                     break;
898
899                 case '\'':
900                     if (_DtCvFALSE == ignore_quotes && singleQuotes)
901                         done = True;
902                     else if (skipString)
903                         myBufPtr++;
904                     else if (_DtHelpCeAddCharToBuf (&myBufPtr, &stringPtr,
905                                 &stringSize, &stringMax, MIN_GROW) == -1)
906                         return -1;
907                     break;
908
909                 case '\"':
910                     if (_DtCvFALSE == ignore_quotes && doubleQuotes)
911                         done = True;
912                     else if (skipString)
913                         myBufPtr++;
914                     else if (_DtHelpCeAddCharToBuf (&myBufPtr, &stringPtr,
915                                 &stringSize, &stringMax, MIN_GROW) == -1)
916                         return -1;
917                     break;
918
919               }
920           }
921       }
922
923     if (skipString)
924       {
925         if (stringPtr)
926             free (stringPtr);
927       }
928     else
929         *ret_string = stringPtr;
930
931     *in_ptr = myBufPtr;
932     return result;
933
934 } /* End _DtHelpCeGetCcdfStrParam */
935
936 /******************************************************************************
937  * Function: int _DtHelpCeGetCcdfValueParam (FILE *in_file, char *in_buf,
938  *                                      int in_size, char **in_ptr,
939  *                                      int flag, int *ret_value)
940  * 
941  * Parameters:
942  *              in_file         Specifies a stream to read from.
943  *              in_buf          Specifies the buffer where new information
944  *                                      is placed.
945  *              in_size         Specifies the maximum size of 'in_buf'.
946  *              in_ptr          Specifies the pointer into 'in_buf' to
947  *                                      start processing.
948  *                              Returns the new location in 'in_buf' to
949  *                                      continue processing.
950  *              flag            Specifies whether the routine returns
951  *                                      a -2 if '>' is the next token.
952  *              ret_value       Returns the atoi conversion
953  *                              of the string found.
954  *
955  * Returns:     0 if successful, -1 if errors, -2 if 'flag' is True and
956  *              the next token is '>'.
957  *
958  * errno Values:
959  *              read (2)        Errors set via a read call.
960  *              EINVAL
961  *              CEErrorMalloc
962  *              CEErrorIllegalInfo
963  *              CEErrorFormattingValue
964  *              CEErrorReadEmpty
965  *
966  * Purpose:     Get then next numeric parameter.
967  *
968  *****************************************************************************/
969 int
970 _DtHelpCeGetCcdfValueParam(
971         BufFilePtr in_file,
972         char      *in_buf,
973         int        in_size,
974         char     **in_ptr,
975         _DtCvValue flag,
976         int        cur_mb_len,
977         int       *ret_value )
978 {
979     int    done = False;
980     char *myBufPtr;
981     char *stringPtr = NULL;
982     int stringSize = 0;
983     int stringMax  = 0;
984     int result = 0;
985     int spnResult = 0;
986     int copySize;
987
988     if (_DtHelpCeSkipToNextCcdfToken (in_file, in_buf, in_size,
989                                         cur_mb_len, in_ptr, _DtCvTRUE) != 0)
990         return -1; 
991
992     myBufPtr = *in_ptr;
993
994     while (!done)
995       {
996         spnResult = _DtHelpCeStrcspn (myBufPtr, " >\n", cur_mb_len, &copySize);
997         if (_DtHelpCeAddStrToBuf (&myBufPtr, &stringPtr, &stringSize,
998                                         &stringMax, copySize, 0) == -1)
999             return -1;
1000
1001         /*
1002          * _DtHelpCeStrcspn stopped at a character we want
1003          */
1004         if (spnResult == 0)
1005             done = True;
1006         else if (((int)strlen(myBufPtr)) >= cur_mb_len)
1007           {
1008             errno = CEErrorIllegalInfo;
1009             return -1;
1010           }
1011         else if (_DtHelpCeGetNxtBuf(in_file,in_buf,&myBufPtr,in_size) == -1)
1012             return -1;
1013       }
1014
1015     if (stringPtr != NULL && *stringPtr != '\0')
1016       {
1017         *ret_value = atoi(stringPtr);
1018         free (stringPtr);
1019       }
1020     else
1021       {
1022         errno = CEErrorFormattingValue;
1023         result = -1;
1024       }
1025
1026     *in_ptr = myBufPtr;
1027
1028     if (result != -1 && _DtCvTRUE == flag && *myBufPtr == '>')
1029         return -2;
1030
1031     return result;
1032 }
1033
1034 /******************************************************************************
1035  * Function: int _DtHelpCeSkipToNextCcdfToken (FILE *read_file, char *read_buf,
1036  *                              int read_size, char **src_ptr, int flag)
1037  * 
1038  * Parameters:
1039  *              read_file       Specifies a stream to read from.
1040  *              read_buf        Specifies the buffer where new information
1041  *                                      is placed.
1042  *              read_size       Specifies the maximum size of 'read_buf'.
1043  *              src_ptr         Specifies the pointer into 'read_buf' to
1044  *                                      start processing.
1045  *                              Returns the new location in 'read_buf' to
1046  *                                      continue processing.
1047  *              flag            Specifies whether the routine returns
1048  *                                      a 1 if '>' is the next token.
1049  * Returns:
1050  *              -1      If problems encountered finding the next token.
1051  *               0      If no problems encountered finding the next token.
1052  *               1      If flag is true and the next token is a > character.
1053  *
1054  * errno Values:
1055  *              read (2)        Errors set via a read call.
1056  *              EINVAL
1057  *              CEErrorReadEmpty
1058  *              CEErrorIllegalInfo
1059  *
1060  * Purpose:     Move 'src_ptr' to the next occurrance of a > character
1061  *              or the first character after the next space.
1062  *
1063  *****************************************************************************/
1064 int
1065 _DtHelpCeSkipToNextCcdfToken (
1066         BufFilePtr read_file,
1067         char     *read_buf,
1068         int       read_size,
1069         int       cur_mb_len,
1070         char    **src_ptr,
1071     _DtCvValue    flag )
1072 {
1073     int       len;
1074     int       result;
1075     char     *srcPtr = *src_ptr;
1076
1077     /*
1078      * Skip the rest of the alphanumeric string.
1079      */
1080     do
1081       {
1082         /*
1083          * _DtHelpCeStrcspn returns 0 for 'found a character'
1084          */
1085         result = _DtHelpCeStrcspn (srcPtr, " >\n", cur_mb_len, &len);
1086         srcPtr = srcPtr + len;
1087
1088         if (result)
1089           {
1090             if (result == -1 && ((int)strlen(srcPtr)) >= cur_mb_len)
1091               {
1092                 errno = CEErrorIllegalInfo;
1093                 return -1;
1094               }
1095             if (_DtHelpCeGetNxtBuf(read_file, read_buf,&srcPtr,read_size) == -1)
1096                 return -1;
1097           }
1098       } while (result);
1099
1100     /*
1101      * Now skip the blanks and end of lines
1102      */
1103     do
1104       {
1105         /*
1106          * _DtHelpCeStrspn returns 0 for 'found a character'
1107          */
1108         result = _DtHelpCeStrspn (srcPtr, " \n", cur_mb_len, &len);
1109         srcPtr = srcPtr + len;
1110         if (result)
1111           {
1112             if (result == -1 && ((int)strlen(srcPtr)) >= cur_mb_len)
1113               {
1114                 errno = CEErrorIllegalInfo;
1115                 return -1;
1116               }
1117             if (_DtHelpCeGetNxtBuf(read_file,read_buf,&srcPtr,read_size) == -1)
1118                 return -1;
1119           }
1120       } while (result);
1121
1122     *src_ptr = srcPtr;
1123
1124     if (_DtCvTRUE == flag && *srcPtr == '>')
1125       {
1126         errno = CEErrorFormattingOption;
1127         return 1;
1128       }
1129
1130     return 0;
1131 }
1132 /******************************************************************************
1133  * Function: int _DtHelpCeGetCcdfTopicCmd (void *dpy, FILE *in_file, char *in_buf,
1134  *                              char **in_ptr, int in_size,
1135  *                              char **ret_charSet)
1136  *
1137  * Parameters:
1138  *              in_file         Specifies a stream to read from.
1139  *              in_buf          Specifies the buffer where new information
1140  *                                      is placed.
1141  *              in_ptr          Specifies the pointer into 'in_buf' to
1142  *                                      start processing.
1143  *                              Returns the new location in 'in_buf' to
1144  *                                      continue processing.
1145  *              in_size         Specifies the maximum size of 'in_buf'.
1146  *              ret_charSet     Returns the characters set if specified.
1147  *
1148  * Returns:     0 if successful, -1 if errors.
1149  *
1150  * errno Values:
1151  *              read (2)        Errors set via a read call.
1152  *              EINVAL
1153  *              CEErrorMalloc
1154  *              CEErrorIllegalInfo
1155  *              CEErrorReadEmpty
1156  *
1157  * 
1158  * Purpose:     Checks for the <TOPIC> command and returns the charset
1159  *              if specified.
1160  *
1161  *****************************************************************************/
1162 int
1163 _DtHelpCeGetCcdfTopicCmd (
1164     void     *dpy,
1165     BufFilePtr in_file,
1166     char     *in_buf,
1167     char    **in_ptr,
1168     int       in_size,
1169     int       cur_mb_len,
1170     char    **ret_charSet )
1171 {
1172     char    *mycharSet = NULL;
1173
1174     /*
1175      * null the return values
1176      */
1177     if (ret_charSet)
1178         *ret_charSet = NULL;
1179
1180     /*
1181      * check for <TOPIC charset string>
1182      */
1183     if (_DtHelpCeCheckNextCcdfCmd ("to",in_file,in_buf,in_size,cur_mb_len,in_ptr) == 0)
1184       {
1185         /*
1186          * The <TOPIC> command and it's attributes must be in 1-byte charset.
1187          */
1188         if (_DtHelpCeSkipToNextCcdfToken(in_file, in_buf, in_size, 1,
1189                                                 in_ptr, _DtCvFALSE) == -1)
1190             return -1;
1191
1192         /*
1193          * charset string
1194          */
1195         if (_DtCvToLower (**in_ptr) == 'c')
1196           {
1197             if (_DtHelpCeGetCcdfStrParam (in_file, in_buf, in_size,
1198                         1, in_ptr, True, False, False, False, &mycharSet) == -1)
1199                 return -1;
1200
1201             if (_DtHelpCeGetCcdfEndMark(in_file,in_buf,in_ptr,in_size,1) == -1)
1202               {
1203                 if (mycharSet)
1204                     free (mycharSet);
1205                 return -1;
1206               }
1207
1208           }
1209         else if (**in_ptr != '>')
1210           {
1211             errno = CEErrorTopicSyntax;
1212             return -1;
1213           }
1214         else
1215           {
1216             /*
1217              * skip the end token
1218              */
1219             *in_ptr = *in_ptr + 1;
1220           }
1221       }
1222     else
1223       {
1224         errno = CEErrorMissingTopicCmd;
1225         return -1;
1226       }
1227
1228     if (ret_charSet)
1229         *ret_charSet = mycharSet;
1230     else if (mycharSet)
1231         free (mycharSet);
1232
1233     return 0;
1234 }
1235
1236 /******************************************************************************
1237  * Function: int _DtHelpCeCheckNextCcdfCmd (char *token, FILE *in_file, char in_buf,
1238  *                              int in_size, char **in_ptr)
1239  * 
1240  * Parameters:
1241  *              token           Specifies the syntax to look for.
1242  *                                      <token ....> data </>
1243  *              in_file         Specifies a stream to read from.
1244  *              in_buf          Specifies the buffer where new information
1245  *                                      is placed.
1246  *              in_size         Specifies the maximum size of 'in_buf'.
1247  *              in_ptr          Specifies the pointer into 'in_buf' to
1248  *                                      start processing.
1249  *                              Returns the new location in 'in_buf' to
1250  *                                      continue processing.
1251  *
1252  * Returns:     0 if successful, -1 if errors, -2 if token not found.
1253  *
1254  * errno Values:
1255  *              read (2)        Errors set via a read call.
1256  *              EINVAL
1257  *              CEErrorIllegalInfo
1258  *              CEErrorReadEmpty
1259  *
1260  * Purpose:     Determine if the next formatting command is
1261  *                      <'token' ...>.
1262  *
1263  * Note:        'token' must be a lower case string.
1264  *
1265  *****************************************************************************/
1266 int
1267 _DtHelpCeCheckNextCcdfCmd(
1268         char      *token,
1269         BufFilePtr in_file,
1270         char      *in_buf,
1271         int        in_size,
1272         int        cur_mb_len,
1273         char     **in_ptr )
1274 {
1275     int      result = 0;
1276     int      len = strlen (token);
1277     char    *str;
1278
1279     /*
1280      * check for the token
1281      */
1282     while (len > 0 && result > -1)
1283       {
1284         if (**in_ptr == '\0' &&
1285                 _DtHelpCeGetNxtBuf(in_file, in_buf, in_ptr, in_size) == -1)
1286             return -1;
1287
1288         if (cur_mb_len == 1 || mblen (*in_ptr, cur_mb_len) == 1)
1289           {
1290             if ((isspace (**in_ptr) || **in_ptr == '\n'))
1291                 *in_ptr = *in_ptr + 1;
1292             else if (**in_ptr == '<')
1293               {
1294                 if (((int)strlen(*in_ptr)) < (len + 1) &&
1295                                 _DtHelpCeGetNxtBuf (in_file, in_buf,
1296                                             in_ptr, in_size) == -1)
1297                     return -1;
1298
1299                 for (str = *in_ptr + 1; len > 0; len--, str++, token++)
1300                   {
1301                     if (_DtCvToLower (*str) != *token)
1302                         return -2;
1303                   }
1304                 result = 0;
1305               }
1306             else
1307                 result = -2;
1308           }
1309         else
1310             result = -2;
1311       }
1312
1313     return result;
1314 }
1315
1316 /*****************************************************************************
1317  * Function: int _DtHelpCeGetCcdfTopicAbbrev (void *dpy, FILE *file, char *buffer,
1318  *                      char **buf_ptr, int buf_size, int strip,
1319  *                      char **ret_title, char **ret_charSet,
1320  *                      char **ret_abbrev)
1321  *
1322  * Parameters:
1323  *              dpy             Specifies the display connection as a void.
1324  *                              Do it this way to prevent the terminal
1325  *                              functions from having to know about Xlib.
1326  *                              Terminal/Access Functions should pass NULL
1327  *                              to this routine.
1328  *              file            Specifies the stream of the open file.
1329  *              buffer          The buffer holding the current information.
1330  *              buf_ptr         Specifies the pointer into 'buffer' to
1331  *                                      start processing.
1332  *                              Returns the new location in 'buffer' to
1333  *                                      continue processing.
1334  *              buf_size        The size of buffer.
1335  *              ret_title       Returns a null terminated string
1336  *                              containing the title if found.
1337  *              ret_charSet     Returns a null terminated string
1338  *                              containing the character set if found.
1339  *              ret_abbrev      Returns a null terminated string
1340  *                              containing the abbreviated title if found.
1341  *
1342  * Memory own by caller:
1343  *              ret_name
1344  *              ret_charSet
1345  *              ret_abbrev
1346  *
1347  * Returns:     0 if successful, -2 if <TOPIC> not found, otherwise -1.
1348  *
1349  * errno Values:
1350  *              read (2)        Errors set via a read call.
1351  *              EINVAL
1352  *              CEErrorMalloc
1353  *              CEErrorIllegalInfo
1354  *              CEErrorReadEmpty
1355  *
1356  * Purpose:     Find the title and abbreviated title of a topic.
1357  *
1358  *****************************************************************************/
1359 int
1360 _DtHelpCeGetCcdfTopicAbbrev (
1361         void             *dpy,
1362         BufFilePtr        file,
1363         char             *buffer,
1364         char            **buf_ptr,
1365         int               buf_size,
1366         int               cur_mb_len,
1367         char            **ret_title,
1368         char            **ret_charSet,
1369         char            **ret_abbrev )
1370 {
1371     /*
1372      * NULL the entries.
1373      */
1374     if (ret_title)
1375         *ret_title   = NULL;
1376     if (ret_abbrev)
1377         *ret_abbrev  = NULL;
1378
1379     /*
1380      * check for <TOPIC charset string>
1381      */
1382     if (_DtHelpCeGetCcdfTopicCmd (dpy,
1383                           file,
1384                           buffer,
1385                           buf_ptr,
1386                           buf_size,
1387                           cur_mb_len,
1388                           ret_charSet) == -1
1389                         ||
1390         /* Must have a <TITLE> token*/
1391         GetTitleCmd(file, buffer, buf_size, cur_mb_len,buf_ptr,ret_title) == -1
1392                         ||
1393         /* check for the <ABBREV> token */
1394         _DtHelpCeGetCcdfAbbrevCmd (file, buffer, buf_size, cur_mb_len,buf_ptr, ret_abbrev) == -1)
1395
1396         return -1;
1397
1398     return 0;
1399 }
1400
1401 /*****************************************************************************
1402  * Function: int _DtHelpCeSkipCcdfAbbrev (FILE *file, char *buffer, int buf_size,
1403  *                                                      char **buf_ptr)
1404  *
1405  * Parameters:
1406  *              file            Specifies the stream of the open file.
1407  *              buffer          The buffer holding the current information.
1408  *              buf_size        The size of buffer.
1409  *              buf_ptr         Specifies the pointer into 'buffer' to
1410  *                                      start processing.
1411  *                              Returns the new location in 'buffer' to
1412  *                                      continue processing.
1413  *
1414  * Returns:     0 if successful, otherwise -1.
1415  *
1416  * errno Values:
1417  *              read (2)        Errors set via a read call.
1418  *              EINVAL
1419  *              CEErrorMalloc
1420  *              CEErrorIllegalInfo
1421  *              CEErrorReadEmpty
1422  *
1423  * Purpose:     Skip the <ABBREV> command
1424  *
1425  *****************************************************************************/
1426 int
1427 _DtHelpCeSkipCcdfAbbrev (
1428         BufFilePtr        file,
1429         char             *buffer,
1430         char            **buf_ptr,
1431         int               buf_size,
1432         int               cur_mb_len)
1433 {
1434     /*
1435      * check for the <ABBREV> token and skip its data.
1436      */
1437     return _DtHelpCeGetCcdfAbbrevCmd(file, buffer, buf_size, cur_mb_len,buf_ptr, NULL);
1438 }
1439
1440 /******************************************************************************
1441  * Function: int _DtHelpCeGetCcdfAbbrevCmd (FILE *in_file, char *in_buf, int in_size,
1442  *                              char **in_ptr, char **ret_string)
1443  * 
1444  * Parameters:
1445  *              in_file         Specifies a stream to read from.
1446  *              in_buf          Specifies the buffer where new information
1447  *                                      is placed.
1448  *              in_size         Specifies the maximum size of 'in_buf'.
1449  *              in_ptr          Specifies the pointer into 'in_buf' to
1450  *                                      start processing.
1451  *                              Returns the new location in 'in_buf' to
1452  *                                      continue processing.
1453  *              ret_string      Returns the data found.
1454  *
1455  * Returns:     0 if successful, -1 if errors
1456  *
1457  * errno Values:
1458  *              read (2)        Errors set via a read call.
1459  *              EINVAL
1460  *              CEErrorIllegalInfo
1461  *              CEErrorReadEmpty
1462  *
1463  * Purpose:     Determine if the next formatting command is
1464  *                      <ABBREV ...>.
1465  *              Returns the data found between <ABBREV> and its ending </>.
1466  *
1467  * Note:        The only formatting command allowed between <ABBREV> and
1468  *              its </> is the <NEWLINE> command. And it is stripped.
1469  *
1470  *****************************************************************************/
1471 int
1472 _DtHelpCeGetCcdfAbbrevCmd(
1473         BufFilePtr in_file,
1474         char      *in_buf,
1475         int        in_size,
1476         int        cur_mb_len,
1477         char     **in_ptr,
1478         char     **ret_string )
1479 {
1480     int       result;
1481     int       junkSize  = 0;
1482     int       junkMax  = 0;
1483
1484     /*
1485      * null the return string
1486      */
1487     if (ret_string)
1488         *ret_string = NULL;
1489
1490     /*
1491      * check for the token
1492      */
1493     result = _DtHelpCeCheckNextCcdfCmd ("ab", in_file, in_buf, in_size, cur_mb_len, in_ptr);
1494     if (result == -2)
1495         result = 0;
1496     else if (result == 0 &&
1497         _DtHelpCeGetCcdfEndMark(in_file,in_buf,in_ptr,in_size,cur_mb_len) != -1)
1498       {
1499         result = GetCmdData (in_file, in_buf, in_size, in_ptr, cur_mb_len,
1500                                         CCDF_NEWLINE_CMD, CCDF_NEWLINE_CMD,
1501                                         &junkSize, &junkMax, ret_string);
1502         if (result == -1 && errno == CMD_NOT_ALLOWED)
1503             errno = CEErrorAbbrevSyntax;
1504       }
1505     else
1506         result = -1;
1507
1508     return result;
1509 }
1510
1511 /******************************************************************************
1512  * Function:    int _DtHelpCeGetCcdfCmd (int current, char *buffer,
1513  *                                        char **buf_ptr, FILE *my_file,
1514  *                                        int size, int allowed, int flag )
1515  *
1516  * Parameters:  current         Specifies the current formatting command.
1517  *              buffer          Specifies the buffer to use for input.
1518  *              buf_ptr         Specifies the current position into 'buffer'.
1519  *              my_file         Specifies the file stream to read from.
1520  *              size            Specifies the maximum size of the input buffer.
1521  *              allowed         Specifies the commands allowed at this time.
1522  *              flag            Specifies the flag to use for
1523  *                                      _DtHelpCeGetNxtBuf. No longer used.
1524  *
1525  * Returns
1526  *              -1      If errors reading the file or the command is not
1527  *                      allowed
1528  *              > 0     The formmatting command.
1529  *
1530  * errno Values:
1531  *
1532  * Purpose:     Determine if the string pointed to by 'ptr' is a formatting
1533  *              command.
1534  *
1535  *****************************************************************************/
1536 int
1537 _DtHelpCeGetCcdfCmd (
1538     int     current,
1539     char   *buffer,
1540     char  **buf_ptr,
1541     BufFilePtr my_file,
1542     int     size,
1543     int     allowed)
1544 {
1545     int   i = -1;
1546     int   j = 1;
1547     int   different;
1548     int   my_error = 0;
1549     char  firstChar;
1550     char *myPtr;
1551
1552     /*
1553      * always allow the end of formatting command
1554      */
1555     allowed = allowed | CCDF_FORMAT_END;
1556
1557     /*
1558      * set the pointer to the current position in the input buffer
1559      */
1560     myPtr = *buf_ptr;
1561     if (*myPtr == '\0' &&
1562                 _DtHelpCeGetNxtBuf(my_file, buffer, &myPtr, size) == -1)
1563         return -1;
1564
1565     firstChar = _DtCvToLower (*myPtr);
1566     do {
1567         i++;
1568         different = firstChar - CcdfFormatCmds[i].cmd[0];
1569
1570         if (!different && CcdfFormatCmds[i].significant > 1)
1571           {
1572             if (((int)strlen(myPtr)) < CcdfFormatCmds[i].significant &&
1573                 _DtHelpCeGetNxtBuf (my_file, buffer, &myPtr, size) == -1)
1574                 return -1;
1575
1576             j = 1;
1577             do {
1578                 different = _DtCvToLower(myPtr[j]) - CcdfFormatCmds[i].cmd[j];
1579                 j++;
1580               } while (!different && j < CcdfFormatCmds[i].significant);
1581           }
1582
1583       } while (different && CcdfFormatCmds[i].type != CCDF_FORMAT_END);
1584
1585     /*
1586      * update the passed in pointer
1587      */
1588     *buf_ptr = myPtr;
1589
1590     /*
1591      * check to see if the formatting command is valid
1592      */
1593     if (different)
1594         errno = CEErrorFormattingCmd;
1595
1596     else if (!different && CCDF_NOT_ALLOW_CMD (allowed, CcdfFormatCmds[i].type))
1597       {
1598         my_error = -1;
1599         switch (current)
1600           {
1601             case CCDF_ABBREV_CMD:
1602                         errno = CEErrorAbbrevSyntax;
1603                         break;
1604             case CCDF_FIGURE_CMD:
1605                         errno = CEErrorFigureSyntax;
1606                         break;
1607             case CCDF_FONT_CMD:
1608                         errno = CEErrorFontSyntax;
1609                         break;
1610             case CCDF_GRAPHIC_CMD:
1611                         errno = CEErrorGraphicSyntax;
1612                         break;
1613             case CCDF_ID_CMD:
1614                         errno = CEErrorIdSyntax;
1615                         break;
1616             case CCDF_LABEL_CMD:
1617                         errno = CEErrorLabelSyntax;
1618                         break;
1619             case CCDF_LINK_CMD:
1620                         errno = CEErrorLinkSyntax;
1621                         break;
1622             case CCDF_NEWLINE_CMD:
1623                         errno = CEErrorNewLineSyntax;
1624                         break;
1625             case CCDF_OCTAL_CMD:
1626                         errno = CEErrorOctalSyntax;
1627                         break;
1628             case CCDF_PARAGRAPH_CMD:
1629                         errno = CEErrorParagraphSyntax;
1630                         break;
1631             case CCDF_TITLE_CMD:
1632                         errno = CEErrorTitleSyntax;
1633                         break;
1634             case CCDF_TOPIC_CMD:
1635                         errno = CEErrorTopicSyntax;
1636                         break;
1637           }
1638       }
1639     if (different || my_error)
1640         return -1;
1641
1642     return CcdfFormatCmds[i].type;
1643 }
1644
1645 /******************************************************************************
1646  * Function:    int _DtHelpCeGetCcdfFontType (char *code)
1647  *
1648  * Parameters:  code    Specifies the character set to initialize
1649  *                      data and flags. The caller must ensure that
1650  *                      there is enough of the code string available
1651  *                      to make the determination.
1652  *
1653  * Return Value: int    Returns the font resource to change.
1654  *                      -1 if unknown font change type.
1655  *
1656  * Purpose:     Determines if the code is a font change specification.
1657  *
1658  *****************************************************************************/
1659 int
1660 _DtHelpCeGetCcdfFontType (char      *code)
1661 {
1662     char  my2Char;
1663     char  myChar = _DtCvToLower (*code);
1664
1665     code++;
1666     my2Char = _DtCvToLower (*code);
1667     switch (myChar)
1668       {
1669         /*
1670          * <angle string>
1671          */
1672         case 'a':
1673                 if (my2Char == 'n')
1674                     return _CEFONT_ANGLE;
1675                 break;
1676         /*
1677          * <charset string>
1678          */
1679         case 'c': return _CEFONT_CHAR_SET;
1680
1681         /*
1682          * <type string>
1683          */
1684         case 't':
1685                 if (my2Char == 'y')
1686                     return _CEFONT_TYPE;
1687                 break;
1688
1689         /*
1690          * <weight string>
1691          */
1692         case 'w': return _CEFONT_WEIGHT;
1693
1694         /*
1695          * <size string>
1696          * <spacing string>
1697          */
1698         case 's':
1699             if (my2Char == 'i')
1700                 return _CEFONT_SIZE;
1701
1702             if (my2Char == 'p')
1703                 return _CEFONT_SPACING;
1704       }
1705     return -1;
1706 }