Mercurial > hg > batmud > maputils
view diffmap.c @ 945:81184d58133c aprilli2011
Sync.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 14 May 2010 11:18:20 +0000 |
parents | 304a50a9d51f |
children | 82469eecbae7 |
line wrap: on
line source
/* * diffmap - Compute 'diff' between two maps * Programmed by Matti 'ccr' Hämäläinen (Ggr Pupunen) * (C) Copyright 2006-2008 Tecnic Software productions (TNSP) */ #include "maputils.h" #include "th_util.h" #include "th_args.h" #include "th_string.h" #include <string.h> #define DEF_FILTER "C?%" char *srcFilename1 = NULL, *srcFilename2 = NULL, *destFilename = NULL; BOOL optUseOldFormat = FALSE, optAlwaysDiff = FALSE; char *optFilter1 = "", *optFilter2 = DEF_FILTER; /* Arguments */ optarg_t optList[] = { { 0, '?', "help", "Show this help", OPT_NONE }, { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, { 2, 'q', "quiet", "Be quiet", OPT_NONE }, { 3, 'O', "old-format", "Input using old symbols/colors", OPT_NONE }, { 4, 'o', "output", "Output filename", OPT_ARGREQ }, { 5, 'F', NULL, "Filter chars (none) for mapfile #1", OPT_ARGREQ }, { 6, 'f', NULL, "Filter chars (" DEF_FILTER ") for mapfile #2", OPT_ARGREQ }, { 7, 'a', "always", "Always output diff file even when no changes", OPT_NONE }, }; const int optListN = (sizeof(optList) / sizeof(optarg_t)); void argShowHelp(void) { th_args_help(stderr, optList, optListN, th_prog_name, "[options] <mapfile #1> <mapfile #2>"); } BOOL argHandleOpt(const int optN, char *optArg, char *currArg) { switch (optN) { case 0: argShowHelp(); exit(0); break; case 1: th_verbosityLevel++; break; case 2: th_verbosityLevel = -1; break; case 3: optUseOldFormat = TRUE; THMSG(2, "Input is using old map symbols/colors.\n"); break; case 4: destFilename = optArg; THMSG(2, "Output file set to '%s'.\n", optArg); break; case 5: optFilter1 = optArg; THMSG(2, "Filter characters for mapfile #1 set to'%s'.\n", optArg); break; case 6: optFilter2 = optArg; THMSG(2, "Filter characters for mapfile #2 set to'%s'.\n", optArg); break; case 7: optAlwaysDiff = TRUE; THMSG(2, "Outputting diff file even with no changes.\n"); break; default: THERR("Unknown option '%s'.\n", currArg); return FALSE; } return TRUE; } BOOL argHandleFile(char *currArg) { if (!srcFilename1) srcFilename1 = currArg; else if (!srcFilename2) srcFilename2 = currArg; else { THERR("Too many input map files specified!\n"); return FALSE; } return TRUE; } mapblock_t * diffBlocks(mapblock_t *map1, mapblock_t *map2, BOOL useOld, char *filter1, char *filter2, size_t *count) { int x, y; mapblock_t *res; unsigned char *p1, *p2, *pd; if (map1->w != map2->w || map1->h != map2->h) { THERR("Mapblock size mismatch (%d, %d) vs (%d, %d)\n", map1->w, map1->h, map2->w, map2->h); return NULL; } if ((res = allocBlock(map1->w, map1->h)) == NULL) { THERR("Could not allocate mapblock (%d, %d)\n", map1->w, map1->h); return NULL; } p1 = map1->d; p2 = map2->d; pd = (unsigned char *) res->d; *count = 0; for (y = 0; y < map1->h; y++) for (x = 0; x < map1->w; x++) { int c; if (*p1 != *p2 && !strchr(filter1, *p1) && !strchr(filter2, *p2)) { c = mcGet(*p2, useOld, FALSE); if (c < 0) *pd = 0xfd; else *pd = c | 64; THMSG(2, "[%d,%d]: %d -> %d\n", x+1, y+1, *p1, *p2); (*count)++; } else { c = mcGet(*p1, useOld, FALSE); if (c < 0) *pd = 0xfd; else *pd = c; } p1++; p2++; pd++; } return res; } int main(int argc, char *argv[]) { mapblock_t *map1, *map2, *res; FILE *outFile; size_t count; /* Initialize */ th_init("diffmap", "Create a diff between two ASCII mapfiles", "0.5", NULL, NULL); th_verbosityLevel = 1; /* Parse arguments */ if (!th_args_process(argc, argv, optList, optListN, argHandleOpt, argHandleFile, TRUE)) exit(1); if (srcFilename1 == NULL || srcFilename2 == NULL) { THERR("Nothing to do. (try --help)\n"); exit(0); } /* Read mapfiles */ if ((map1 = parseFile(srcFilename1, FALSE)) == NULL) exit(2); if ((map2 = parseFile(srcFilename2, FALSE)) == NULL) exit(2); /* Compute and output data */ count = 0; if ((res = diffBlocks(map1, map2, optUseOldFormat, optFilter1, optFilter2, &count)) == NULL) { THERR("Could not create diff between inputs!\n"); exit(3); } THMSG(1, "%ld differences.\n", count); /* Open output file */ if (optAlwaysDiff || count > 0) { THMSG(2, "Outputting map %d x %d...\n", res->w, res->h); if (destFilename == NULL) outFile = stdout; else if ((outFile = fopen(destFilename, "wb")) == NULL) { THERR("Error opening output file '%s'!\n", destFilename); exit(1); } fprintf(outFile, DIFF_MAGIC "%d\n", DIFF_VERSION); printBlockRaw(outFile, res); fclose(outFile); } else { THMSG(2, "Not outputting diff because of no changes found.\n"); } exit(count); return count; }