aboutsummaryrefslogtreecommitdiffstats
path: root/src/gfile/gfile_scang.c
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2014-08-20 17:42:53 +1000
committerinmarket <andrewh@inmarket.com.au>2014-08-20 17:42:53 +1000
commit0f3f8f68f87233bf59c3fa68c3dfe1f492a1a478 (patch)
tree3dc625e7dfcfc620e83827ccd18423be1b5334f4 /src/gfile/gfile_scang.c
parentfcbb66a9394eaf4059bc942df6729b4b55a057d8 (diff)
downloaduGFX-0f3f8f68f87233bf59c3fa68c3dfe1f492a1a478.tar.gz
uGFX-0f3f8f68f87233bf59c3fa68c3dfe1f492a1a478.tar.bz2
uGFX-0f3f8f68f87233bf59c3fa68c3dfe1f492a1a478.zip
Rename lots of files to help prevent compile time name conflicts.
Diffstat (limited to 'src/gfile/gfile_scang.c')
-rw-r--r--src/gfile/gfile_scang.c234
1 files changed, 234 insertions, 0 deletions
diff --git a/src/gfile/gfile_scang.c b/src/gfile/gfile_scang.c
new file mode 100644
index 00000000..5fac5ce3
--- /dev/null
+++ b/src/gfile/gfile_scang.c
@@ -0,0 +1,234 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/********************************************************
+ * Scang Routines
+ ********************************************************/
+
+#include "gfx.h"
+
+#if GFX_USE_GFILE && GFILE_NEED_SCANG
+
+int fscang(GFILE *f, const char *fmt, ...) {
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = vfscang(f, fmt, ap);
+ va_end(ap);
+ return res;
+}
+
+int vfscang(GFILE *f, const char *fmt, va_list arg) {
+ int res, width, size, base;
+ unsigned long num;
+ char c;
+ bool_t assign, negate;
+ char *p;
+
+ for(res = 0; *fmt; fmt++) {
+ switch(*fmt) {
+ case ' ': case '\t': case '\r': case '\n': case '\v': case '\f':
+ break;
+
+ case '%':
+ fmt++;
+ assign = TRUE;
+ negate = FALSE;
+ width = 0;
+ size = 1;
+ num = 0;
+
+ if (*fmt == '*') {
+ fmt++;
+ assign = FALSE;
+ }
+ while(*fmt >= '0' && *fmt <= '9')
+ width = width * 10 + (*fmt++ - '0');
+ if (*fmt == 'h') {
+ fmt++;
+ size = 0;
+ } else if (*fmt == 'l') {
+ fmt++;
+ size = 2;
+ } else if (*fmt == 'L') {
+ fmt++;
+ size = 3;
+ }
+ switch(*fmt) {
+ case 0:
+ return res;
+ case '%':
+ goto matchchar;
+ case 'c':
+ if (!width) {
+ while(1) {
+ if (!gfileRead(f, &c, 1)) return res;
+ switch(c) {
+ case ' ': case '\t': case '\r':
+ case '\n': case '\v': case '\f': continue;
+ }
+ break;
+ }
+ width = 1;
+ } else {
+ if (!gfileRead(f, &c, 1)) return res;
+ }
+ if (assign) {
+ p = va_arg(arg, char *);
+ res++;
+ *p++ = c;
+ }
+ while(--width) {
+ if (!gfileRead(f, &c, 1)) return res;
+ if (assign) *p++ = c;
+ }
+ break;
+ case 's':
+ while(1) {
+ if (!gfileRead(f, &c, 1)) return res;
+ switch(c) {
+ case ' ': case '\t': case '\r':
+ case '\n': case '\v': case '\f': continue;
+ }
+ break;
+ }
+ if (assign) {
+ p = va_arg(arg, char *);
+ res++;
+ *p++ = c;
+ }
+ if (width) {
+ while(--width) {
+ if (!gfileRead(f, &c, 1)) {
+ if (assign) *((char *)p) = 0;
+ return res;
+ }
+ if (assign) *p++ = c;
+ }
+ } else {
+ while(1) {
+ if (!gfileRead(f, &c, 1)) {
+ if (assign) *((char *)p) = 0;
+ return res;
+ }
+ switch(c) {
+ case ' ': case '\t': case '\r':
+ case '\n': case '\v': case '\f': break;
+ default:
+ if (assign) *p++ = c;
+ continue;
+ }
+ break;
+ }
+ //ungetch(c);
+ }
+ if (assign) *p = 0;
+ break;
+ case 'd': base = 10; goto getnum;
+ case 'i': base = -1; goto getnum;
+ case 'o': base = 8; goto getnum;
+ case 'u': base = 10; goto getnum;
+ case 'x': base = 16; goto getnum;
+ case 'b': base = 2;
+ getnum:
+ while(1) {
+ if (!gfileRead(f, &c, 1)) return res;
+ switch(c) {
+ case ' ': case '\t': case '\r':
+ case '\n': case '\v': case '\f': continue;
+ }
+ break;
+ }
+ if (c == '-' && *fmt != 'u') {
+ negate = TRUE;
+ if ((width && !--width) || !gfileRead(f, &c, 1)) return res;
+ }
+ if (base == -1) {
+ if (c == '0') {
+ if ((width && !--width) || !gfileRead(f, &c, 1)) goto assignnum;
+ switch(c) {
+ case 'x': case 'X':
+ base = 16;
+ if ((width && !--width) || !gfileRead(f, &c, 1)) return res;
+ break;
+ case 'b': case 'B':
+ base = 2;
+ if ((width && !--width) || !gfileRead(f, &c, 1)) return res;
+ break;
+ default:
+ base = 8;
+ break;
+ }
+ } else
+ base = 10;
+ }
+ while(1) {
+ if (c >= '0' && c <= '9' && c - '0' < base)
+ num = num * base + (c - '0');
+ else if (c >= 'A' && c <= 'F' && base == 16)
+ num = num * base + (c - ('A'-10));
+ else if (c >= 'a' && c <= 'f' && base == 16)
+ num = num * base + (c - ('a'-10));
+ else {
+ // ungetch(c)
+ break;
+ }
+ if ((width && !--width) || !gfileRead(f, &c, 1))
+ break;
+ }
+
+ assignnum:
+ if (negate)
+ num = -num;
+
+ if (assign) {
+ switch(size) {
+ case 0: // short
+ p = (char *)va_arg(arg, short *);
+ res++;
+ *((short *)p) = (short)num;
+ case 1: // int
+ p = (char *)va_arg(arg, int *);
+ res++;
+ *((int *)p) = (int)num;
+ case 2: case 3: // long
+ p = (char *)va_arg(arg, long *);
+ res++;
+ *((long *)p) = (long)num;
+ }
+ }
+ break;
+
+ #if GFILE_ALLOW_FLOATS
+ case 'e': case 'f': case 'g':
+ // TODO
+ #endif
+ default:
+ return res;
+ }
+
+ break;
+
+ default:
+ matchchar:
+ while(1) {
+ if (!gfileRead(f, &c, 1)) return res;
+ switch(c) {
+ case ' ': case '\t': case '\r':
+ case '\n': case '\v': case '\f': continue;
+ }
+ break;
+ }
+ if (c != *fmt) return res;
+ break;
+ }
+ }
+ return res;
+}
+
+#endif //GFX_USE_GFILE && GFILE_NEED_SCANG