changeset 860:daebbf28953d

The argument handling API in dmargs* was synced with th-libs.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 22 Nov 2014 18:50:07 +0200
parents 55a3d6db20ac
children 15b413845e24
files src/dmargs.c src/dmargs.h src/dmargs_int.c tests/blittest.c tests/efu.c tests/evaltest.c tests/vptest.c tools/auval.c tools/data2inc.c tools/fontconv.c tools/gentab.c tools/gfxconv.c tools/mod2wav.c tools/objlink.c tools/packed.c tools/ppl.c tools/view64.c tools/viewmod.c tools/xm2jss.c
diffstat 19 files changed, 247 insertions(+), 388 deletions(-) [+]
line wrap: on
line diff
--- a/src/dmargs.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/src/dmargs.c	Sat Nov 22 18:50:07 2014 +0200
@@ -1,6 +1,6 @@
 #include "dmargs.h"
 #define TH_EXTERNAL 1
-#define optarg_t DMOptArg
+#define th_optarg_t DMOptArg
 #define th_args_process dmArgsProcess
 #define th_args_help dmArgsPrintHelp
 
--- a/src/dmargs.h	Sat Nov 22 18:45:12 2014 +0200
+++ b/src/dmargs.h	Sat Nov 22 18:50:07 2014 +0200
@@ -1,7 +1,7 @@
 /*
  * Simple commandline argument processing functions
  * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2002-2008 Tecnic Software productions (TNSP)
+ * (C) Copyright 2002-2014 Tecnic Software productions (TNSP)
  *
  * Please read file 'COPYING' for information on license and distribution.
  */
@@ -17,13 +17,20 @@
 
 /* Option flags
  */
-#define OPT_NONE       (0)    // Simple option with no arguments
-#define OPT_ARGREQ     (1)    // Option's argument is required
-#define OPT_ARGOPT     (3)    // Option's argument is optional
-#define OPT_ARGMASK    (3)    // Mask for option argument flags
-#define OPT_REQUIRED   (4)    // This option is required to be given
+#define OPT_NONE             (0)    // Simple option with no arguments
+#define OPT_ARGREQ           (1)    // Option requires an argument
+#define OPT_ARGMASK          (1)    // Mask for option argument flags
 
-typedef struct {
+#define OPTH_BAILOUT         0x0001 // Bail out on errors
+#define OPTH_ONLY_OPTS       0x0010 // Handle only options
+#define OPTH_ONLY_OTHER      0x0020 // Handle only "non-options"
+#define OPTH_ONLY_MASK       0x00f0 // Mask
+
+
+/* Option argument structure
+ */
+typedef struct
+{
     int id;
     char optShort;
     char *optLong;
@@ -31,12 +38,17 @@
     int flags;
 } DMOptArg;
 
+
 BOOL dmArgsProcess(int argc, char *argv[],
-     DMOptArg argList[], int argListN,
-     BOOL (*handleOpt)(int, char *, char *),
-     BOOL (*handleFile)(char *), BOOL);
+     const DMOptArg optList[], int noptList,
+     BOOL (*handleOptionCB)(int, char *, char *),
+     BOOL (*handleFileCB)(char *), BOOL);
 
-void dmArgsPrintHelp(FILE *, DMOptArg optList[], int optListN);
+void dmArgsPrintHelp(FILE *,
+     const DMOptArg optList[],
+     const int noptList,
+     const int flags);
+
 
 #ifdef __cplusplus
 }
--- a/src/dmargs_int.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/src/dmargs_int.c	Sat Nov 22 18:50:07 2014 +0200
@@ -1,121 +1,10 @@
 /*
  * Simple commandline argument processing
  * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2002-2008 Tecnic Software productions (TNSP)
+ * (C) Copyright 2002-2014 Tecnic Software productions (TNSP)
  *
  * Please read file 'COPYING' for information on license and distribution.
  */
