From: <Mee...@us...> - 2007-06-03 17:56:54
|
Revision: 2771 http://sc2.svn.sourceforge.net/sc2/?rev=2771&view=rev Author: Meep-Eep Date: 2007-06-03 10:56:51 -0700 (Sun, 03 Jun 2007) Log Message: ----------- Resource ID printing program. Useful for scripts. Modified Paths: -------------- trunk/tools/shared/util.c trunk/tools/shared/util.h Added Paths: ----------- trunk/tools/resid/ trunk/tools/resid/Makefile trunk/tools/resid/resid.c Added: trunk/tools/resid/Makefile =================================================================== --- trunk/tools/resid/Makefile (rev 0) +++ trunk/tools/resid/Makefile 2007-06-03 17:56:51 UTC (rev 2771) @@ -0,0 +1,9 @@ +TARGET := resid +CFILES := ../shared/util.c resid.c +HFILES := ../shared/util.h +CFLAGS := -std=c99 +DEBUG := 1 +#ERROR := 1 + +include ../shared/Makefile.default + Added: trunk/tools/resid/resid.c =================================================================== --- trunk/tools/resid/resid.c (rev 0) +++ trunk/tools/resid/resid.c 2007-06-03 17:56:51 UTC (rev 2771) @@ -0,0 +1,249 @@ +/* + * Print a resource ID. By Serge van den Boom (sv...@st...) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <getopt.h> +#include <inttypes.h> + +#include "../shared/util.h" + +typedef uint32_t RESOURCE; +typedef uint16_t RES_PACKAGE; +typedef uint16_t RES_INSTANCE; +typedef uint16_t RES_TYPE; + +#define TYPE_BITS 8 +#define INSTANCE_BITS 13 +#define PACKAGE_BITS 11 + +#define GET_TYPE(res) \ + ((RES_TYPE)(res) & (RES_TYPE)((1 << TYPE_BITS) - 1)) +#define GET_INSTANCE(res) \ + ((RES_INSTANCE)((res) >> TYPE_BITS) & ((1 << INSTANCE_BITS) - 1)) +#define GET_PACKAGE(res) \ + ((RES_PACKAGE)((res) >> (TYPE_BITS + INSTANCE_BITS)) & \ + ((1 << PACKAGE_BITS) - 1)) +#define MAKE_RESOURCE(p,t,i) \ + (((RESOURCE)(p) << (TYPE_BITS + INSTANCE_BITS)) | \ + ((RESOURCE)(i) << TYPE_BITS) | \ + ((RESOURCE)(t))) + +void usage(FILE *out); +int printResource(FILE *out, const char *format, RESOURCE res); + +int +main(int argc, char *argv[]) { + char ch; + RESOURCE res = 0; + const char *format = "RESID=0x%08R PACKAGE=%p (0x%04P) " + "INSTANCE=%i (0x%04I) TYPE=%t (0x%02T)\n"; + + for (;;) { + ch = getopt(argc, argv, "f:hi:p:r:t:"); + if (ch == -1) + break; + switch(ch) { + case 'f': + // format + format = optarg; + break; + case 'r': { + // resource + uint32_t temp; + if (parseU32(optarg, 0, &temp) == -1) { + fprintf(stderr, "Invalid resource for -r.\n"); + exit(EXIT_FAILURE); + } + res = temp; + break; + } + case 'p': { + // package + uint16_t temp; + if (parseU16(optarg, 0, &temp) == -1) { + fprintf(stderr, "Invalid package for -p.\n"); + exit(EXIT_FAILURE); + } + res = MAKE_RESOURCE(temp, GET_TYPE(res), GET_INSTANCE(res)); + break; + } + case 'i': { + // instance + uint16_t temp; + if (parseU16(optarg, 0, &temp) == -1) { + fprintf(stderr, "Invalid instance for -i.\n"); + exit(EXIT_FAILURE); + } + res = MAKE_RESOURCE(GET_PACKAGE(res), GET_TYPE(res), temp); + break; + } + case 't': { + // type + uint16_t temp; + if (parseU16(optarg, 0, &temp) == -1) { + fprintf(stderr, "Invalid type for -t.\n"); + exit(EXIT_FAILURE); + } + res = MAKE_RESOURCE(GET_PACKAGE(res), temp, GET_INSTANCE(res)); + break; + } + case '?': + case 'h': + usage(stdout); + return EXIT_SUCCESS; + default: + usage(stderr); + exit(EXIT_FAILURE); + } + } + argc -= optind; + argv += optind; + if (argc != 0) { + fprintf(stderr, "Error: Extra arguments passed.\n"); + usage(stderr); + exit(EXIT_FAILURE); + } + + (void) printResource(stdout, format, res); + + return EXIT_SUCCESS; +} + +void +usage(FILE *out) { + fprintf(out, "Usage: resid [-f format] [-r resource] [-p package] [-i" + "instance] [-t type]\n" + "\t-f Format to print the resource:\n" + "\t %%r - resource (decimal)\n" + "\t %%R - resource (hexadecimal)\n" + "\t %%i - instance (decimal)\n" + "\t %%I - instance (hexadecimal)\n" + "\t %%t - type (decimal)\n" + "\t %%T - type (hexadecimal)\n" + "\t %%%% - literal '%%'\n" + "\t-r resource to print\n" + "\t-p package part of the resource to print\n" + "\t-i instance part of the resource to print\n" + "\t-t type part of the resource to print\n"); +} + +int +printResource(FILE *out, const char *format, RESOURCE res) { + int result = 0; + + const char *ptr = format; + for (;;) { + const char *lastEnd = ptr; + ptr += strcspn(ptr, "%\\"); + + if (lastEnd != ptr) { + // Print literal text skipped since the last % pattern. + result += fwrite(lastEnd, 1, ptr - lastEnd, out); + } + + if (*ptr == '\0') + break; + + if (*ptr == '\\') { + // Escape a character. + ptr++; + if (*ptr == '\0') + break; + + char ch = *ptr; + switch (ch) { + case 'n': + ch = '\n'; + break; + case 'r': + ch = '\r'; + break; + case 't': + ch = '\t'; + break; + default: + break; + } + fputc(ch, out); + result++; + } + + // ptr == '%" + ptr++; + + if (*ptr == '%') { + // Literal %. + fputc('%', out); + ptr++; + result++; + continue; + } + + // Parse the width + long width = 0; + char *widthEnd; + width = strtol(ptr, &widthEnd, 10); + ptr = widthEnd; + + switch (*ptr) { + case 'r': + result += fprintf(out, "%0*" PRIu32, (int) width, res); + break; + case 'R': + result += fprintf(out, "%0*" PRIx32, (int) width, res); + break; + case 'p': + result += fprintf(out, "%0*" PRIu16, (int) width, + GET_PACKAGE(res)); + break; + case 'P': + result += fprintf(out, "%0*" PRIx16, (int) width, + GET_PACKAGE(res)); + break; + case 'i': + result += fprintf(out, "%0*" PRIu16, (int) width, + GET_INSTANCE(res)); + break; + case 'I': + result += fprintf(out, "%0*" PRIx16, (int) width, + GET_INSTANCE(res)); + break; + case 't': + result += fprintf(out, "%0*" PRIu16, (int) width, + GET_TYPE(res)); + break; + case 'T': + result += fprintf(out, "%0*" PRIx16, (int) width, + GET_TYPE(res)); + break; + case '\0': + continue; + default: + fputc(*ptr, out); + result++; + break; + } + ptr++; + } + + return 0; +} + Modified: trunk/tools/shared/util.c =================================================================== --- trunk/tools/shared/util.c 2007-06-01 18:41:10 UTC (rev 2770) +++ trunk/tools/shared/util.c 2007-06-03 17:56:51 UTC (rev 2771) @@ -114,4 +114,203 @@ return -1; } +// Use base '0' for any base. +// returns 0 if the entire string is ok. +int +parseU8(const char *str, int base, uint8_t *result) { + char *endPtr; + unsigned long temp; + if (str[0] == '\0') + { + errno = EINVAL; + return -1; + } + + errno = 0; + temp = strtoul (str, &endPtr, base); + if (errno != 0) + return -1; + + if (*endPtr != '\0') + { + errno = EINVAL; + return -1; + } + + if (temp > UINT8_MAX) { + errno = ERANGE; + return -1; + } + + *result = (uint8_t) temp; + return 0; +} + +// Use base '0' for any base. +// returns 0 if the entire string is ok. +int +parseS8(const char *str, int base, int8_t *result) { + char *endPtr; + long temp; + + if (str[0] == '\0') + { + errno = EINVAL; + return -1; + } + + errno = 0; + temp = strtol (str, &endPtr, base); + if (errno != 0) + return -1; + + if (*endPtr != '\0') + { + errno = EINVAL; + return -1; + } + + if (temp < INT8_MIN || temp > INT8_MAX) { + errno = ERANGE; + return -1; + } + + *result = (int8_t) temp; + return 0; +} + +// Use base '0' for any base. +// returns 0 if the entire string is ok. +int +parseU16(const char *str, int base, uint16_t *result) { + char *endPtr; + unsigned long temp; + + if (str[0] == '\0') + { + errno = EINVAL; + return -1; + } + + errno = 0; + temp = strtoul (str, &endPtr, base); + if (errno != 0) + return -1; + + if (*endPtr != '\0') + { + errno = EINVAL; + return -1; + } + + if (temp > UINT16_MAX) { + errno = ERANGE; + return -1; + } + + *result = (uint16_t) temp; + return 0; +} + +// Use base '0' for any base. +// returns 0 if the entire string is ok. +int +parseS16(const char *str, int base, int16_t *result) { + char *endPtr; + long temp; + + if (str[0] == '\0') + { + errno = EINVAL; + return -1; + } + + errno = 0; + temp = strtol (str, &endPtr, base); + if (errno != 0) + return -1; + + if (*endPtr != '\0') + { + errno = EINVAL; + return -1; + } + + if (temp < INT16_MIN || temp > INT16_MAX) { + errno = ERANGE; + return -1; + } + + *result = (int16_t) temp; + return 0; +} + +// Use base '0' for any base. +// returns 0 if the entire string is ok. +int +parseU32(const char *str, int base, uint32_t *result) { + char *endPtr; + unsigned long temp; + + if (str[0] == '\0') + { + errno = EINVAL; + return -1; + } + + errno = 0; + temp = strtoul (str, &endPtr, base); + if (errno != 0) + return -1; + + if (*endPtr != '\0') + { + errno = EINVAL; + return -1; + } + + if (temp > UINT32_MAX) { + errno = ERANGE; + return -1; + } + + *result = (uint32_t) temp; + return 0; +} + +// Use base '0' for any base. +// returns 0 if the entire string is ok. +int +parseS32(const char *str, int base, int32_t *result) { + char *endPtr; + long temp; + + if (str[0] == '\0') + { + errno = EINVAL; + return -1; + } + + errno = 0; + temp = strtol (str, &endPtr, base); + if (errno != 0) + return -1; + + if (*endPtr != '\0') + { + errno = EINVAL; + return -1; + } + + if (temp < INT32_MIN || temp > INT32_MAX) { + errno = ERANGE; + return -1; + } + + *result = (int32_t) temp; + return 0; +} + + + Modified: trunk/tools/shared/util.h =================================================================== --- trunk/tools/shared/util.h 2007-06-01 18:41:10 UTC (rev 2770) +++ trunk/tools/shared/util.h 2007-06-03 17:56:51 UTC (rev 2771) @@ -20,6 +20,7 @@ #include <stdarg.h> #include <stdbool.h> #include <sys/types.h> +#include <stdint.h> void logError(bool useErrno, const char *format, ...) @@ -30,6 +31,12 @@ int mmapOpen(const char *fileName, int flags, void **buf, size_t *len); +int parseU8(const char *str, int base, uint8_t *res); +int parseS8(const char *str, int base, int8_t *res); +int parseU16(const char *str, int base, uint16_t *res); +int parseS16(const char *str, int base, int16_t *res); +int parseU32(const char *str, int base, uint32_t *res); +int parseS32(const char *str, int base, int32_t *res); #endif /* _UTIL_H */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |