瀏覽代碼

Hack long long support into scanf. For now, will fail for unsigned long longs
that are greater that long long max, but works well enough to support interface
in busybox. Just a temporary measure until scanf.c is rewritten.

Manuel Novoa III 23 年之前
父節點
當前提交
485ed9315e
共有 2 個文件被更改,包括 24 次插入4 次删除
  1. 4 1
      libc/stdio/Makefile
  2. 20 3
      libc/stdio/scanf.c

+ 4 - 1
libc/stdio/Makefile

@@ -25,13 +25,16 @@ include $(TOPDIR)Rules.mak
 LIBC=$(TOPDIR)libc.a
 
 PRINTF_FLAGS =
+SCANF_FLAGS =
 
 ifeq ($(HAS_FLOATS),true)
 	PRINTF_FLAGS += -DWANT_DOUBLE
+	SCANF_FLAGS += -DWANT_DOUBLE
 endif
 
 ifeq ($(HAS_LONG_LONG),true)
 	PRINTF_FLAGS += -DWANT_LONG_LONG
+	SCANF_FLAGS += -DWANT_LONG_LONG
 endif
 
 MSRC=stdio.c
@@ -72,7 +75,7 @@ $(MOBJ2): $(MSRC2)
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
 
 $(MOBJ3): $(MSRC3)
-	$(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+	$(CC) $(CFLAGS) $(SCANF_FLAGS) -DL_$* $< -c -o $*.o
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
 
 $(COBJS): %.o : %.c

+ 20 - 3
libc/stdio/scanf.c

@@ -169,7 +169,11 @@ register const char *fmt;
 va_list ap;
 
 {
+#if WANT_LONG_LONG
+	long long n;
+#else
 	register long n;
+#endif
 	register int c, width, lval, cnt = 0;
 	int store, neg, base, wide1, endnull, rngflag, c2;
 	register unsigned char *p;
@@ -219,9 +223,13 @@ va_list ap;
 			case '*':
 				endnull = store = 0;
 				goto fmtnxt;
-
 			case 'l':			/* long data */
 				lval = 1;
+#if WANT_LONG_LONG
+			    if (*fmt == 'L') { /* long long data */
+					lval = 2;
+				}
+#endif
 				goto fmtnxt;
 			case 'h':			/* short data */
 				lval = 0;
@@ -250,8 +258,10 @@ va_list ap;
 			case 'u':			/* unsigned decimal */
 			  numfmt:skip();
 
+#if 0
 				if (isupper(*fmt))
 					lval = 1;
+#endif
 
 				if (!base) {
 					base = 10;
@@ -300,7 +310,13 @@ va_list ap;
 				if (store) {
 					if (neg == 1)
 						n = -n;
-					if (lval)
+#if WANT_LONG_LONG
+					if (lval == 2)
+						*va_arg(ap, long long *) = n;
+
+					else
+#endif
+					if (lval == 1)
 						*va_arg(ap, long *) = n;
 
 					else
@@ -316,9 +332,10 @@ va_list ap;
 			case 'g':
 				skip();
 				fprintf(stderr, "LIBM:SCANF");
-
+#if 0
 				if (isupper(*fmt))
 					lval = 1;
+#endif
 
 				fstate = FS_INIT;
 				neg = 0;