1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
/*
* Motif Tools Library, Version 3.1
* $Id$
*
* Written by David Flanagan.
* Copyright (c) 1992-2001 by David Flanagan.
* All Rights Reserved. See the file COPYRIGHT for details.
* This is open source software. See the file LICENSE for details.
* There is no warranty for this software. See NO_WARRANTY for details.
*
* $Log$
* Revision 1.1.1.1 2001/07/18 11:06:01 root
* Initial checkin.
*
* Revision 1.1 2001/06/12 15:00:21 andre
* AA-2001-06-12-0: replaced Xmt212 by Xmt310
* (http://sourceforge.net/projects/motiftools) with
* our xmt212 patches applied
*
*
*/
#include <Xmt/Xmt.h>
#include <string.h>
#include <ctype.h>
#ifndef X_NOT_STDC_ENV
#include <stdlib.h>
#else
extern long int strtol();
#endif
#if NeedFunctionPrototypes
static int gettype(char *s, char *type, int *pos, char **newstr)
#else
static int gettype(s, type, pos, newstr)
char *s;
char *type;
int *pos;
char **newstr;
#endif
{
int longer = False;
/* look for a format specifiction, but not a %% */
while(*s) {
if (*s == '%') {
s++;
if (*s && (*s != '%')) break;
}
s++;
}
if (!*s) return 0; /* end of string */
/*
* here, s[-1] is the '%' char.
* s[0] is known not to be '%'.
*/
/* first check for a positional argument */
if (isdigit(*s) && (*(s + strspn(s, "0123456789")) == '$')) {
*pos = strtol(s, &s, 0);
*pos -= 1; /* convered 1-based to 0-based */
s++; /* skip the '$' */
}
else
*pos = -1;
/* now skip any flags */
s += strspn(s, "-+ #");
/*
* skip any field width and precision.
* note that we don't handle the '*' or '*ddd$' syntax
* here for widths and precisions from the arg list.
* tough luck. These probably aren't portable, anyway.
*/
s += strspn(s, "0123456789.");
/*
* now there are three possible size characters: 'h', 'l', and 'L'.
* we can ignore h; it just controls how printing is done; it doesn't
* specify anything about the required argument type. The other 2 do.
*/
if (*s == 'h') s++;
else if ((*s == 'l') || (*s == 'L')) { s++; longer = True; }
/*
* Now check for the type character. All we care about is the
* type of the expected argument, not the actual format, and
* args are widened, so we don't care about short or float.
* We map all the format characters to 8 types:
* d integer
* D long
* f double
* F long double
* c char
* s string
* p pointer
* n address of int
*/
switch(*s) {
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
if (longer) *type = 'D'; else *type = 'd';
break;
case 'f':
case 'g':
case 'e':
case 'G':
case 'E':
if (longer) *type = 'F'; else *type = 'f';
break;
case 'c':
*type = 'c';
break;
case 's':
*type = 's';
break;
case 'p':
*type = 'p';
break;
case 'n':
*type = 'n';
break;
default:
*type = '\0'; /* bad format */
}
if (*s) s++;
*newstr = s;
return 1;
}
#if NeedFunctionPrototypes
Boolean XmtCheckPrintfFormat(StringConst template, StringConst msg)
#else
Boolean XmtCheckPrintfFormat(template, msg)
String template;
String msg;
#endif
{
char types[100]; /* no conversion will have > 100 args */
char type;
int pos;
char *s;
int nextpos;
memset(types, 0, sizeof(types));
/* figure out what args are expected by the template string */
s = (char *) template;
nextpos = 0;
while(gettype(s, &type, &pos, &s)) {
if (!type) return False; /* error; bad format */
if (pos >= 0) types[pos] = type;
else types[nextpos++] = type;
}
/* now see if the other string matches these */
s = (char *)msg;
nextpos = 0;
while(gettype(s, &type, &pos, &s)) {
if (!type) return False; /* error; bad format */
if (pos == -1) pos = nextpos++;
if (type != types[pos]) return False; /* error; bad type */
}
return True;
}
|