changeset 1642:8fb4e8c825d6

Refactor "packed" utility. This breaks commandline backwards compatibility.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 28 May 2018 15:54:03 +0300
parents f28f36162740
children 1834a477e0e2
files tools/packed.c
diffstat 1 files changed, 96 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/tools/packed.c	Mon May 28 15:17:44 2018 +0300
+++ b/tools/packed.c	Mon May 28 15:54:03 2018 +0300
@@ -1,7 +1,7 @@
 /*
  * PACKed - PACKfile EDitor
  * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2011 Tecnic Software productions (TNSP)
+ * (C) Copyright 2011, 2018 Tecnic Software productions (TNSP)
  */
 #include "dmtool.h"
 #include "dmlib.h"
@@ -13,7 +13,6 @@
 
 
 #define	SET_MAX_FILES	  (4096)
-#define SET_DEFAULT_PACK  "data.pak"
 #define	SET_TMPBUF_SIZE   (128 * 1024)
 
 enum
@@ -41,19 +40,25 @@
 int    optDefResFlags = 0;
 
 
+static const DMOptArg cmdList[] =
+{
+    { CMD_CREATE  , 'c', "create",      "Create and add files to PACK", OPT_NONE },
+    { CMD_ADD     , 'a', "add",         "Add files to PACK", OPT_NONE },
+    { CMD_LIST    , 'l', "list",        "List files in PACK", OPT_NONE },
+    { CMD_EXTRACT , 'e', "extract",     "Extract files from PACK", OPT_NONE },
+};
+
+static const int cmdListN = sizeof(cmdList) / sizeof(cmdList[0]);
+
+
 static const DMOptArg optList[] =
 {
     {  0, '?', "help",        "Show this help", OPT_NONE },
-    {  1, 'p', "pack",        "Set pack filename (default: " SET_DEFAULT_PACK ")", OPT_ARGREQ },
-    {  2, 'c', "create",      "Create and add files to PACK", OPT_NONE },
-    {  3, 'a', "add",         "Add files to PACK", OPT_NONE },
-    {  4, 'l', "list",        "List files in PACK", OPT_NONE },
-    {  5, 'e', "extract",     "Extract files from PACK", OPT_NONE },
-    {  6, 'n', "nocompress",  "No compression / decompression", OPT_NONE },
-    { 10, 'C', "level",       "Set zlib compression level 1-9", OPT_ARGREQ },
-    {  7, 'v', "verbose",     "Increase verbosity", OPT_NONE },
-    {  8, 'f', "resflags",    "Set default resource flags (-f 0xff)", OPT_ARGREQ },
-    {  9, 'x', "exclude",     "Exclude name/glob pattern from add", OPT_ARGREQ },
+    {  1, 'n', "nocompress",  "No compression / decompression", OPT_NONE },
+    {  2, 'C', "level",       "Set zlib compression level 1-9", OPT_ARGREQ },
+    {  3, 'v', "verbose",     "Increase verbosity", OPT_NONE },
+    {  4, 'f', "resflags",    "Set default resource flags (-f 0xff)", OPT_ARGREQ },
+    {  5, 'x', "exclude",     "Exclude name/glob pattern from add", OPT_ARGREQ },
 };
 
 static const int optListN = sizeof(optList) / sizeof(optList[0]);