-/*
-Description
-===========
-Structures and functions for simple commandline argument processing,
-option argument handling (short and long forms supported).
-
-Output function for printing out short on-line help for said options
-and program commandline usage.
-
-
-Format for typical commandline:
-
-$ program -a -b -c --long-d -e argument-for-e --long-f="argument for f"
-
-where -a, -b and -c are short options without required arguments;
---long-d is a long option without argument; -e is short option with
-argument and finally --long-f is long option with argument.
-
-
-Introduction
-============
-Handling of commandline options in th_args_process() has various
-options, which effect how an option is handled. Also the error
-situations (unknown option/no required argument) can be handled
-in different ways.
-
-Typically th_args_process() is called as follows:
-
-BOOL optionHandlerCallback(int optionNumber, char *optionArgument, char *optionName)
-{
-  if (option is OK)
-    return TRUE;
-  else
-    return FALSE;
-}
-
-BOOL nonoptionHandlerCallback(char *argumentString)
-{
-  // return value same as in optionHandlerCallback
-}
-
-
-int main(int argc, char *argv[])
-{
-  if (th_args_process(argc, argv, optList, optListN,
-      optionHandlerCallback, nonoptionHandlerCallback)) {
-    ... arguments OK ...
-  } else {
-    ... arguments invalid or required arguments missing ...
-  }
-}
-
-
-NOTICE!
--------
-The return value from handler callbacks affects the return value of
-th_args_process(). Additionally, a failure in callback (returns FALSE)
-effects the argument processing if bailOut argument of th_args_process()
-is TRUE!
-
-If bailOut is TRUE, any error/failure in argument processing (including
-callbacks) immediately stops the argument processing and FALSE is
-returned from th_args_process().
-
-If bailOut is FALSE, most errors are "ignored", but FALSE is still returned
-if any errors occured.
-
-
-NOTICE #2!
-----------
-A small temporary buffer of N*sizeof(BOOL) (where N is number of
-options in optList[]) is allocated for processing required options.
-If this allocation fails, the program is immediately exited with
-code 128.
-
-
-Examples
-========
-Example of different options, in a fictional optionlist struct:
-
-optarg_t optList[] = {
-  // Option without arguments
-  { 0, '?', "help",      "Show this help",                    OPT_NONE },
-
-  // Option with a required argument
-  { 1, 'o', "output",    "Output file name",                  OPT_ARGREQ },
-  
-  // Option with optional argument
-  { 2, 'f', "foobar",    "Use foobar, with optional string",  OPT_ARGOPT },
-
-  // This option is required to be given, though without other flags
-  // it may not make much sense.
-  { 4, 'S', "stupid",     "You must give this option",        OPT_REQUIRED },
-
-  // The flags can be combined with OR operator: this option is both
-  // required to be specified, and also requires argument (the filename)
-  { 5, 'i', "input",     "Input file name",                   OPT_REQUIRED | OPT_ARGREQ },
-
-
-  // Option with only long form
-  { 0, 0,   "only-long", "Long option",                       OPT_NONE },
-
-  // Option with only short form
-  { 0, 's', NULL,        "Short option",                      OPT_NONE },
-
-};
-
-const int optListN = (sizeof(optList) / sizeof(optarg_t));
-
-
-*/
 #ifndef TH_EXTERNAL
 #include "th_util.h"
 #include "th_args.h"
@@ -123,135 +12,81 @@
 #endif
 
 
-/* Check if option requires an argument
+/* Parse long and short options
  */
