From d5432bccff8c43b27f42ba5a44a7ed8f124d0867 Mon Sep 17 00:00:00 2001
From: sam <sam@92316355-f0b4-4df1-b90c-862c8a59935f>
Date: Mon, 29 Sep 2008 22:05:10 +0000
Subject: [PATCH] Hide the list of available commands in pipi/context.c, so
 that the pipi source code doesn't need to know about them.

git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2857 92316355-f0b4-4df1-b90c-862c8a59935f
---
 pipi/context.c |  55 +++++++++
 pipi/pipi.h    |   9 ++
 src/pipi.c     | 303 ++++++++++---------------------------------------
 3 files changed, 127 insertions(+), 240 deletions(-)

diff --git a/pipi/context.c b/pipi/context.c
index c490655..9af6d5c 100644
--- a/pipi/context.c
+++ b/pipi/context.c
@@ -42,6 +42,61 @@ void pipi_destroy_context(pipi_context_t *ctx)
     free(ctx);
 }
 
+pipi_command_t const *pipi_get_command_list(void)
+{
+    static pipi_command_t const list[] =
+    {
+        { "load", 1 },
+        { "save", 1 },
+
+        { "dup", 0 },
+        { "swap", 0 },
+        { "roll", 1 },
+
+        { "gamma", 1 },
+        { "scale", 1 },
+        { "geometry", 1 },
+        { "tile", 1 },
+        { "dither", 1 },
+        { "blur", 1 },
+        { "boxblur", 1 },
+        { "median", 1 },
+        { "gray", 0 },
+        { "brightness", 1 },
+        { "contrast", 1 },
+        { "autocontrast", 0 },
+        { "order", 0 },
+        { "hflip", 0 },
+        { "vflip", 0 },
+        { "rotate90", 0 },
+        { "rotate180", 0 },
+        { "rotate270", 0 },
+        { "invert", 0 },
+        { "threshold", 1 },
+        { "dilate", 0 },
+        { "erode", 0 },
+        { "wrap", 0 },
+        { "combine", 0 },
+        { "split", 0 },
+        { "mean", 0 },
+        { "min", 0 },
+        { "max", 0 },
+        { "add", 0 },
+        { "sub", 0 },
+        { "difference", 0 },
+        { "multiply", 0 },
+        { "divide", 0 },
+        { "screen", 0 },
+        { "overlay", 0 },
+        { "line", 1 },
+
+        /* End marker */
+        { NULL, 0 }
+    };
+
+    return list;
+}
+
 int pipi_command(pipi_context_t *ctx, char const *cmd, ...)
 {
     if(!strcmp(cmd, "load"))
diff --git a/pipi/pipi.h b/pipi/pipi.h
index d0f400d..ee2cf7d 100644
--- a/pipi/pipi.h
+++ b/pipi/pipi.h
@@ -104,11 +104,20 @@ typedef struct pipi_context pipi_context_t;
 /* pipi_histogram_t: the histogram type */
 typedef struct pipi_histogram pipi_histogram_t;
 
+/* pipi_command_t: the command type */
+typedef struct
+{
+    char const *name;
+    int argc;
+}
+pipi_command_t;
+
 extern pipi_pixel_t *pipi_get_color_from_string(const char* s);
 
 
 extern pipi_context_t *pipi_create_context(void);
 extern void pipi_destroy_context(pipi_context_t *);
+extern pipi_command_t const *pipi_get_command_list(void);
 extern int pipi_command(pipi_context_t *, char const *, ...);
 
 extern pipi_image_t *pipi_load(char const *);
diff --git a/src/pipi.c b/src/pipi.c
index 0b1bc28..b8ed6d9 100644
--- a/src/pipi.c
+++ b/src/pipi.c
@@ -7,260 +7,83 @@
 
 #include <pipi.h>
 
+static const char * aliases[] =
+{
+    "-o", "--save",
+    "--output", "--save",
+    NULL, NULL,
+};
+
+static pipi_command_t const *list;
+
 int main(int argc, char *argv[])
 {
     pipi_context_t *ctx;
 
     ctx = pipi_create_context();
+    list = pipi_get_command_list();
 
     while(*++argv)
     {
-        if(!strcmp(argv[0], "--dup"))
-        {
-            if(pipi_command(ctx, "dup") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--swap"))
-        {
-            if(pipi_command(ctx, "swap") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--roll"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "roll", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--gamma"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "gamma", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--scale"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "scale", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--geometry"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "geometry", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--tile"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "tile", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--dither"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "dither", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--blur"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "blur", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--boxblur"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "boxblur", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--median"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "median", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--gray"))
-        {
-            if(pipi_command(ctx, "gray") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--brightness"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "brightness", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--contrast"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "contrast", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--autocontrast"))
-        {
-            if(pipi_command(ctx, "autocontrast") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--order"))
-        {
-            if(pipi_command(ctx, "order") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--hflip"))
-        {
-            if(pipi_command(ctx, "hflip") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--vflip"))
-        {
-            if(pipi_command(ctx, "vflip") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--rotate90"))
-        {
-            if(pipi_command(ctx, "rotate90") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--rotate180"))
-        {
-            if(pipi_command(ctx, "rotate180") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--rotate270"))
-        {
-            if(pipi_command(ctx, "rotate270") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--invert"))
-        {
-            if(pipi_command(ctx, "invert") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--threshold"))
-        {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "threshold", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--dilate"))
-        {
-            if(pipi_command(ctx, "dilate") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--erode"))
-        {
-            if(pipi_command(ctx, "erode") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--wrap"))
-        {
-            if(pipi_command(ctx, "wrap") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--combine"))
-        {
-            if(pipi_command(ctx, "combine") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--split"))
-        {
-            if(pipi_command(ctx, "split") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--mean"))
-        {
-            if(pipi_command(ctx, "mean") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--min"))
-        {
-            if(pipi_command(ctx, "min") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--max"))
-        {
-            if(pipi_command(ctx, "max") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--add"))
-        {
-            if(pipi_command(ctx, "add") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--sub"))
-        {
-            if(pipi_command(ctx, "sub") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--difference"))
-        {
-            if(pipi_command(ctx, "difference") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--multiply"))
-        {
-            if(pipi_command(ctx, "multiply") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--divide"))
-        {
-            if(pipi_command(ctx, "divide") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--screen"))
-        {
-            if(pipi_command(ctx, "screen") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--overlay"))
-        {
-            if(pipi_command(ctx, "overlay") != 0)
-                return EXIT_FAILURE;
-        }
-        else if(!strcmp(argv[0], "--line"))
-        {
-            if(argv[6] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "line", argv[1]) != 0)
-                return EXIT_FAILURE;
-            argv++;
-        }
-        else if(!strcmp(argv[0], "--output") || !strcmp(argv[0], "-o"))
+        pipi_command_t const *cmd;
+        char const * const *flag;
+        char const * arg;
+        int i;
+
+        arg = argv[0];
+        for(flag = aliases; flag[0]; flag += 2)
+            if(!strcmp(arg, flag[0]))
+                arg = flag[1];
+
+        if(!strncmp(arg, "--", 2))
         {
-            if(argv[1] == NULL)
-                return EXIT_FAILURE;
-            if(pipi_command(ctx, "save", argv[1]) != 0)
+            for(cmd = list; cmd->name; cmd++)
+                if(!strcmp(arg + 2, cmd->name))
+                    break;
+
+            if(!cmd->name)
+            {
+                fprintf(stderr, "unknown command %s\n", argv[0]);
                 return EXIT_FAILURE;
-            argv++;
+            }
+
+            for(i = 1; i <= cmd->argc; i++)
+                if(argv[i] == NULL)
+                {
+                    fprintf(stderr, "too few arguments for %s\n", argv[0]);
+                    return EXIT_FAILURE;
+                }
+
+            switch(cmd->argc)
+            {
+            case 0:
+                if(pipi_command(ctx, cmd->name) != 0)
+                {
+                    fprintf(stderr, "command %s failed\n", argv[0]);
+                    return EXIT_FAILURE;
+                }
+                break;
+            case 1:
+                if(pipi_command(ctx, cmd->name, argv[1]) != 0)
+                {
+                    fprintf(stderr, "command %s failed\n", argv[0]);
+                    return EXIT_FAILURE;
+                }
+                break;
+            default:
+                /* Can’t handle that argument count */
+                return EXIT_FAILURE;
+            }
+
+            argv += cmd->argc;
         }
         else
         {
-            if(pipi_command(ctx, "load", argv[0]) != 0)
+            if(pipi_command(ctx, "load", arg) != 0)
+            {
+                fprintf(stderr, "could not load `%s'\n", argv[0]);
                 return EXIT_FAILURE;
+            }
         }
     }