"Fossies" - the Fresh Open Source Software Archive

Member "file-5.35/src/fmtcheck.c" (11 Sep 2018, 5528 Bytes) of package /linux/misc/file-5.35.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "fmtcheck.c" see the Fossies "Dox" file reference documentation.

    1 /*  $NetBSD: fmtcheck.c,v 1.8 2008/04/28 20:22:59 martin Exp $  */
    2 
    3 /*-
    4  * Copyright (c) 2000 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code was contributed to The NetBSD Foundation by Allen Briggs.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   20  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   21  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   28  * POSSIBILITY OF SUCH DAMAGE.
   29  */
   30 
   31 #include "file.h"
   32 
   33 #include <stdio.h>
   34 #include <string.h>
   35 #include <ctype.h>
   36 
   37 enum __e_fmtcheck_types {
   38     FMTCHECK_START,
   39     FMTCHECK_SHORT,
   40     FMTCHECK_INT,
   41     FMTCHECK_LONG,
   42     FMTCHECK_QUAD,
   43     FMTCHECK_SHORTPOINTER,
   44     FMTCHECK_INTPOINTER,
   45     FMTCHECK_LONGPOINTER,
   46     FMTCHECK_QUADPOINTER,
   47     FMTCHECK_DOUBLE,
   48     FMTCHECK_LONGDOUBLE,
   49     FMTCHECK_STRING,
   50     FMTCHECK_WIDTH,
   51     FMTCHECK_PRECISION,
   52     FMTCHECK_DONE,
   53     FMTCHECK_UNKNOWN
   54 };
   55 typedef enum __e_fmtcheck_types EFT;
   56 
   57 #define RETURN(pf,f,r) do { \
   58             *(pf) = (f); \
   59             return r; \
   60                } /*NOTREACHED*/ /*CONSTCOND*/ while (0)
   61 
   62 static EFT
   63 get_next_format_from_precision(const char **pf)
   64 {
   65     int     sh, lg, quad, longdouble;
   66     const char  *f;
   67 
   68     sh = lg = quad = longdouble = 0;
   69 
   70     f = *pf;
   71     switch (*f) {
   72     case 'h':
   73         f++;
   74         sh = 1;
   75         break;
   76     case 'l':
   77         f++;
   78         if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
   79         if (*f == 'l') {
   80             f++;
   81             quad = 1;
   82         } else {
   83             lg = 1;
   84         }
   85         break;
   86     case 'q':
   87         f++;
   88         quad = 1;
   89         break;
   90     case 'L':
   91         f++;
   92         longdouble = 1;
   93         break;
   94 #ifdef WIN32
   95     case 'I':
   96         f++;
   97         if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
   98         if (*f == '3' && f[1] == '2') {
   99             f += 2;
  100         } else if (*f == '6' && f[1] == '4') {
  101             f += 2;
  102             quad = 1;
  103         }
  104 #ifdef _WIN64
  105         else {
  106             quad = 1;
  107         }
  108 #endif
  109         break;
  110 #endif
  111     default:
  112         break;
  113     }
  114     if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
  115     if (strchr("diouxX", *f)) {
  116         if (longdouble)
  117             RETURN(pf,f,FMTCHECK_UNKNOWN);
  118         if (lg)
  119             RETURN(pf,f,FMTCHECK_LONG);
  120         if (quad)
  121             RETURN(pf,f,FMTCHECK_QUAD);
  122         RETURN(pf,f,FMTCHECK_INT);
  123     }
  124     if (*f == 'n') {
  125         if (longdouble)
  126             RETURN(pf,f,FMTCHECK_UNKNOWN);
  127         if (sh)
  128             RETURN(pf,f,FMTCHECK_SHORTPOINTER);
  129         if (lg)
  130             RETURN(pf,f,FMTCHECK_LONGPOINTER);
  131         if (quad)
  132             RETURN(pf,f,FMTCHECK_QUADPOINTER);
  133         RETURN(pf,f,FMTCHECK_INTPOINTER);
  134     }
  135     if (strchr("DOU", *f)) {
  136         if (sh + lg + quad + longdouble)
  137             RETURN(pf,f,FMTCHECK_UNKNOWN);
  138         RETURN(pf,f,FMTCHECK_LONG);
  139     }
  140     if (strchr("eEfg", *f)) {
  141         if (longdouble)
  142             RETURN(pf,f,FMTCHECK_LONGDOUBLE);
  143         if (sh + lg + quad)
  144             RETURN(pf,f,FMTCHECK_UNKNOWN);
  145         RETURN(pf,f,FMTCHECK_DOUBLE);
  146     }
  147     if (*f == 'c') {
  148         if (sh + lg + quad + longdouble)
  149             RETURN(pf,f,FMTCHECK_UNKNOWN);
  150         RETURN(pf,f,FMTCHECK_INT);
  151     }
  152     if (*f == 's') {
  153         if (sh + lg + quad + longdouble)
  154             RETURN(pf,f,FMTCHECK_UNKNOWN);
  155         RETURN(pf,f,FMTCHECK_STRING);
  156     }
  157     if (*f == 'p') {
  158         if (sh + lg + quad + longdouble)
  159             RETURN(pf,f,FMTCHECK_UNKNOWN);
  160         RETURN(pf,f,FMTCHECK_LONG);
  161     }
  162     RETURN(pf,f,FMTCHECK_UNKNOWN);
  163     /*NOTREACHED*/
  164 }
  165 
  166 static EFT
  167 get_next_format_from_width(const char **pf)
  168 {
  169     const char  *f;
  170 
  171     f = *pf;
  172     if (*f == '.') {
  173         f++;
  174         if (*f == '*') {
  175             RETURN(pf,f,FMTCHECK_PRECISION);
  176         }
  177         /* eat any precision (empty is allowed) */
  178         while (isdigit((unsigned char)*f)) f++;
  179         if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
  180     }
  181     RETURN(pf,f,get_next_format_from_precision(pf));
  182     /*NOTREACHED*/
  183 }
  184 
  185 static EFT
  186 get_next_format(const char **pf, EFT eft)
  187 {
  188     int     infmt;
  189     const char  *f;
  190 
  191     if (eft == FMTCHECK_WIDTH) {
  192         (*pf)++;
  193         return get_next_format_from_width(pf);
  194     } else if (eft == FMTCHECK_PRECISION) {
  195         (*pf)++;
  196         return get_next_format_from_precision(pf);
  197     }
  198 
  199     f = *pf;
  200     infmt = 0;
  201     while (!infmt) {
  202         f = strchr(f, '%');
  203         if (f == NULL)
  204             RETURN(pf,f,FMTCHECK_DONE);
  205         f++;
  206         if (!*f)
  207             RETURN(pf,f,FMTCHECK_UNKNOWN);
  208         if (*f != '%')
  209             infmt = 1;
  210         else
  211             f++;
  212     }
  213 
  214     /* Eat any of the flags */
  215     while (*f && (strchr("#0- +", *f)))
  216         f++;
  217 
  218     if (*f == '*') {
  219         RETURN(pf,f,FMTCHECK_WIDTH);
  220     }
  221     /* eat any width */
  222     while (isdigit((unsigned char)*f)) f++;
  223     if (!*f) {
  224         RETURN(pf,f,FMTCHECK_UNKNOWN);
  225     }
  226 
  227     RETURN(pf,f,get_next_format_from_width(pf));
  228     /*NOTREACHED*/
  229 }
  230 
  231 const char *
  232 fmtcheck(const char *f1, const char *f2)
  233 {
  234     const char  *f1p, *f2p;
  235     EFT     f1t, f2t;
  236 
  237     if (!f1) return f2;
  238 
  239     f1p = f1;
  240     f1t = FMTCHECK_START;
  241     f2p = f2;
  242     f2t = FMTCHECK_START;
  243     while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) {
  244         if (f1t == FMTCHECK_UNKNOWN)
  245             return f2;
  246         f2t = get_next_format(&f2p, f2t);
  247         if (f1t != f2t)
  248             return f2;
  249     }
  250     return f1;
  251 }