@@ -61,14 +66,28 @@
 
 void argShowHelp()
 {
-    dmPrintBanner(stdout, dmProgName, "[options] [-p <packfilename>] [filename[s]]");
+    dmPrintBanner(stdout, dmProgName, "<command> [options] [<filename(s)>]");
+
+    for (int i = 0; i < cmdListN; i++)
+    {
+        const DMOptArg *cmd = &cmdList[i];
+        char tmpStr[128];
+        snprintf(tmpStr, sizeof(tmpStr), "%c / %s",
+            cmd->optShort, cmd->optLong);
+
+        fprintf(stdout, "  %-15s   %s\n", tmpStr, cmd->desc);
+    }
+
+    fprintf(stdout, "\n");
+
     dmArgsPrintHelp(stdout, optList, optListN, 0);
+
     fprintf(stdout,
         "\n"
         "Examples:\n"
-        "$ %s -p test.pak -l         -- list files in test.pak\n"
-        "$ %s -a foobar.jpg          -- add foobar.jpg in " SET_DEFAULT_PACK "\n"
-        "$ %s -e foobar.jpg          -- extract foobar.jpg from " SET_DEFAULT_PACK "\n",
+        "$ %s l test.pak             -- list files in test.pak\n"
+        "$ %s c test.pak foobar.jpg  -- create test.pak and add foobar.jpg in it\n"
+        "$ %s e test.pak foobar.jpg  -- extract foobar.jpg from test.pak\n",
         dmProgName, dmProgName, dmProgName);
 }
 
@@ -84,30 +103,23 @@
             break;
 
         case 1:
-            optPackFilename = optArg;
-            break;
-        case 2:
-            optCommand = CMD_CREATE;
-            break;
-        case 3:
-            optCommand = CMD_ADD;
-            break;
-        case 4:
-            optCommand = CMD_LIST;
-            break;
-        case 5:
-            optCommand = CMD_EXTRACT;
-            break;
-
-        case 6:
             optDoCompress = FALSE;
             break;
 
-        case 7:
+        case 2:
+            optCompressLevel = atoi(optArg);
+            if (optCompressLevel < 1 || optCompressLevel > 9)
+            {
+                dmErrorMsg("Invalid compression level argument '%s', must be 1 .. 9.\n", optArg);
+                return FALSE;
+            }
+            break;
+
+        case 3:
             dmVerbosity++;
             break;
 
-        case 8:
+        case 4:
             {
                 unsigned int i;
                 if (!dmGetIntVal(optArg, &i))
@@ -119,7 +131,7 @@
             }
             break;
 
-        case 9:
+        case 5:
             if (nexcFilenames < SET_MAX_FILES)
             {
                 excFilenames[nexcFilenames++] = optArg;
@@ -132,15 +144,6 @@
             }
             break;
 
-        case 10:
-            optCompressLevel = atoi(optArg);
-            if (optCompressLevel < 1 || optCompressLevel > 9)
-            {
-                dmErrorMsg("Invalid compression level argument '%s', must be 1 .. 9.\n", optArg);
-                return FALSE;
-            }
-            break;
-
         default:
             return FALSE;
     }
@@ -149,8 +152,32 @@
 }
 
 