-static BOOL th_args_check_arg(const optarg_t *o, const char *optArg)
-{
-    if ((o->flags & OPT_ARGMASK) == OPT_ARGREQ && optArg == NULL)
-    {
-        if (o->optShort != 0 && o->optLong != NULL)
-        {
-            THERR("Option '-%c ARG' (--%s=ARG) requires an argument!\n",
-                  o->optShort, o->optLong);
-        }
-        else if (o->optShort != 0)
-        {
-            THERR("Option '-%c ARG' requires an argument!\n", o->optShort);
-        }
-        else if (o->optLong != NULL)
-        {
-            THERR("Option --%s=ARG requires an argument!\n", o->optLong);
-        }
-
-        return FALSE;
-    }
-    else
-        return TRUE;
-}
-
-
-/* Handle short options
- */
-static BOOL th_args_process_short(char *currArg, int *newArgIndex,
-    BOOL *wasGiven, int argc, char *argv[],
-    optarg_t optList[], int optListN,
-    BOOL (*handleOpt)(int, char *, char *))
+static BOOL th_args_process_opt(
+    char *currArg, int *argIndex,
+    int argc, char *argv[],
+    const th_optarg_t opts[], int numOpts,
+    BOOL (*handleOptionCB)(int, char *, char *),
+    BOOL doProcess, BOOL isLong)
 {
-    char *tmpArg = currArg, *optArg;
-    int optN;
-    BOOL isFound;
-
-    // Short options can be combined: -a -b -c == -abc
-    while (*tmpArg)
-    {
-        for (optN = 0, isFound = FALSE; (optN < optListN) && !isFound; optN++)
-            if (*tmpArg == optList[optN].optShort)
-            {
-                // Get possible option argument, if needed
-                if ((optList[optN].flags & OPT_ARGMASK) != 0
-                    && (++(*newArgIndex) < argc))
-                    optArg = argv[*newArgIndex];
-                else
-                    optArg = NULL;
+    const th_optarg_t *opt = NULL;
+    char *optArg = NULL;
+    int optIndex;
 
-                // Check if option argument is required
-                if (!th_args_check_arg(&optList[optN], optArg))
-                    return FALSE;
-                else
-                {
-                    char tmpStr[2] = { 0, 0 };
-
-                    // Option was given succesfully, try to handle it
-                    wasGiven[optN] = TRUE;
-
-                    tmpStr[0] = *tmpArg;
-
-                    if (!handleOpt(optList[optN].id, optArg, tmpStr))
-                        return FALSE;
-                }
-
-                isFound = TRUE;
+    for (optIndex = 0; optIndex < numOpts; optIndex++)
+    {
+        const th_optarg_t *node = &opts[optIndex];
+        if (isLong && node->optLong != NULL)
+        {
+            if (strcmp(currArg, node->optLong) == 0)
+            {
+                opt = node;
+                optArg = NULL;
+                break;
             }
 
-        if (!isFound)
+            size_t len = strlen(node->optLong);
+            if (strncmp(currArg, node->optLong, len) == 0 &&
+                currArg[len] == '=')
+            {
+                opt = node;
+                optArg = (&currArg[len+1] != 0) ? &currArg[len+1] : NULL;
+                break;
+            }
+        }
+        else
+        if (!isLong && node->optShort != 0)
         {
-            THERR("Unknown short option '%c' in argument '-%s'\n",
-                  *tmpArg, currArg);
-            return FALSE;
+            if (*currArg == node->optShort)
+            {
+                opt = node;
+                optArg = (currArg[1] != 0) ? &currArg[1] : NULL;
+            }
         }
-
-        tmpArg++;
     }
 
-    return TRUE;
-}
-
-
-/* Handle long options
- */
-static BOOL th_args_process_long(char *currArg, int *newArgIndex,
-    BOOL *wasGiven, int argc, char *argv[],
-    optarg_t optList[], int optListN,
-    BOOL (*handleOpt)(int, char *, char *))
-{
-    int optN, optLen, i;
-    char *optArg;
-
-    (void) argc;
-    (void) argv;
-    (void) newArgIndex;
-
-    // Long option
-    for (optN = -1, optLen = i = 0; i < optListN && optN < 0; i++)
-        if (optList[i].optLong)
+    if (opt != NULL)
+    {
+        // Check for the possible option argument
+        if ((opt->flags & OPT_ARGMASK) == OPT_ARGREQ && optArg == NULL)
         {
-            optLen = strlen(optList[i].optLong);
-            if (strncmp(currArg, optList[i].optLong, optLen) == 0)
-                optN = i;
+            if (*argIndex < argc)
+            {
+                (*argIndex)++;
+                optArg = argv[*argIndex];
+            }
+            else
+            {
+                THERR("Option '%s%s' requires an argument.\n",
+                    isLong ? "--" : "-",
+                    currArg);
+                return FALSE;
+            }
         }
-
-    // Get possible option argument, if needed
-    if (optN >= 0)
-    {
-        if ((optList[optN].flags & OPT_ARGMASK) != 0)
-            optArg = (currArg[optLen] == '=') ? &currArg[optLen + 1] : NULL;
-        else
-            optArg = NULL;
-
-        // Check if option argument is required
-        if (!th_args_check_arg(&optList[optN], optArg))
+        
+        // Option was given succesfully, try to process it
+        if (doProcess && !handleOptionCB(opt->id, optArg, currArg))
             return FALSE;
-        else
-        {
-            // Option was given succesfully, try to handle it
-            wasGiven[optN] = TRUE;
-            if (!handleOpt(optList[optN].id, optArg, currArg))
-                return FALSE;
-        }
     }
     else
     {
-        THERR("Unknown long option '--%s'\n", currArg);
+        THERR("Unknown %s option '%s%s'\n",
+            isLong ? "long" : "short",
+            isLong ? "--" : "-",
+            currArg);
+
         return FALSE;
     }
 
@@ -263,151 +98,158 @@
  * calling the given callback functions.
  */
 BOOL th_args_process(int argc, char *argv[],
-                     optarg_t optList[], int optListN,
-                     BOOL(*handleOpt) (int, char *, char *),
-                     BOOL(*handleNonOption) (char *), BOOL bailOut)
+     const th_optarg_t *opts, const int numOpts,
+     BOOL(*handleOptionCB) (int, char *, char *),
+     BOOL(*handleOther) (char *), int flags)
 {
-    BOOL endOptions, optionsOK;
-    int argIndex, newArgIndex, i;
-    char *currArg;
-    BOOL *wasGiven;
+    int argIndex, handleFlags = flags & OPTH_ONLY_MASK;
+    BOOL optionsOK = TRUE, endOfOptions = FALSE;
 
-    // Allocate wasGiven
-    wasGiven = (BOOL *) th_calloc(optListN, sizeof(BOOL));
-    if (!wasGiven)
+    for (argIndex = 1; argIndex < argc; argIndex++)
     {
-        THERR("FATAL ERROR! Could not allocate wasGiven in th_args_process()!\n");
-        exit(128);
-    }
+        char *str = argv[argIndex];
+        if (*str == '-' && !endOfOptions)
+        {
+            // Should we process options?
+            BOOL doProcess = (handleFlags & OPTH_ONLY_OPTS) || handleFlags == 0;
+            BOOL isLong;
 
-    // Parse arguments
-    argIndex = 1;
-    optionsOK = TRUE;
-    endOptions = FALSE;
-    while (argIndex < argc)
-    {
-        currArg = argv[argIndex];
-        if ((currArg[0] == '-') && !endOptions)
-        {
-            newArgIndex = argIndex;
-            currArg++;
-            if (*currArg == '-')
+            str++;
+            if (*str == '-')
             {
                 // Check for "--", which ends the options-list
-                currArg++;
-                if (*currArg == 0)
+                str++;
+                if (*str == 0)
                 {
-                    endOptions = TRUE;
+                    endOfOptions = TRUE;
                     continue;
                 }
 
-                // Long options
-                if (!th_args_process_long(currArg, &newArgIndex,
-                                          wasGiven, argc, argv, optList,
-                                          optListN, handleOpt))
-                    optionsOK = FALSE;
+                // We have a long option
+                isLong = TRUE;
             }
             else
-            {
-                // Short options
-                if (!th_args_process_short(currArg, &newArgIndex,
-                                           wasGiven, argc, argv, optList,
-                                           optListN, handleOpt))
-                    optionsOK = FALSE;
-            }
+                isLong = FALSE;
 
-            argIndex = newArgIndex;
+            if (!th_args_process_opt(str, &argIndex, argc, argv,
+                opts, numOpts, handleOptionCB, doProcess, isLong))
+                optionsOK = FALSE;
         }
         else
+        if (handleFlags == OPTH_ONLY_OTHER || handleFlags == 0)
         {
             // Was not option argument
-            if (handleNonOption == NULL
-                || (handleNonOption != NULL && !handleNonOption(currArg)))
+            if (handleOther == NULL ||
+                (handleOther != NULL && !handleOther(str)))
             {
-                THERR("Invalid argument '%s'\n", currArg);
+                THERR("Invalid argument '%s'\n", str);
                 optionsOK = FALSE;
             }
         }
 
         // Check if we bail out on invalid argument
-        if (!optionsOK && bailOut)
-        {
-            th_free(wasGiven);
+        if (!optionsOK && (flags & OPTH_BAILOUT))
             return FALSE;
-        }
-
-        argIndex++;
     }
 
-    // Check wasGiven by isRequired
-    for (i = 0; i < optListN; i++)
-        if ((optList[i].flags & OPT_REQUIRED) != 0 && !wasGiven[i])
-        {
-            THERR("Option -%s (--%s) is required.\n",
-                  optList[i].optShort, optList[i].optLong);
-
-            optionsOK = FALSE;
-            if (bailOut)
-                break;
-        }
-
-    th_free(wasGiven);
     return optionsOK;
 }
 
 
 /* Print help for commandline arguments/options
  */
-void th_args_help(FILE *outFile, optarg_t optList[], int optListN)
+static void th_pad(FILE *outFile, int count)
+{
+    while (count--)
+        fputc(' ', outFile);
+}
+
+
+static void th_print_wrap(FILE *fh, const char *str, int spad, int rpad, int width)
 {
-    int i, nrequired;
+    size_t pos = 0;
+    BOOL first = TRUE;
+
+    while (str[pos])
+    {
+        // Pre-pad line
+        int linelen = first ? spad : rpad;
+        th_pad(fh, first ? 0 : rpad);
+        first = FALSE;
+
+        // Skip whitespace at line start
+        while (isspace(str[pos]) || str[pos] == '\n') pos++;
+        
+        // Handle each word
+        while (str[pos] && str[pos] != '\n')
+        {
+            size_t next;
+            int wlen;
+            for (wlen = 0, next = pos; str[next] && !isspace(str[next]) && str[next] != '\n'; next++, wlen++);
+//            fprintf(stdout, "X '%c', %d .. linelen=%d/%d, wlen=%d\n", str[pos], pos, linelen, width, wlen);
+            if (linelen + wlen < width)
+            {
+                for (;pos < next; pos++, linelen++)
+                    fputc(str[pos], fh);
 
-    for (i = nrequired = 0; i < optListN; i++)
+                if (str[next] == '\n' || str[next] == 0)
+                {
+                    fprintf(fh, "\n");
+                    break;
+                }
+                else
+                {
+                    fputc(str[pos], fh);
+                    pos++;
+                    linelen++;
+                }
+            }
+            else
+            {
+                fprintf(fh, "\n");
+                break;
+            }
+        }
+    }
+}
+
+
+void th_args_help(FILE *fh,
+    const th_optarg_t *opts, const int numOpts,
+    const int flags)
+{
+    int index;
+    (void) flags;
+
+    // Print out option list
+    for (index = 0; index < numOpts; index++)
     {
-        optarg_t *o = &optList[i];
+        const th_optarg_t *opt = &opts[index];
+        char tmpStr[128];
 
         // Print short option
-        if (o->optShort != 0)
-            fprintf(outFile, "  -%c,  ", o->optShort);
+        if (opt->optShort != 0)
+        {
+            snprintf(tmpStr, sizeof(tmpStr),
+                "-%c,", opt->optShort);
+        }
         else
-            fprintf(outFile, "       ");
+            tmpStr[0] = 0;
+
+        fprintf(fh, " %-5s", tmpStr);
 
         // Print long option
-        if (o->optLong)
+        if (opt->optLong != NULL)
         {
-            char tmpStr[64], *p;
-
-            if ((o->flags & OPT_ARGMASK) == OPT_ARGOPT)
-            {
-                snprintf(tmpStr, sizeof(tmpStr), "%s[=ARG]",
-                         optList[i].optLong);
-                p = tmpStr;
-            }
-            else if ((o->flags & OPT_ARGMASK) == OPT_ARGREQ)
-            {
-                snprintf(tmpStr, sizeof(tmpStr), "%s=ARG",
-                         optList[i].optLong);
-                p = tmpStr;
-            }
-            else
-                p = o->optLong;
-
-            fprintf(outFile, "--%-15s", p);
+            snprintf(tmpStr, sizeof(tmpStr), "--%s%s",
+                opt->optLong,
+                (opt->flags & OPT_ARGREQ) ? "=ARG" : "");
         }
         else
-            fprintf(outFile, "                 ");
+            tmpStr[0] = 0;
 
-        fprintf(outFile, "  %s.", optList[i].desc);
+        fprintf(fh, "%-20s", tmpStr);
 
-        if (o->flags & OPT_REQUIRED)
-        {
-            fprintf(outFile, " [*]\n");
-            nrequired++;
-        }
-        else
-            fprintf(outFile, "\n");
+        th_print_wrap(fh, opt->desc, 26, 26, 73);
     }
-
-    if (nrequired > 0)
-        fprintf(outFile, "(Options marked with [*] are required)\n");
 }
--- a/tests/blittest.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tests/blittest.c	Sat Nov 22 18:50:07 2014 +0200
@@ -12,7 +12,7 @@
 int optScrWidth = 640, optScrHeight = 480, optFontSize = 20, optScrDepth = 32;
 int optBenchmarkLen = 20;
 
-DMOptArg optList[] = {
+static const DMOptArg optList[] = {
     { 0, '?', "help",       "Show this help", OPT_NONE },
     { 2, 'v', "verbose",    "Be more verbose", OPT_NONE },
     { 3, 'f', "full",       "Fullscreen", OPT_NONE },
@@ -27,7 +27,7 @@
 
 void argShowHelp()
 {
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 }
 
 
@@ -288,7 +288,7 @@
 
     dmInitProg("blittest", "dmlib blittest", "0.2", NULL, NULL);
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, NULL, FALSE))
+        argHandleOpt, NULL, OPTH_BAILOUT))
         exit(1);
 
     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
--- a/tests/efu.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tests/efu.c	Sat Nov 22 18:50:07 2014 +0200
@@ -14,7 +14,8 @@
 int optScrWidth = 640, optScrHeight = 480, optFontSize = 20, optScrDepth = 32;
 int optBenchmarkLen = 20;
 
-DMOptArg optList[] = {
+static const DMOptArg optList[] =
+{
     { 0, '?', "help",       "Show this help", OPT_NONE },
     { 2, 'v', "verbose",    "Be more verbose", OPT_NONE },
     { 3, 'f', "full",       "Fullscreen", OPT_NONE },
@@ -29,7 +30,7 @@
 
 void argShowHelp()
 {
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 }
 
 
@@ -285,7 +286,7 @@
     DMResource *file;
     
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, NULL, FALSE))
+        argHandleOpt, NULL, OPTH_BAILOUT))
         exit(1);
 
     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
