annotate src/fftw-3.3.5/kernel/scan.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 2cd0e3b3e1fd
children
rev   line source
Chris@42 1 /*
Chris@42 2 * Copyright (c) 2003, 2007-14 Matteo Frigo
Chris@42 3 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
Chris@42 4 *
Chris@42 5 * This program is free software; you can redistribute it and/or modify
Chris@42 6 * it under the terms of the GNU General Public License as published by
Chris@42 7 * the Free Software Foundation; either version 2 of the License, or
Chris@42 8 * (at your option) any later version.
Chris@42 9 *
Chris@42 10 * This program is distributed in the hope that it will be useful,
Chris@42 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@42 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@42 13 * GNU General Public License for more details.
Chris@42 14 *
Chris@42 15 * You should have received a copy of the GNU General Public License
Chris@42 16 * along with this program; if not, write to the Free Software
Chris@42 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@42 18 *
Chris@42 19 */
Chris@42 20
Chris@42 21
Chris@42 22 #include "ifftw.h"
Chris@42 23 #include <string.h>
Chris@42 24 #include <stddef.h>
Chris@42 25 #include <stdarg.h>
Chris@42 26 #include <stdio.h>
Chris@42 27
Chris@42 28 #ifdef USE_CTYPE
Chris@42 29 #include <ctype.h>
Chris@42 30 #else
Chris@42 31 /* Screw ctype. On linux, the is* functions call a routine that gets
Chris@42 32 the ctype map in the current locale. Because this operation is
Chris@42 33 expensive, the map is cached on a per-thread basis. I am not
Chris@42 34 willing to link this crap with FFTW. Not over my dead body.
Chris@42 35
Chris@42 36 Sic transit gloria mundi.
Chris@42 37 */
Chris@42 38 #undef isspace
Chris@42 39 #define isspace(x) ((x) >= 0 && (x) <= ' ')
Chris@42 40 #undef isdigit
Chris@42 41 #define isdigit(x) ((x) >= '0' && (x) <= '9')
Chris@42 42 #undef isupper
Chris@42 43 #define isupper(x) ((x) >= 'A' && (x) <= 'Z')
Chris@42 44 #undef islower
Chris@42 45 #define islower(x) ((x) >= 'a' && (x) <= 'z')
Chris@42 46 #endif
Chris@42 47
Chris@42 48 static int mygetc(scanner *sc)
Chris@42 49 {
Chris@42 50 if (sc->ungotc != EOF) {
Chris@42 51 int c = sc->ungotc;
Chris@42 52 sc->ungotc = EOF;
Chris@42 53 return c;
Chris@42 54 }
Chris@42 55 return(sc->getchr(sc));
Chris@42 56 }
Chris@42 57
Chris@42 58 #define GETCHR(sc) mygetc(sc)
Chris@42 59
Chris@42 60 static void myungetc(scanner *sc, int c)
Chris@42 61 {
Chris@42 62 sc->ungotc = c;
Chris@42 63 }
Chris@42 64
Chris@42 65 #define UNGETCHR(sc, c) myungetc(sc, c)
Chris@42 66
Chris@42 67 static void eat_blanks(scanner *sc)
Chris@42 68 {
Chris@42 69 int ch;
Chris@42 70 while (ch = GETCHR(sc), isspace(ch))
Chris@42 71 ;
Chris@42 72 UNGETCHR(sc, ch);
Chris@42 73 }
Chris@42 74
Chris@42 75 static void mygets(scanner *sc, char *s, int maxlen)
Chris@42 76 {
Chris@42 77 char *s0 = s;
Chris@42 78 int ch;
Chris@42 79
Chris@42 80 A(maxlen > 0);
Chris@42 81 while ((ch = GETCHR(sc)) != EOF && !isspace(ch)
Chris@42 82 && ch != ')' && ch != '(' && s < s0 + maxlen)
Chris@42 83 *s++ = (char)(ch & 0xFF);
Chris@42 84 *s = 0;
Chris@42 85 UNGETCHR(sc, ch);
Chris@42 86 }
Chris@42 87
Chris@42 88 static long getlong(scanner *sc, int base, int *ret)
Chris@42 89 {
Chris@42 90 int sign = 1, ch, count;
Chris@42 91 long x = 0;
Chris@42 92
Chris@42 93 ch = GETCHR(sc);
Chris@42 94 if (ch == '-' || ch == '+') {
Chris@42 95 sign = ch == '-' ? -1 : 1;
Chris@42 96 ch = GETCHR(sc);
Chris@42 97 }
Chris@42 98 for (count = 0; ; ++count) {
Chris@42 99 if (isdigit(ch))
Chris@42 100 ch -= '0';
Chris@42 101 else if (isupper(ch))
Chris@42 102 ch -= 'A' - 10;
Chris@42 103 else if (islower(ch))
Chris@42 104 ch -= 'a' - 10;
Chris@42 105 else
Chris@42 106 break;
Chris@42 107 x = x * base + ch;
Chris@42 108 ch = GETCHR(sc);
Chris@42 109 }
Chris@42 110 x *= sign;
Chris@42 111 UNGETCHR(sc, ch);
Chris@42 112 *ret = count > 0;
Chris@42 113 return x;
Chris@42 114 }
Chris@42 115
Chris@42 116 /* vscan is mostly scanf-like, with our additional format specifiers,
Chris@42 117 but with a few twists. It returns simply 0 or 1 indicating whether
Chris@42 118 the match was successful. '(' and ')' in the format string match
Chris@42 119 those characters preceded by any whitespace. Finally, if a
Chris@42 120 character match fails, it will ungetchr() the last character back
Chris@42 121 onto the stream. */
Chris@42 122 static int vscan(scanner *sc, const char *format, va_list ap)
Chris@42 123 {
Chris@42 124 const char *s = format;
Chris@42 125 char c;
Chris@42 126 int ch = 0;
Chris@42 127 int fmt_len;
Chris@42 128
Chris@42 129 while ((c = *s++)) {
Chris@42 130 fmt_len = 0;
Chris@42 131 switch (c) {
Chris@42 132 case '%':
Chris@42 133 getformat:
Chris@42 134 switch ((c = *s++)) {
Chris@42 135 case 's': {
Chris@42 136 char *x = va_arg(ap, char *);
Chris@42 137 mygets(sc, x, fmt_len);
Chris@42 138 break;
Chris@42 139 }
Chris@42 140 case 'd': {
Chris@42 141 int *x = va_arg(ap, int *);
Chris@42 142 *x = (int) getlong(sc, 10, &ch);
Chris@42 143 if (!ch) return 0;
Chris@42 144 break;
Chris@42 145 }
Chris@42 146 case 'x': {
Chris@42 147 int *x = va_arg(ap, int *);
Chris@42 148 *x = (int) getlong(sc, 16, &ch);
Chris@42 149 if (!ch) return 0;
Chris@42 150 break;
Chris@42 151 }
Chris@42 152 case 'M': {
Chris@42 153 md5uint *x = va_arg(ap, md5uint *);
Chris@42 154 *x = (md5uint)
Chris@42 155 (0xFFFFFFFF & getlong(sc, 16, &ch));
Chris@42 156 if (!ch) return 0;
Chris@42 157 break;
Chris@42 158 }
Chris@42 159 case '*': {
Chris@42 160 if ((fmt_len = va_arg(ap, int)) <= 0) return 0;
Chris@42 161 goto getformat;
Chris@42 162 }
Chris@42 163 default:
Chris@42 164 A(0 /* unknown format */);
Chris@42 165 break;
Chris@42 166 }
Chris@42 167 break;
Chris@42 168 default:
Chris@42 169 if (isspace(c) || c == '(' || c == ')')
Chris@42 170 eat_blanks(sc);
Chris@42 171 if (!isspace(c) && (ch = GETCHR(sc)) != c) {
Chris@42 172 UNGETCHR(sc, ch);
Chris@42 173 return 0;
Chris@42 174 }
Chris@42 175 break;
Chris@42 176 }
Chris@42 177 }
Chris@42 178 return 1;
Chris@42 179 }
Chris@42 180
Chris@42 181 static int scan(scanner *sc, const char *format, ...)
Chris@42 182 {
Chris@42 183 int ret;
Chris@42 184 va_list ap;
Chris@42 185 va_start(ap, format);
Chris@42 186 ret = vscan(sc, format, ap);
Chris@42 187 va_end(ap);
Chris@42 188 return ret;
Chris@42 189 }
Chris@42 190
Chris@42 191 scanner *X(mkscanner)(size_t size, int (*getchr)(scanner *sc))
Chris@42 192 {
Chris@42 193 scanner *s = (scanner *)MALLOC(size, OTHER);
Chris@42 194 s->scan = scan;
Chris@42 195 s->vscan = vscan;
Chris@42 196 s->getchr = getchr;
Chris@42 197 s->ungotc = EOF;
Chris@42 198 return s;
Chris@42 199 }
Chris@42 200
Chris@42 201 void X(scanner_destroy)(scanner *sc)
Chris@42 202 {
Chris@42 203 X(ifree)(sc);
Chris@42 204 }