[llvm-commits] CVS: llvm/tools/lli/Interpreter/ExternalFunctions.cpp

Chris Lattner lattner at cs.uiuc.edu
Mon Mar 31 16:13:01 PST 2003


Changes in directory llvm/tools/lli/Interpreter:

ExternalFunctions.cpp updated: 1.42 -> 1.43

---
Log message:

Implement scanf and fix sscanf to actually endian swap the results correctly


---
Diffs of the changes:

Index: llvm/tools/lli/Interpreter/ExternalFunctions.cpp
diff -u llvm/tools/lli/Interpreter/ExternalFunctions.cpp:1.42 llvm/tools/lli/Interpreter/ExternalFunctions.cpp:1.43
--- llvm/tools/lli/Interpreter/ExternalFunctions.cpp:1.42	Sun Jan 12 18:59:47 2003
+++ llvm/tools/lli/Interpreter/ExternalFunctions.cpp	Mon Mar 31 16:12:37 2003
@@ -410,17 +410,111 @@
   return GV;
 }
 
+static void ByteswapSCANFResults(const char *Fmt, void *Arg0, void *Arg1,
+                                 void *Arg2, void *Arg3, void *Arg4, void *Arg5,
+                                 void *Arg6, void *Arg7, void *Arg8) {
+  void *Args[] = { Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, 0 };
+
+  // Loop over the format string, munging read values as appropriate (performs
+  // byteswaps as neccesary).
+  unsigned ArgNo = 0;
+  while (*Fmt) {
+    if (*Fmt++ == '%') {
+      // Read any flag characters that may be present...
+      bool Suppress = false;
+      bool Half = false;
+      bool Long = false;
+      bool LongLong = false;  // long long or long double
+
+      while (1) {
+        switch (*Fmt++) {
+        case '*': Suppress = true; break;
+        case 'a': /*Allocate = true;*/ break;  // We don't need to track this
+        case 'h': Half = true; break;
+        case 'l': Long = true; break;
+        case 'q':
+        case 'L': LongLong = true; break;
+        default:
+          if (Fmt[-1] > '9' || Fmt[-1] < '0')   // Ignore field width specs
+            goto Out;
+        }
+      }
+    Out:
+
+      // Read the conversion character
+      if (!Suppress && Fmt[-1] != '%') { // Nothing to do?
+        unsigned Size = 0;
+        const Type *Ty = 0;
+
+        switch (Fmt[-1]) {
+        case 'i': case 'o': case 'u': case 'x': case 'X': case 'n': case 'p':
+        case 'd':
+          if (Long || LongLong) {
+            Size = 8; Ty = Type::ULongTy;
+          } else if (Half) {
+            Size = 4; Ty = Type::UShortTy;
+          } else {
+            Size = 4; Ty = Type::UIntTy;
+          }
+          break;
+
+        case 'e': case 'g': case 'E':
+        case 'f':
+          if (Long || LongLong) {
+            Size = 8; Ty = Type::DoubleTy;
+          } else {
+            Size = 4; Ty = Type::FloatTy;
+          }
+          break;
+
+        case 's': case 'c': case '[':  // No byteswap needed
+          Size = 1;
+          Ty = Type::SByteTy;
+          break;
+
+        default: break;
+        }
+
+        if (Size) {
+          GenericValue GV;
+          void *Arg = Args[ArgNo++];
+          memcpy(&GV, Arg, Size);
+          TheInterpreter->StoreValueToMemory(GV, (GenericValue*)Arg, Ty);
+        }
+      }
+    }
+  }
+}
+
 // int sscanf(const char *format, ...);
 GenericValue lle_X_sscanf(FunctionType *M, const vector<GenericValue> &args) {
   assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!");
 
-  const char *Args[10];
+  char *Args[10];
   for (unsigned i = 0; i < args.size(); ++i)
-    Args[i] = (const char*)GVTOP(args[i]);
+    Args[i] = (char*)GVTOP(args[i]);
 
   GenericValue GV;
   GV.IntVal = sscanf(Args[0], Args[1], Args[2], Args[3], Args[4],
                      Args[5], Args[6], Args[7], Args[8], Args[9]);
+  ByteswapSCANFResults(Args[1], Args[2], Args[3], Args[4],
+                       Args[5], Args[6], Args[7], Args[8], Args[9], 0);
+  return GV;
+}
+
+// int scanf(const char *format, ...);
+GenericValue lle_X_scanf(FunctionType *M, const vector<GenericValue> &args) {
+  assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!");
+
+  char *Args[10];
+  for (unsigned i = 0; i < args.size(); ++i)
+    Args[i] = (char*)GVTOP(args[i]);
+
+  GenericValue GV;
+  GV.IntVal = scanf(Args[0], Args[1], Args[2], Args[3], Args[4],
+                    Args[5], Args[6], Args[7], Args[8], Args[9]);
+  ByteswapSCANFResults(Args[0], Args[1], Args[2], Args[3], Args[4],
+                       Args[5], Args[6], Args[7], Args[8], Args[9]);
   return GV;
 }
 
@@ -644,6 +738,7 @@
   FuncNames["lle_X_printf"]       = lle_X_printf;
   FuncNames["lle_X_sprintf"]      = lle_X_sprintf;
   FuncNames["lle_X_sscanf"]       = lle_X_sscanf;
+  FuncNames["lle_X_scanf"]        = lle_X_scanf;
   FuncNames["lle_i_clock"]        = lle_i_clock;
   FuncNames["lle_X_fopen"]        = lle_X_fopen;
   FuncNames["lle_X_fclose"]       = lle_X_fclose;





More information about the llvm-commits mailing list