--- a/tests/evaltest.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tests/evaltest.c	Sat Nov 22 18:50:07 2014 +0200
@@ -8,7 +8,7 @@
 char *  optExpression = "";
 
 
-DMOptArg optList[] =
+static const DMOptArg optList[] =
 {
     { 0, '?', "help",       "Show this help", OPT_NONE },
     { 1, 'v', "verbose",    "Be more verbose", OPT_NONE },
@@ -23,7 +23,7 @@
 void argShowHelp()
 {
     dmPrintBanner(stdout, dmProgName, "[options] [-e] '<expression>'");
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 }
 
 
@@ -79,7 +79,7 @@
 
     // Parse arguments
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleNonOpt, FALSE))
+        argHandleOpt, argHandleNonOpt, OPTH_BAILOUT))
         exit(1);
 
 
--- a/tests/vptest.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tests/vptest.c	Sat Nov 22 18:50:07 2014 +0200
@@ -16,7 +16,8 @@
 int optScrWidth = 640, optScrHeight = 480, optFontSize = 8, optScrDepth = 32;
 int optBenchmarkLen = 20;
 
-DMOptArg optList[] = {
+static const DMOptArg optList[] =
+{
     { 0, '?', "help",       "Show this help", OPT_NONE },
     { 2, 'v', "verbose",    "Be more verbose", OPT_NONE },
     { 3, 'f', "full",       "Fullscreen", OPT_NONE },
@@ -31,7 +32,7 @@
 
 void argShowHelp()
 {
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 }
 
 
@@ -123,7 +124,7 @@
 
     dmVerbosity = 5;
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, NULL, FALSE))
+        argHandleOpt, NULL, OPTH_BAILOUT))
         exit(1);
 
     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
