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