File: CheckFormat.c

package info (click to toggle)
gridengine 6.2-4
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 51,532 kB
  • ctags: 51,172
  • sloc: ansic: 418,155; java: 37,080; sh: 22,593; jsp: 7,699; makefile: 5,292; csh: 4,244; xml: 2,901; cpp: 2,086; perl: 1,895; tcl: 1,188; lisp: 669; ruby: 642; yacc: 393; lex: 266
file content (175 lines) | stat: -rw-r--r-- 4,044 bytes parent folder | download | duplicates (3)
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;
}