--- a/tools/auval.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/auval.c	Sat Nov 22 18:50:07 2014 +0200
@@ -51,7 +51,8 @@
      optScale = TRUE;
 
 
-DMOptArg optList[] = {
+static const DMOptArg optList[] =
+{
     { 0, '?', "help",       "Show this help", OPT_NONE },
     { 2, 'v', "verbose",    "Be more verbose", OPT_NONE },
     { 3,   0, "fs",         "Fullscreen", OPT_NONE },
@@ -70,7 +71,7 @@
 void argShowHelp()
 {
     printf("%s v%s\n(C) Copyright 2011 ccr/TNSP\n", AUVAL_NAME, AUVAL_VERSION);
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 }
 
 
@@ -608,7 +609,7 @@
     int histPos = 0, histMax = 0, viewMode;
     SDL_Surface *screen = NULL, *bmp = NULL;
     TTF_Font *font = NULL;
-    SDL_Color fontcol={255,255,255, 0};
+    SDL_Color fontcol = {255,255,255, 0};
     SDL_Event event;
     SDL_AudioSpec fmt;
     AUAudioData audata;
@@ -620,7 +621,7 @@
 
     /* Parse arguments */
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, NULL, FALSE))
+        argHandleOpt, NULL, 0))
         exit(1);
 
 
