]> git.ipfire.org Git - thirdparty/libbsd.git/commitdiff
fmtcheck: New function
authorAurelien Jarno <aurel32@debian.org>
Sun, 18 Dec 2005 04:02:56 +0000 (04:02 +0000)
committerGuillem Jover <guillem@hadrons.org>
Tue, 6 May 2008 05:45:48 +0000 (08:45 +0300)
ChangeLog
Makefile
Versions
fmtcheck.c [new file with mode: 0644]
include/bsd/string.h

index f6b41bb52912bdfaff7367af4b9f107d9c531878..31c4bbc99fa0aad145fd6c91ba02dbcb9b60167a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2005-12-18  Aurelien Jarno <aurel32@debian.org>
+       
+       * fmtcheck.c: new
+       * include/string.h: added fmtcheck
+       * Versions: added fmtcheck
+
 2005-11-01  Guillem Jover  <guillem@debian.org>
 
        * ip_icmp.h: Move to ...
index f0e2c065eb6336ab9a0e2073f91ef100f93ede14..2d6d425a10625024a4b529f02672fca1950fe37c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
 # $Id$
 #
 
-LIB_SRCS = arc4random.c fgetln.c inet_net_pton.c strlcat.c strlcpy.c md5c.c
+LIB_SRCS = arc4random.c fgetln.c inet_net_pton.c strlcat.c strlcpy.c md5c.c fmtcheck.c
 
 LIB_INCLUDES = bsd.h md5.h
 