-BOOL argHandleFile(char *currArg)
+BOOL argHandleNonOpt(char *currArg)
 {
+    if (optCommand == CMD_NONE)
+    {
+        for (int n = 0; n < cmdListN; n++)
+        {
+            const DMOptArg *cmd = &cmdList[n];
+            if ((currArg[0] == cmd->optShort && currArg[1] == 0) ||
+                strcmp(currArg, cmd->optLong) == 0)
+            {
+                optCommand = cmd->id;
+                break;
+            }
+        }
+        if (optCommand == CMD_NONE)
+        {
+            dmErrorMsg("Invalid command '%s'.\n", currArg);
+            return FALSE;
+        }
+    }
+    else
+    if (optPackFilename == NULL)
+    {
+        optPackFilename = currArg;
+    }
+    else
     if (nsrcFilenames < SET_MAX_FILES)
     {
         srcFilenames[nsrcFilenames++] = currArg;
@@ -612,8 +639,7 @@
 
 BOOL dmCheckExcluded(const char *filename)
 {
-    int i;
-    for (i = 0; i < nexcFilenames; i++)
+    for (int i = 0; i < nexcFilenames; i++)
     {
         if (dmStrMatch(filename, excFilenames[i]))
             return TRUE;
@@ -624,30 +650,31 @@
 
 int main(int argc, char *argv[])
 {
-    int i, res = 0;
+    int res = 0;
     DMPackFile *pack = NULL;
 
     // Parse arguments
-    dmInitProg("packed", "Pack File Editor", "0.5", NULL, NULL);
+    dmInitProg("packed", "Pack File Editor", "0.7", NULL, NULL);
     dmVerbosity = 0;
 
     if (!dmArgsProcess(argc, argv, optList, optListN,
-        argHandleOpt, argHandleFile, OPTH_BAILOUT))
+        argHandleOpt, argHandleNonOpt, OPTH_BAILOUT))
         exit(1);
 
-    // Check PACK filename
-    if (optPackFilename == NULL)
-        optPackFilename = SET_DEFAULT_PACK;
-
     if (optCommand == CMD_NONE)
     {
-        argShowHelp();
-        dmErrorMsg("Nothing to do.\n");
-        exit(0);
-        return 0;
+        dmErrorMsg("Nothing to do. Perhaps try \"%s --help\"?\n",
+            dmProgName);
+        goto error;
     }
 
-    dmMsg(1, "Processing %s ...\n", optPackFilename);
+    if (optPackFilename == NULL)
+    {
+        dmErrorMsg("No PACK file specified.\n");
+        goto error;
+    }
+
+    dmMsg(1, "Processing PACK '%s' ...\n", optPackFilename);
 
     // Execute command
     switch (optCommand)
@@ -672,7 +699,7 @@
         {
             dmMsg(1, "Adding files...\n");
 
-            for (i = 0; i < nsrcFilenames; i++)
+            for (int i = 0; i < nsrcFilenames; i++)
             if (!dmCheckExcluded(srcFilenames[i]))
             {
                 DMPackEntry *node = NULL;
@@ -693,8 +720,8 @@
                 }
             }
 
-            dmMsg(1, "w=%d\n", dmPackWrite(pack));
-            dmMsg(1, "c=%d\n", dmPackClose(pack));
+            dmMsg(2, "w=%d\n", dmPackWrite(pack));
+            dmMsg(2, "c=%d\n", dmPackClose(pack));
         }
         else
         {
@@ -709,8 +736,10 @@
         if (res == DMERR_OK)
         {
             DMPackEntry *node;
+            int i;
             for (i = 0, node = pack->entries; node; i++)
                 node = node->next;
+
             dmMsg(1, "%d files total\n", i);
 
             dmPrint(0, "%-32s | %8s | %8s | %8s | %s\n",
@@ -724,7 +753,7 @@
                 if (nsrcFilenames > 0)
                 {
                     match = FALSE;
-                    for (i = 0; i < nsrcFilenames && !match; i++)
+                    for (int i = 0; i < nsrcFilenames && !match; i++)
                         match = dmStrMatch(node->filename, srcFilenames[i]);
                 }
                 else
@@ -739,7 +768,7 @@
                 }
             }
 
-            dmMsg(1, "c=%d\n", dmPackClose(pack));
+            dmMsg(2, "c=%d\n", dmPackClose(pack));
         }
         else
             dmErrorMsg("Could not open packfile, error #%d: %s\n", res,
@@ -768,7 +797,7 @@
                 if (nsrcFilenames > 0)
                 {
                     match = FALSE;
-                    for (i = 0; (i < nsrcFilenames) && !match; i++)
+                    for (int i = 0; i < nsrcFilenames && !match; i++)
                     {
                         if (dmStrMatch(node->filename, srcFilenames[i]) &&
                             !dmCheckExcluded(node->filename))
@@ -794,7 +823,7 @@
                 }
             }
 
-            dmMsg(1, "c=%d\n", dmPackClose(pack));
+            dmMsg(2, "c=%d\n", dmPackClose(pack));
 
             if (resFile != NULL)
                 fclose(resFile);
@@ -803,8 +832,8 @@
             dmErrorMsg("Could not open packfile, error #%d: %s\n", res,
                   dmErrorStr(res));
         break;
-
     }
 
+error:
     return 0;
 }