update fdprintf
[ascii.git] / ascii.c
diff --git a/ascii.c b/ascii.c
index 5eeac21c7c52b719f0ad4d6df202d58ea5ff29ce..dd54596f948c06f00d32bf003b20b149d5ec0db6 100644 (file)
--- a/ascii.c
+++ b/ascii.c
@@ -1,16 +1,16 @@
 /* depend: */
 /* cflags: */
-/* linker: */
+/* linker: atoi.o fdprintf.o */
 
-#include <assert.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
+#include <stddef.h>
+
+#include "atoi.h"
+#include "fdprintf.h"
 
 /* macros */
 
 #define VERBOSE(level, statement...) do { if (level <= verbose) { statement; } } while(0)
+#define VERSION "0.9"
 
 /* gobal variables */
 
@@ -38,67 +38,95 @@ char tablechars[256][4] = {
 
 /* help function */
 
-void usage (int ret)
+int usage (int ret)
 {
-    FILE *fd = ret ? stderr : stdout;
-    fprintf (fd, "usage: %s\n", progname);
-    fprintf (fd, " -c : number of columns (%d)\n", nbcols);
-    fprintf (fd, " -h : help message\n");
-    fprintf (fd, " -v : verbose level (%d)\n", verbose);
+    int fd = ret ? stdfderr : stdfdout;
+    fdprintf (fd, "usage: %s\n", progname);
+    fdprintf (fd, " -c : number of columns (%d)\n", nbcols);
+    fdprintf (fd, " -h : help message\n");
+    fdprintf (fd, " -v : show version\n");
 
-    exit (ret);
+    return ret;
 }
 
 /* main function */
 
 int main (int argc, char *argv[]) 
 {
-    int i;
+    int i = 0;
+
+    /* programm name */
 
     progname = argv[0];
+    while (progname[i] != '\0') {
+        if ((progname[i] == '/') || (progname[i] == '\\')) {
+            progname += i + 1;
+            i = 0;
+        } else {
+            i++;
+        }
+    }
+
+    /* argument processing */
 
-    int c;
-    while ((c = getopt(argc, argv, "c:hv:")) != EOF) {
+    while (argc-- > 1) {
+        char *arg = *(++argv);
+        if (arg[0] != '-') {
+            PRINTERR ("%s: invalid option -- %s\n", progname, arg);
+            return usage (1);
+        }
+        char c = arg[1];
         switch (c) {
         case 'c':
-            nbcols = atoi (optarg);
+            arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
+            if (arg == NULL) {
+                PRINTERR ("%s: missing number of columns\n", progname);
+                return usage (1);
+            }
+            nbcols = atoi (arg);
             break;
         case 'v':
-            verbose = atoi (optarg);
+            PRINTOUT ("%s: version %s\n", progname, VERSION);
+            return 0;
             break;
         case 'h':
         default:
-            usage (c != 'h');
+            return usage (c != 'h');
         }
     }
-    if (argc - optind != 0) {
-        fprintf (stderr, "%s: invalid option -- %s\n", progname, argv[optind]);
-        usage (1);
-    }
 
-    for (i = 0; i < 256; i++) {
-        char line[] = "   :  :    x";
+    /* main */
+
+    int n = (256 + nbcols - 1) / nbcols;
+    for (i = 0; i < n * nbcols; i++) {
+        char line[] = "   [  ]    x";
+        int j = i / nbcols + (i % nbcols) * n;
 
-        if (i > 99) line[0] = '0' + i / 100;
-        if (i > 9) line[1] = '0' + (i / 10) % 10;
-        line[2] = '0' + i % 10;
-        line[4] = '0' + i / 16;
+        if (j > 255) {
+            PRINTOUT ("\n");
+            continue;
+        }
+
+        if (j > 99) line[0] = '0' + j / 100;
+        if (j > 9) line[1] = '0' + (j / 10) % 10;
+        line[2] = '0' + j % 10;
+        line[4] = '0' + j / 16;
         if (line[4] > '9') line[4] += 'a' - '0' - 10;
-        line[5] = '0' + i % 16;
+        line[5] = '0' + j % 16;
         if (line[5] > '9') line[5] += 'a' - '0' - 10;
         
-        if (tablechars[i][0] != '\0') {
-            int j = 0;
-            while (tablechars[i][j] != '\0') {
-                line[8 + j] = tablechars[i][j];
-                j++;
+        if (tablechars[j][0] != '\0') {
+            int k = 0;
+            while (tablechars[j][k] != '\0') {
+                line[8 + k] = tablechars[j][k];
+                k++;
             }
         } else {
-            line[8] = i;
+            line[8] = j;
         }
-        line[11] = (((i + 1) % nbcols == 0) || (i == 255)) ? '\n' : ' ';
+        line[11] = ((i + 1) % nbcols == 0) ? '\n' : ' ';
 
-        write (STDOUT_FILENO, line, 12);
+        PRINTOUT ("%s", line);
     }
 
     return 0;
@@ -106,7 +134,16 @@ int main (int argc, char *argv[])
 
 // test: ascii.exe -h
 // test: ascii.exe -h | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
-// test: ascii.exe -_ 2> /dev/null | awk 'END { if (NR == 0) { exit(0) } else exit (1) }'
+// test: ascii.exe -_ 2>/dev/null | awk 'END { if (NR == 0) { exit(0) } else exit (1) }'
+// test: ascii.exe error 2>&1 | grep -q 'invalid option'
 // test: ascii.exe -_ 2>&1 | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
 
+// test: ascii.exe | awk '/ 64\[40\] @/ { rc=1 } END { exit (1-rc) }'
+// test: ascii.exe | awk '/127\[7f\] DEL/ { rc=1 } END { exit (1-rc) }'
+// test: ascii.exe -v | grep -q version
+// test: ascii.exe -c 4 | tail -1 | awk '/63/ { rc=1 } END { exit (1-rc) }'
+// test: ascii.exe -c 5 | tail -1 | awk '/51/ { rc=1 } END { exit (1-rc) }'
+// test: ascii.exe -c 6 | tail -1 | awk '/42/ { rc=1 } END { exit (1-rc) }'
+// test: ascii.exe -c 2>&1 | grep -q 'missing number of columns'
+
 /* vim: set ts=4 sw=4 et: */