index d82b7114c412d433feeee786909438822941839b..8bda61c9524a43271a1b45c6e12a5158a1c6b82b 100644 (file)
--- a/Versions
+++ b/Versions
@@ -2,6 +2,7 @@ LIBBSD_0.0 {
   global:
     arc4random;
     fgetln;
+    fmtcheck;
     inet_net_pton;
     strlcpy;
     strlcat;
diff --git a/fmtcheck.c b/fmtcheck.c
new file mode 100644 (file)
index 0000000..5d54b7c
--- /dev/null
@@ -0,0 +1,267 @@
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Allen Briggs.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*     $NetBSD: fmtcheck.c,v 1.2 2000/11/01 01:17:20 briggs Exp $      */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/fmtcheck.c,v 1.8 2005/03/21 08:00:55 das Exp $");
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+__weak_reference(__fmtcheck, fmtcheck);
+
+enum __e_fmtcheck_types {
+       FMTCHECK_START,
+       FMTCHECK_SHORT,
+       FMTCHECK_INT,
+       FMTCHECK_LONG,
+       FMTCHECK_QUAD,
+       FMTCHECK_PTRDIFFT,
+       FMTCHECK_SIZET,
+       FMTCHECK_SHORTPOINTER,
+       FMTCHECK_INTPOINTER,
+       FMTCHECK_LONGPOINTER,
+       FMTCHECK_QUADPOINTER,
+       FMTCHECK_PTRDIFFTPOINTER,
+       FMTCHECK_SIZETPOINTER,
+#ifndef NO_FLOATING_POINT
+       FMTCHECK_DOUBLE,
+       FMTCHECK_LONGDOUBLE,
+#endif
+       FMTCHECK_STRING,
+       FMTCHECK_WIDTH,
+       FMTCHECK_PRECISION,
+       FMTCHECK_DONE,
+       FMTCHECK_UNKNOWN
+};
+typedef enum __e_fmtcheck_types EFT;
+
+#define RETURN(pf,f,r) do { \
+                       *(pf) = (f); \
+                       return r; \
+                      } /*NOTREACHED*/ /*CONSTCOND*/ while (0)
+
+static EFT
+get_next_format_from_precision(const char **pf)
+{
+       int             sh, lg, quad, longdouble, ptrdifft, sizet;
+       const char      *f;
+
+       sh = lg = quad = longdouble = ptrdifft = sizet = 0;
+
+       f = *pf;
+       switch (*f) {
+       case 'h':
+               f++;
+               sh = 1;
+               break;
+       case 'l':
+               f++;
+               if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
+               if (*f == 'l') {
+                       f++;
+                       quad = 1;
+               } else {
+                       lg = 1;
+               }
+               break;
+       case 'q':
+               f++;
+               quad = 1;
+               break;
+       case 't':
+               f++;
+               ptrdifft = 1;
+               break;
+       case 'z':
+               f++;
+               sizet = 1;
+               break;
+       case 'L':
+               f++;
+               longdouble = 1;
+               break;
+       default:
+               break;
+       }
+       if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
+       if (strchr("diouxX", *f)) {
+               if (longdouble)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               if (lg)
+                       RETURN(pf,f,FMTCHECK_LONG);
+               if (quad)
+                       RETURN(pf,f,FMTCHECK_QUAD);
+               if (ptrdifft)
+                       RETURN(pf,f,FMTCHECK_PTRDIFFT);
+               if (sizet)
+                       RETURN(pf,f,FMTCHECK_SIZET);
+               RETURN(pf,f,FMTCHECK_INT);
+       }
+       if (*f == 'n') {
+               if (longdouble)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               if (sh)
+                       RETURN(pf,f,FMTCHECK_SHORTPOINTER);
+               if (lg)
+                       RETURN(pf,f,FMTCHECK_LONGPOINTER);
+               if (quad)
+                       RETURN(pf,f,FMTCHECK_QUADPOINTER);
+               if (ptrdifft)
+                       RETURN(pf,f,FMTCHECK_PTRDIFFTPOINTER);
+               if (sizet)
+                       RETURN(pf,f,FMTCHECK_SIZETPOINTER);
+               RETURN(pf,f,FMTCHECK_INTPOINTER);
+       }
+       if (strchr("DOU", *f)) {
+               if (sh + lg + quad + longdouble + ptrdifft + sizet)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               RETURN(pf,f,FMTCHECK_LONG);
+       }
+#ifndef NO_FLOATING_POINT
+       if (strchr("aAeEfFgG", *f)) {
+               if (longdouble)
+                       RETURN(pf,f,FMTCHECK_LONGDOUBLE);
+               if (sh + lg + quad + ptrdifft + sizet)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               RETURN(pf,f,FMTCHECK_DOUBLE);
+       }
+#endif
+       if (*f == 'c') {
+               if (sh + lg + quad + longdouble + ptrdifft + sizet)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               RETURN(pf,f,FMTCHECK_INT);
+       }
+       if (*f == 's') {
+               if (sh + lg + quad + longdouble + ptrdifft + sizet)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               RETURN(pf,f,FMTCHECK_STRING);
+       }
+       if (*f == 'p') {
+               if (sh + lg + quad + longdouble + ptrdifft + sizet)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               RETURN(pf,f,FMTCHECK_LONG);
+       }
+       RETURN(pf,f,FMTCHECK_UNKNOWN);
+       /*NOTREACHED*/
+}
+
+static EFT
+get_next_format_from_width(const char **pf)
+{
+       const char      *f;
+
+       f = *pf;
+       if (*f == '.') {
+               f++;
+               if (*f == '*') {
+                       RETURN(pf,f,FMTCHECK_PRECISION);
+               }
+               /* eat any precision (empty is allowed) */
+               while (isdigit(*f)) f++;
+               if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
+       }
+       RETURN(pf,f,get_next_format_from_precision(pf));
+       /*NOTREACHED*/
+}
+
+static EFT
+get_next_format(const char **pf, EFT eft)
+{
+       int             infmt;
+       const char      *f;
+
+       if (eft == FMTCHECK_WIDTH) {
+               (*pf)++;
+               return get_next_format_from_width(pf);
+       } else if (eft == FMTCHECK_PRECISION) {
+               (*pf)++;
+               return get_next_format_from_precision(pf);
+       }
+
+       f = *pf;
+       infmt = 0;
+       while (!infmt) {
+               f = strchr(f, '%');
+               if (f == NULL)
+                       RETURN(pf,f,FMTCHECK_DONE);
+               f++;
+               if (!*f)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               if (*f != '%')
+                       infmt = 1;
+               else
+                       f++;
+       }
+
+       /* Eat any of the flags */
+       while (*f && (strchr("#'0- +", *f)))
+               f++;
+
+       if (*f == '*') {
+               RETURN(pf,f,FMTCHECK_WIDTH);
+       }
+       /* eat any width */
+       while (isdigit(*f)) f++;
+       if (!*f) {
+               RETURN(pf,f,FMTCHECK_UNKNOWN);
+       }
+
+       RETURN(pf,f,get_next_format_from_width(pf));
+       /*NOTREACHED*/
+}
+
+__const char *
+__fmtcheck(const char *f1, const char *f2)
+{
+       const char      *f1p, *f2p;
+       EFT             f1t, f2t;
+
+       if (!f1) return f2;
+       
+       f1p = f1;
+       f1t = FMTCHECK_START;
+       f2p = f2;
+       f2t = FMTCHECK_START;
+       while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) {
+               if (f1t == FMTCHECK_UNKNOWN)
+                       return f2;
+               f2t = get_next_format(&f2p, f2t);
+               if (f1t != f2t)
+                       return f2;
+       }
+       return f1;
+}
index ed319339e8203d6276cb63a36351bbaf07b34261..70a9b38cf27460f5e54a9764d853aad2e8ee7b4c 100644 (file)
@@ -7,5 +7,6 @@
 size_t strlcpy(char *dst, const char *src, size_t siz);
 size_t strlcat(char *dst, const char *src, size_t siz);
 char *fgetln(FILE *fp, size_t *lenp);
+const char *fmtcheck(const char *, const char *);
 
 #endif