/* * testField.c - simple driver to test methods of field.h. * * "Copyright (c) 2013 by Fritz Sieker." * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written * agreement is hereby granted, provided that the above copyright notice * and the following two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" * BASIS, AND THE AUTHOR NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, * UPDATES, ENHANCEMENTS, OR MODIFICATIONS." */ #include #include #include #include "field.h" // Union of float and integer typedef union _floatInt { // Single memory location interpreted as different formats! int i; float f; } floatInt; /** @mainpage cs270 Spring 2014 Programming Assignment PA2 - Bit Fields in C * \htmlinclude "FIELD.html" */ /** @file: testField.c * @brief Driver to test functions of field.c (do not modify) * * @details This is a driver program to test the functions * defined in field.h and implemented in field.c. The program takes one * or more command line parameters and calls one of the methods, then * prints the results. To see how to use the program, execute * testField in a terminal window. This will print a usage * statement defining how to run the program. The first parameter of the * program is always a key defining which function to run. The * options are: *
    *
  • bin print the next parameter in decimal, hex and binary
  • *
  • fits check if value will fit in a field (3 more parameters)
  • *
  • get get a field from a value (4 more parameter)
  • *
  • set set a field in a value (4 more parameters)
  • *
*

* A sample execution might be: testField get 0xABCD 9 4 0 *

* which prints

dec: 60  hex: 0x3C  bin: 0000-0000-0000-0000-0000-0000-0011-1100
*

* All values may be entered as signed decimal numbers or as hex values * by beginning it with 0x. *

* @author Fritz Sieker */ /** Print the binary representation of a value starting at the specified * bit position. A separator is printed every 4 bits for easy reading. * @param value the value to be printed * @param msb the bit position to begin printing (31 to 0) */ void printBinaryMSB (int value, int msb) { while (msb >= 0) { putchar(((value & (1 << msb)) ? '1' : '0')); if (msb && ((msb & 0x3) == 0)) putchar('-'); msb--; } } /** Print a 32 bit binary representation of a value. * @param value the value to be printed */ void printBinary (int value) { printBinaryMSB(value, 31); } /** Print a usage statement, then exit the program returning a non zero * value, the Linux convention indicating an error */ static void usage() { puts("Usage: testField bins value"); puts(" testField fits value width isSigned"); puts(" testField get value hi lo isSigned"); puts(" testField set value hi lo newValue"); exit(1); } /** print the value in decimal, hex and binary. * @param result the value to be printed. */ static void printResult (int result) { printf("dec: %d hex: 0x%X bin: ", result, result); printBinary(result); } /** Entry point of the program * @param argc count of arguments, will always be at least 1 * @param argv array of parameters to program argv[0] is the name of * the program, so additional parameters will begin at index 1. * @return 0 the Linux convention for success. */ int main (int argc, char* argv[]) { char* junk; int value, hi, lo, isSigned, width; if (argc < 3) usage(); char* op = argv[1]; if ((strcmp(op, "bin") == 0) && (argc == 3)) { printResult((int) strtol(argv[2], &junk, 0)); } else if ((strcmp(op, "fits") == 0) && (argc == 5)) { value = (int) strtol(argv[2], &junk, 0); width = (int) strtol(argv[3], &junk, 0); isSigned = (int) strtol(argv[4], &junk, 0); printf("%d\n", fieldFits(value, width, isSigned)); } else if ((strcmp(op, "get") == 0) && (argc == 6)) { value = (int) strtol(argv[2], &junk, 0); hi = (int) strtol(argv[3], &junk, 0); lo = (int) strtol(argv[4], &junk, 0); isSigned = (int) strtol(argv[5], &junk, 0); printResult(getField(value, hi, lo, isSigned)); } else if ((strcmp(op, "set") == 0) && (argc == 6)) { value = (int) strtol(argv[2], &junk, 0); hi = (int) strtol(argv[3], &junk, 0); lo = (int) strtol(argv[4], &junk, 0); printResult(setField(value, hi, lo, strtol(argv[5], &junk, 0))); } else if ((strcmp(op,"floatHex") == 0) && (argc == 3)) { // Deconstruct floating point number floatInt value; value.f = atof(argv[2]); printf("float = %f\n", value.f); int sign = getField(value.i, 31, 31, 0); int exponent = getField(value.i, 31, 23, 0); int mantissa = getField(value.i, 22, 0, 0); printf("sign = %d\n", sign); printf("exponent = %d\n", exponent); printf("mantissa = 0x%6x\n", mantissa); } else if ((strcmp(op,"hexFloat") == 0) && (argc == 3)) { // Construct floating point number floatInt value; int hex = (int)strtol(argv[2], NULL, 16); printf("hexadecimal = 0x%08x\n", hex); value.i = 0; value.i = setField(value.i, 31, 31, (hex & 0x80000000) >> 31); value.i = setField(value.i, 30, 23, (hex & 0x7F800000) >> 23); value.i = setField(value.i, 22, 0, (hex & 0x007FFFFF) >> 0); printf("float = %f\n", value.f); } else usage(); printf("\n"); return 0; }