home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / graphics-0.17 / dist-stat / btoa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-13  |  9.1 KB  |  405 lines

  1. /*
  2.  * $Header: /files1/home/toy/src/stat/RCS/btoa.c,v 1.3 90/11/04 17:12:05 toy Exp $
  3.  * NAME
  4.  *    btoa - binary to ASCII
  5.  *
  6.  * SYNOPSIS
  7.  *    btoa [-H] [-P prec] [-i{cisudf}] [-o{cdx}] [-c cols] [files ...]
  8.  *
  9.  * DESCRIPTION
  10.  *    Read in the data using the specified format and print
  11.  *    out the data in human-readable form according to the
  12.  *    desired output format.
  13.  *
  14.  *    The -c option specifies the number of columns to be used
  15.  *    in printing the output.  The default is 8.  The -P option
  16.  *    specifies the default precision for printing floating point
  17.  *    numbers.
  18.  *
  19.  *    The recognized input formats are specified using the -i
  20.  *    option.  The formats are:
  21.  *
  22.  *        c    - signed char
  23.  *        C    - unsigned char
  24.  *        i    - int
  25.  *        I    - unsigned int
  26.  *        s    - short int
  27.  *        S    - unsigned short int
  28.  *        l    - long
  29.  *        L    - unsigned long
  30.  *        f    - float
  31.  *        d    - double
  32.  *
  33.  *    The default input format is s, short int.
  34.  *
  35.  *    The numbers are printed out according the to -o option.
  36.  *    The valid formats are:
  37.  *
  38.  *        a    - ASCII, or octal if not printable
  39.  *        b    - byte values, hex
  40.  *        c    - characters
  41.  *        d    - decimal integers
  42.  *        o    - octal integers
  43.  *        u    - unsigned integers
  44.  *        x    - hexadecimal format
  45.  *        f    - floating point
  46.  *
  47.  *    Suitable defaults are chosen for each input format.  The
  48.  *    default is d, decimal integers.
  49.  *
  50.  * HISTORY
  51.  * $Log:    btoa.c,v $
  52.  * Revision 1.3  90/11/04  17:12:05  toy
  53.  * errcnt was not initialized
  54.  *
  55.  * Revision 1.2  90/09/11  18:24:02  toy
  56.  * Added support for an "a" (ASCII) output format.
  57.  * Fixed a few bugs in printing numbers in columns.
  58.  *
  59.  * Revision 1.1  90/09/10  20:16:53  toy
  60.  * Initial revision
  61.  *
  62.  */
  63.  
  64. #include <stdio.h>
  65. #include <string.h>
  66. #include <ctype.h>
  67.  
  68. #if    defined(__STDC__) || defined(__GNUC__)
  69. #include <stddef.h>
  70. #include <stdlib.h>
  71. #endif
  72.  
  73. #include "gps.h"
  74.  
  75. extern int getopt ();
  76. extern int optind;
  77. extern char *optarg;
  78.  
  79. static const char RCSID[] = "@(#) $Id: btoa.c,v 1.3 90/11/04 17:12:05 toy Exp $";
  80.  
  81. const char *progname;
  82.  
  83. #define    DEF_PROGNAME    "btoa"
  84. #define    OPT_STRING    "Hc:i:o:"
  85. #define    DEF_INPUT_FORM    's'
  86. #define    DEF_OUTPUT_FORM    'd'
  87. #define    INPUT_FORMATS    "csilfdCSIL"
  88. #define    OUTPUT_FORMATS    "abcduoxf"
  89.  
  90. #if    defined(__STDC__) || defined(__GNUC__)
  91. void
  92. help (void)
  93. #else
  94. void
  95. help ()
  96. #endif
  97. {
  98.   static const char *help_strings[] =
  99.   {
  100.     "\t-H\tThis help\n",
  101.     "\t-c c\tNumber of output columns per line\n",
  102.     "\t-i i\tThe input is assumed to have the format specified.\n",
  103.     "\t\tThe option character means char, short, int, long, float,\n",
  104.     "\t\tor double.  Use upper case character for unsigned versions.\n",
  105.     "\t-o o\tOutput format.  The option character means ascii,\n",
  106.     "\t\tbyte (hex), char, decimal, unsigned, octal, hex, floating\n",
  107.     "Read the given file or stdin assuming the input is in the\n",
  108.     "specified format.  This in then printed out in the specified\n",
  109.     "output format.  This is useful for printing out a speech file.\n",
  110.     NULL
  111.   };
  112.  
  113.   (void) fprintf (stderr, "%s\n\n", RCSID);
  114.   (void) fprintf (stderr, "Usage:  %s [-H] [-c cols] [-i{%s}] [-o{%s}] [files]\n",
  115.           progname, INPUT_FORMATS, OUTPUT_FORMATS);
  116.   print_help_strings (help_strings);
  117.   (void) fprintf (stderr, "The default input format is `%c'; the default output, `%c'.\n",
  118.           DEF_INPUT_FORM, DEF_OUTPUT_FORM);
  119. }
  120.  
  121.  
  122. #if    defined(__STDC__) || defined(__GNUC__)
  123. void
  124. print_it (int input_form, int output_form)
  125. #else
  126. void
  127. print_it (input_form, output_form)
  128.      int input_form;
  129.      int output_form;
  130. #endif
  131. {
  132.   char hformat[BUFSIZ];
  133.   char oformat[BUFSIZ];
  134.   int k;
  135.   int input_size;
  136.   long value;
  137.   unsigned long uvalue;
  138.   union
  139.   {
  140.     char Char;
  141.     unsigned char Uchar;
  142.     short Short;
  143.     unsigned short Ushort;
  144.     int Int;
  145.     unsigned Uint;
  146.     long Long;
  147.     unsigned long Ulong;
  148.     float Float;
  149.     double Double;
  150.     char buffer[sizeof (double)];
  151.   } number;
  152.  
  153.   /*
  154.    * Initialize number buffer
  155.    */
  156.   memset (number.buffer, 0, sizeof (double));
  157.  
  158.   /*
  159.    * Figure out the size of the input item
  160.    */
  161.  
  162.   switch (input_form)
  163.     {
  164.     case 'c':            /* Character type     */
  165.     case 'C':
  166.       input_size = sizeof (char);
  167.       break;
  168.     case 'i':            /* Integer type         */
  169.     case 'I':
  170.       input_size = sizeof (int);
  171.       break;
  172.     case 's':            /* Short int type     */
  173.     case 'S':
  174.       input_size = sizeof (short);
  175.       break;
  176.     case 'l':            /* Long int type     */
  177.     case 'L':
  178.       input_size = sizeof (long);
  179.       break;
  180.     case 'f':            /* Float type         */
  181.       input_size = sizeof (float);
  182.       break;
  183.     case 'd':            /* Double type         */
  184.       input_size = sizeof (double);
  185.       break;
  186.     default:
  187.       message ("Fatal internal error:  print_it size char = %x\n", (int) input_form);
  188.       exit (2);
  189.     }                /* endswitch     */
  190.  
  191.   if ((input_form == 'f') || (input_form == 'd'))
  192.     {
  193.       while (fread (&number.buffer, input_size, 1, stdin) == 1)
  194.     {
  195.       if (output_form == 'b')
  196.         {
  197.           for (k = 0; k < input_size; k++)
  198.         {
  199.           printf ("%02hx", ((unsigned short) number.buffer[k]) & 0xff);
  200.         }
  201.           next_column (stdout);
  202.         }
  203.       else
  204.         {
  205.           print_number (stdout, (input_form == 'f') ? number.Float : number.Double);
  206.         }
  207.     }            /* endwhile      */
  208.     }
  209.   else
  210.     {
  211.  
  212.       /*
  213.        * Compute the correct field width for printing hex
  214.        * and octal numbers
  215.        */
  216.  
  217.       (void) sprintf (hformat, "%%0%dlx", 2 * input_size);
  218.       (void) sprintf (oformat, "%%0%dlo", (8 * input_size + 2) / 3);
  219.  
  220.       /*
  221.        * Read in the desired element
  222.        */
  223.  
  224.       while (fread (&number.buffer, input_size, 1, stdin) == 1)
  225.     {
  226.  
  227.       /*
  228.            * Convert the input number into a long or
  229.            * unsigned long
  230.            */
  231.  
  232.       if (input_size == sizeof (unsigned long))
  233.         {
  234.           uvalue = number.Ulong;
  235.           value = number.Long;
  236.         }
  237.       else if (input_size == sizeof (unsigned int))
  238.         {
  239.           uvalue = (unsigned long) number.Uint;
  240.           value = (long) number.Int;
  241.         }
  242.       else if (input_size == sizeof (unsigned short))
  243.         {
  244.           uvalue = (unsigned long) number.Ushort;
  245.           value = (long) number.Short;
  246.         }
  247.       else
  248.         {
  249.           uvalue = (unsigned long) number.Uchar;
  250.           value = (long) number.Char;
  251.         }
  252.  
  253.       /*
  254.            * Print out the number in the desired format
  255.            */
  256.  
  257.       switch (output_form)
  258.         {
  259.         case 'a':        /* ASCII         */
  260.           for (k = 0; k < input_size; k++)
  261.         {
  262.           if (isascii (number.buffer[k]) && isprint (number.buffer[k]))
  263.             {
  264.               putchar (number.buffer[k]);
  265.             }
  266.           else
  267.             {
  268.               printf ("\\%03o", ((unsigned short) number.buffer[k]) & 0xff);
  269.             }
  270.           next_column (stdout);
  271.         }
  272.           break;
  273.         case 'b':        /* Byte             */
  274.           for (k = 0; k < input_size; k++)
  275.         {
  276.           printf ("%02hx", ((unsigned short) number.buffer[k]) & 0xff);
  277.         }
  278.           next_column (stdout);
  279.           break;
  280.         case 'c':        /* Characters         */
  281.           for (k = 0; k < input_size; k++)
  282.         {
  283.           putchar ((int) number.buffer[k]);
  284.         }
  285.           next_column (stdout);
  286.           break;
  287.         case 'd':        /* Decimal integers     */
  288.           printf ("%ld", value);
  289.           next_column (stdout);
  290.           break;
  291.         case 'u':        /* Unsigned integer     */
  292.           printf ("%lu", uvalue);
  293.           next_column (stdout);
  294.           break;
  295.         case 'o':        /* Octal format         */
  296.           printf (oformat, uvalue);
  297.           next_column (stdout);
  298.           break;
  299.         case 'x':        /* Hex format         */
  300.           printf (hformat, uvalue);
  301.           next_column (stdout);
  302.           break;
  303.         case 'f':        /* Floating format     */
  304.           print_number (stdout, (double) value);
  305.           next_column (stdout);
  306.           break;
  307.         default:
  308.           message ("Fatal error:  unknown output format:  `%c' (%0x)\n", output_form, (int) output_form);
  309.           exit (2);
  310.         }            /* endswitch     */
  311.     }            /* endwhile     */
  312.     }                /* endif     */
  313. }
  314.  
  315.  
  316.  
  317. int
  318. main (argc, argv)
  319.      int argc;
  320.      char *argv[];
  321. {
  322.   char input_format;
  323.   char output_format;
  324.   int option;
  325.   int errcnt;
  326.  
  327.   progname = get_my_name (argv[0], DEF_PROGNAME);
  328.   set_def_prec ();
  329.   set_max_columns (8);
  330.  
  331.   input_format = DEF_INPUT_FORM;
  332.   output_format = DEF_OUTPUT_FORM;
  333.   errcnt = 0;
  334.  
  335.   while ((option = getopt (argc, argv, OPT_STRING)) != -1)
  336.     {
  337.       switch (option)
  338.     {
  339.     case 'H':        /* Help             */
  340.       help ();
  341.       exit (0);
  342.       break;
  343.     case 'c':        /* Columns         */
  344.       set_max_columns (atoi (optarg));
  345.       break;
  346.     case 'i':        /* Input format         */
  347.       input_format = *optarg;
  348.       break;
  349.     case 'o':        /* Output format     */
  350.       output_format = *optarg;
  351.       break;
  352.     default:
  353.       break;
  354.     }            /* endswitch     */
  355.     }                /* endwhile     */
  356.  
  357.   /*
  358.    * Check options
  359.    */
  360.  
  361.   if (strchr (INPUT_FORMATS, input_format) == NULL)
  362.     {
  363.       message ("Unknown input format character: `%c' (0x%x)\n", input_format, (int) input_format);
  364.       errcnt++;
  365.     }
  366.   if (strchr (OUTPUT_FORMATS, output_format) == NULL)
  367.     {
  368.       message ("Unknown output format character:  `%c' (0x%x)\n", output_format, (int) output_format);
  369.       errcnt++;
  370.     }
  371.   if (errcnt > 0)
  372.     {
  373.       help ();
  374.       exit (1);
  375.     }
  376.  
  377.   /*
  378.    * Print each specified file, or use stdin, if non
  379.    * given
  380.    */
  381.  
  382.   if (optind >= argc)
  383.     {
  384.       print_it (input_format, output_format);
  385.     }
  386.   else
  387.     {
  388.       while (optind < argc)
  389.     {
  390.       if (freopen (argv[optind], "r", stdin) == NULL)
  391.         {
  392.           message ("cannot open for reading:  `%s'\n", argv[optind]);
  393.         }
  394.       else
  395.         {
  396.           print_it (input_format, output_format);
  397.         }
  398.       optind++;
  399.     }
  400.     }
  401.  
  402.   end_column (stdout);
  403.   return 0;
  404. }
  405.