--- a/tools/data2inc.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/data2inc.c	Sat Nov 22 18:50:07 2014 +0200
@@ -39,7 +39,7 @@
 void (*writeFooter) (FILE *, size_t, char *) = NULL;
 
 
-static DMOptArg optList[] =
+static const DMOptArg optList[] =
 {
     {  0, '?', "help",           "Show this help", OPT_NONE },
     {  4, 'A', "format-asm",     "Output in XA-compatible asm", OPT_NONE },
@@ -62,7 +62,7 @@
     dmPrintBanner(stdout, dmProgName,
         "[options] [sourcefile] [destfile]");
 
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
     
     printf(
     "\n"
@@ -275,7 +275,7 @@
 
     /* Parse arguments */
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, TRUE))
+        argHandleOpt, argHandleFile, OPTH_BAILOUT))
         exit(1);
 
     /* Determine output type, if not specified */
--- a/tools/fontconv.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/fontconv.c	Sat Nov 22 18:50:07 2014 +0200
@@ -21,7 +21,7 @@
 SDL_Color optColor = { 255, 255, 255, 100 };
 
 
-DMOptArg optList[] =
+static const DMOptArg optList[] =
 {
     {  0, '?', "help",     "Show this help", OPT_NONE },
     {  1, 'v', "verbose",  "Be more verbose", OPT_NONE },
@@ -41,7 +41,7 @@
             dmPrintBanner(stdout, dmProgName,
                 "[options] <sourcefile.(ttf|fnt|dmf|png)> <outputfile.dmf>");
 
-            dmArgsPrintHelp(stdout, optList, optListN);
+            dmArgsPrintHelp(stdout, optList, optListN, 0);
             printf(
             "\n"
             "This utility can be used to convert TSFONT files to bitmap DMFONT (DMF)\n"
@@ -282,7 +282,7 @@
 
     // Parse arguments
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, TRUE))
+        argHandleOpt, argHandleFile, OPTH_BAILOUT))
         exit(1);
 
     // Check arguments
