home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / unix / emx / test / scanf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-16  |  4.8 KB  |  205 lines

  1. /* scanf.c (emx+gcc) */
  2.  
  3. /* Note: This program is not portable and uses dirty tricks. */
  4. /*       It's a test program, not a sample program.          */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10.  
  11. #define FALSE 0
  12. #define TRUE  1
  13.  
  14. #define TYPE_STRING 0
  15. #define TYPE_U16    1
  16. #define TYPE_S16    2
  17. #define TYPE_U32    3
  18. #define TYPE_S32    4
  19. #define TYPE_FLOAT  5
  20. #define TYPE_DOUBLE 6
  21.  
  22. struct data
  23. {
  24.   char type;
  25.   size_t len;
  26. };
  27.  
  28. static struct data *data;
  29. static void **list;
  30. static int allocated, used;
  31.  
  32.  
  33. static void add (size_t n, char type)
  34. {
  35.   void *tmp;
  36.  
  37.   tmp = malloc (n);
  38.   if (tmp == NULL)
  39.     {
  40.       fputs ("Out of memory\n", stderr);
  41.       exit (1);
  42.     }
  43.   if (used >= allocated)
  44.     {
  45.       allocated += 1;
  46.       list = realloc (list, allocated * sizeof (list[0]));
  47.       data = realloc (data, allocated * sizeof (data[0]));
  48.       if (list == NULL || data == NULL)
  49.         {
  50.           fputs ("Out of memory\n", stderr);
  51.           exit (1);
  52.         }
  53.     }
  54.   list[used] = tmp;
  55.   data[used].type = type;
  56.   data[used].len = n;
  57.   ++used;
  58. }
  59.  
  60.  
  61. static void parse (const char *fmt)
  62. {
  63.   int assign, first;
  64.   char size;
  65.  
  66.   list = NULL; data = NULL; allocated = 0; used = 0;
  67.   while (*fmt != 0)
  68.     {
  69.       if (*fmt == '%')
  70.         {
  71.           ++fmt;
  72.           assign = TRUE; size = 0;
  73.           if (*fmt == '*')
  74.             {
  75.               assign = FALSE; ++fmt;
  76.             }
  77.           while (isdigit (*fmt))
  78.             ++fmt;
  79.           if (*fmt == 'h' || *fmt == 'l')
  80.             size = *fmt++;
  81.           if (*fmt == 0)
  82.             break;
  83.           switch (*fmt)
  84.             {
  85.             case '[':
  86.               first = TRUE;
  87.               ++fmt;
  88.               if (*fmt == '^')
  89.                 ++fmt;
  90.               while (*fmt != 0)
  91.                 {
  92.                   if (*fmt == ']' && !first)
  93.                     break;
  94.                   if (fmt[1] == '-' && fmt[2] != 0 &&
  95.                       (unsigned char)fmt[0] < (unsigned char)fmt[2])
  96.                     fmt += 3;
  97.                   else
  98.                     ++fmt;
  99.                   first = FALSE;
  100.                 }
  101.               if (*fmt == 0)
  102.                 --fmt;
  103.               if (assign)
  104.                 add (1024, TYPE_STRING);
  105.               break;
  106.             case 'c':
  107.             case 's':
  108.               if (assign)
  109.                 add (1024, TYPE_STRING);
  110.               break;
  111.             case 'f':
  112.             case 'e':
  113.             case 'E':
  114.             case 'g':
  115.             case 'G':
  116.               if (assign)
  117.                 {
  118.                   if (size == 'l')
  119.                     add (sizeof (double), TYPE_DOUBLE);
  120.                   else
  121.                     add (sizeof (float), TYPE_FLOAT);
  122.                 }
  123.               break;
  124.             case 'i':
  125.             case 'd':
  126.               if (assign)
  127.                 {
  128.                   if (size == 'h')
  129.                     add (sizeof (short), TYPE_S16);
  130.                   else
  131.                     add (sizeof (int), TYPE_S32);
  132.                 }
  133.               break;
  134.             case 'u':
  135.             case 'o':
  136.             case 'x':
  137.             case 'X':
  138.               if (assign)
  139.                 {
  140.                   if (size == 'h')
  141.                     add (sizeof (short), TYPE_U16);
  142.                   else
  143.                     add (sizeof (int), TYPE_U32);
  144.                 }
  145.               break;
  146.             }
  147.         }
  148.       ++fmt;
  149.     }
  150. }
  151.  
  152.  
  153. int main (void)
  154. {
  155.   int i, n;
  156.   char fmt[128], *p;
  157.  
  158.   printf ("Format: "); fflush (stdout);
  159.   if (fgets (fmt, sizeof (fmt), stdin) == NULL)
  160.     return (0);
  161.   p = strchr (fmt, '\n');
  162.   if (p != NULL) *p = 0;
  163.   parse (fmt);
  164.   for (;;)
  165.     {
  166.       for (i = 0; i < used; ++i)
  167.         memset (list[i], 0, data[i].len);
  168.       printf ("Input: "); fflush (stdout);
  169.       n = vscanf (fmt, list);
  170.       printf ("n=%d", n);
  171.       for (i = 0; i < used; ++i)
  172.         {
  173.           printf (" %d:", i+1);
  174.           switch (data[i].type)
  175.             {
  176.             case TYPE_STRING:
  177.               printf ("%s", (char *)list[i]);
  178.               break;
  179.             case TYPE_U16:
  180.               printf ("%hu", *(unsigned short *)list[i]);
  181.               break;
  182.             case TYPE_S16:
  183.               printf ("%hd", *(short *)list[i]);
  184.               break;
  185.             case TYPE_U32:
  186.               printf ("%lu", *(unsigned long *)list[i]);
  187.               break;
  188.             case TYPE_S32:
  189.               printf ("%ld", *(long *)list[i]);
  190.               break;
  191.             case TYPE_FLOAT:
  192.               printf ("%g", *(float *)list[i]);
  193.               break;
  194.             case TYPE_DOUBLE:
  195.               printf ("%g", *(double *)list[i]);
  196.               break;
  197.           }
  198.         }
  199.       putchar ('\n');
  200.       if (feof (stdin))
  201.         break;
  202.     }
  203.   return (0);
  204. }
  205.