--- a/tools/gentab.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/gentab.c	Sat Nov 22 18:50:07 2014 +0200
@@ -50,7 +50,7 @@
     *optOutFilename = NULL;
 
 
-static DMOptArg optList[] =
+static const DMOptArg optList[] =
 {
     {  0, '?', "help",        "Show this help", OPT_NONE },
     {  1, 'v', "verbose",     "Increase verbosity", OPT_NONE },
@@ -75,7 +75,7 @@
 {
     int index;
     dmPrintBanner(stdout, dmProgName, "[options]");
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 
     printf("\nAvailable types:\n");
     for (index = 0; index < MT_LAST; index++)
@@ -182,7 +182,7 @@
 
     // Parse arguments
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, NULL, TRUE))
+        argHandleOpt, NULL, OPTH_BAILOUT))
         exit(1);
 
     // Check settings
--- a/tools/gfxconv.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/gfxconv.c	Sat Nov 22 18:50:07 2014 +0200
@@ -149,7 +149,7 @@
     .format = 0,
 };
 
-static DMOptArg optList[] =
+static const DMOptArg optList[] =
 {
     {  0, '?', "help",         "Show this help", OPT_NONE },
     { 15, 'v', "verbose",      "Increase verbosity", OPT_NONE },
@@ -217,7 +217,7 @@
 void argShowHelp()
 {
     dmPrintBanner(stdout, dmProgName, "[options] <input file>");
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 
     printf(
     "\n"
@@ -1547,7 +1547,7 @@
     dmInitProg("gfxconv", "Simple graphics converter", "0.80", NULL, NULL);
 
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, TRUE))
+        argHandleOpt, argHandleFile, OPTH_BAILOUT))
         exit(1);
 
 #ifndef DM_USE_LIBPNG
--- a/tools/mod2wav.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/mod2wav.c	Sat Nov 22 18:50:07 2014 +0200
@@ -28,7 +28,7 @@
 size_t  optPlayTime;
 
 
-DMOptArg optList[] =
+static const DMOptArg optList[] =
 {
     {  0, '?', "help",     "Show this help", OPT_NONE },
     {  2, 'v', "verbose",  "Be more verbose", OPT_NONE },
@@ -56,7 +56,7 @@
             dmPrintBanner(stdout, dmProgName,
                 "[options] [sourcefile] [destfile]");
                 
-            dmArgsPrintHelp(stdout, optList, optListN);
+            dmArgsPrintHelp(stdout, optList, optListN, 0);
             exit(0);
             break;
 
@@ -139,7 +139,7 @@
 
     // Parse arguments
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, TRUE))
+        argHandleOpt, argHandleFile, OPTH_BAILOUT))
         exit(1);
 
     // Check arguments
--- a/tools/objlink.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/objlink.c	Sat Nov 22 18:50:07 2014 +0200
@@ -148,7 +148,8 @@
 
 /* Arguments
  */
-static DMOptArg optList[] = {
+static const DMOptArg optList[] =
+{
     {  0, '?', "help",        "Show this help", OPT_NONE },
     {  1, 'r', "input-raw",   "RAW input: -r <file>:<addr>", OPT_ARGREQ },
     {  2, 'p', "input-prg",   "PRG input: -p <file>[:<addr>]", OPT_ARGREQ },
@@ -172,7 +173,7 @@
     int i;
 
     dmPrintBanner(stdout, dmProgName, "[options]");
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 
     printf(
     "\n"
@@ -769,7 +770,7 @@
 
     // Parse arguments
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, NULL, TRUE))
+        argHandleOpt, NULL, OPTH_BAILOUT))
         exit(1);
 
     if (nsrcFiles < 1)
--- a/tools/packed.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/packed.c	Sat Nov 22 18:50:07 2014 +0200
@@ -38,7 +38,7 @@
 int    optDefResFlags = 0;
 
 
-static DMOptArg optList[] =
+static const DMOptArg optList[] =
 {
     { 0, '?', "help",        "Show this help", OPT_NONE },
     { 1, 'p', "pack",        "Set pack filename (default: " SET_DEFAULT_PACK ")", OPT_ARGREQ },
@@ -58,7 +58,7 @@
 void argShowHelp()
 {
     dmPrintBanner(stdout, dmProgName, "[options] [-p <packfilename>] [filename[s]]");
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
     fprintf(stdout,
     "\n"
     "Examples:\n"
@@ -293,7 +293,7 @@
     dmVerbosity = 1;
     
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, TRUE))
+        argHandleOpt, argHandleFile, OPTH_BAILOUT))
         exit(1);
 
     // Check PACK filename
--- a/tools/ppl.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/ppl.c	Sat Nov 22 18:50:07 2014 +0200
@@ -54,7 +54,7 @@
 size_t  optPlayTime;
 
 
-DMOptArg optList[] =
+static const DMOptArg optList[] =
 {
     {  0, '?', "help",     "Show this help", OPT_NONE },
     {  1, 'v', "verbose",  "Be more verbose", OPT_NONE },
@@ -78,7 +78,7 @@
 void argShowHelp()
 {
     dmPrintBanner(stdout, dmProgName, "[options] <module>");
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 }
 
 
@@ -571,7 +571,7 @@
 
     // Parse arguments
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, TRUE))
+        argHandleOpt, argHandleFile, OPTH_BAILOUT))
         exit(1);
 
     // Open the files
--- a/tools/view64.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/view64.c	Sat Nov 22 18:50:07 2014 +0200
@@ -18,7 +18,7 @@
 int    optForcedFormat = -1;
 
 
-static DMOptArg optList[] =
+static const DMOptArg optList[] =
 {
     { 0, '?', "help",       "Show this help", OPT_NONE },
     { 1, 'v', "verbose",    "Be more verbose", OPT_NONE },
@@ -42,7 +42,7 @@
     int i;
 
     dmPrintBanner(stdout, dmProgName, "[options] <input image file>");
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 
     printf("\nAvailable bitmap formats:\n");
     for (i = 0; i < ndmC64ImageFormats; i++)
@@ -169,7 +169,7 @@
 
     /* Parse arguments */
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, FALSE))
+        argHandleOpt, argHandleFile, OPTH_BAILOUT))
         exit(1);
 
 
--- a/tools/viewmod.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/viewmod.c	Sat Nov 22 18:50:07 2014 +0200
@@ -21,7 +21,7 @@
         optDump = FALSE;
 
 
-DMOptArg optList[] =
+static const DMOptArg optList[] =
 {
     { 0, '?', "help", "Show this help and exit", OPT_NONE },
     { 1, 'p', "patterns", "View patterns", OPT_NONE },
@@ -38,7 +38,7 @@
 void argShowHelp()
 {
     dmPrintBanner(stdout, dmProgName, "[options] [modfile]");
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 }
 
 
@@ -388,7 +388,7 @@
 
     // Parse arguments
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, TRUE))
+        argHandleOpt, argHandleFile, OPTH_BAILOUT))
         exit(1);
 
     // Initialize miniJSS
--- a/tools/xm2jss.c	Sat Nov 22 18:45:12 2014 +0200
+++ b/tools/xm2jss.c	Sat Nov 22 18:50:07 2014 +0200
@@ -44,7 +44,8 @@
 };
 
 
-DMOptArg optList[] = {
+static const DMOptArg optList[] =
+{
     { 0, '?', "help",           "Show this help", OPT_NONE },
     { 1, 'v', "verbose",        "Be more verbose", OPT_NONE },
     { 2, 'i', "ignore",         "Ignore errors", OPT_NONE },
@@ -65,7 +66,7 @@
     int i;
 
     dmPrintBanner(stdout, dmProgName, "[options] <input.xm> <output.jmod>");
-    dmArgsPrintHelp(stdout, optList, optListN);
+    dmArgsPrintHelp(stdout, optList, optListN, 0);
 
     printf("\n"
     "Pattern storage modes:\n");
@@ -928,7 +929,7 @@
 
     // Parse arguments
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, TRUE))
+        argHandleOpt, argHandleFile, OPTH_BAILOUT))
         exit(1);
 
     // Check arguments