From 76bcaba6011b4a3a3f2c3dcd65e3438bb46b79f0 Mon Sep 17 00:00:00 2001 From: truelight Date: Thu, 24 Aug 2006 12:08:25 +0000 Subject: [PATCH] (svn r6089) -Backport r6088: added -s (source) and -d (destination) to strgen (Darkvater) --- Makefile | 8 +-- langs.vcproj | 52 +++++++++---------- langs_vs80.vcproj | 52 +++++++++---------- strgen/strgen.c | 129 ++++++++++++++++++++++++++++++++-------------- string.c | 26 +++++++++- win32.c | 21 -------- 6 files changed, 170 insertions(+), 118 deletions(-) diff --git a/Makefile b/Makefile index 379f92ab20..9d73e5a093 100644 --- a/Makefile +++ b/Makefile @@ -879,17 +879,17 @@ $(TTD): $(OBJS) $(MAKE_CONFIG) $(Q)$(CXX_TARGET) $(LDFLAGS) $(TTDLDFLAGS) $(OBJS) $(LIBS) -o $@ endif -$(STRGEN): strgen/strgen.c endian_host.h +$(STRGEN): strgen/strgen.c string.c endian_host.h @echo '===> Compiling and Linking $@' - $(Q)$(CC_HOST) $(CFLAGS_HOST) $(CDEFS) $< -o $@ + $(Q)$(CC_HOST) $(CFLAGS_HOST) -DSTRGEN strgen/strgen.c string.c -o $@ table/strings.h: lang/english.txt $(STRGEN) @echo '===> Generating $@' - $(Q)$(STRGEN) + $(Q)$(STRGEN) -s lang -d table lang/%.lng: lang/%.txt $(STRGEN) lang/english.txt @echo '===> Compiling language $(*F)' - $(Q)$(STRGEN) $(STRGEN_FLAGS) $< $(LANG_ERRORS) || rm -f $@ + $(Q)$(STRGEN) $(STRGEN_FLAGS) -s lang -d lang $< $(LANG_ERRORS) || rm -f $@ # stupid KUDr doesn't know how to setup unittest dependencies (so rm,cp,rm) # please don't blame him and repair it: diff --git a/langs.vcproj b/langs.vcproj index 5633d4a100..db053ccf99 100644 --- a/langs.vcproj +++ b/langs.vcproj @@ -31,7 +31,7 @@ + CommandLine="strgen\debug\strgen.exe -s lang -d table"/> @@ -44,7 +44,7 @@ @@ -56,7 +56,7 @@ @@ -68,7 +68,7 @@ @@ -80,7 +80,7 @@ @@ -92,7 +92,7 @@ @@ -104,7 +104,7 @@ @@ -116,7 +116,7 @@ @@ -128,7 +128,7 @@ @@ -139,7 +139,7 @@ @@ -151,7 +151,7 @@ @@ -163,7 +163,7 @@ @@ -175,7 +175,7 @@ @@ -187,7 +187,7 @@ @@ -199,7 +199,7 @@ @@ -211,7 +211,7 @@ @@ -224,7 +224,7 @@ @@ -236,7 +236,7 @@ @@ -248,7 +248,7 @@ @@ -260,7 +260,7 @@ @@ -272,7 +272,7 @@ @@ -284,7 +284,7 @@ @@ -296,7 +296,7 @@ @@ -308,7 +308,7 @@ @@ -320,7 +320,7 @@ @@ -332,7 +332,7 @@ diff --git a/langs_vs80.vcproj b/langs_vs80.vcproj index 31f5c3c363..e7c7e5ae4c 100644 --- a/langs_vs80.vcproj +++ b/langs_vs80.vcproj @@ -27,7 +27,7 @@ @@ -68,7 +68,7 @@ @@ -82,7 +82,7 @@ @@ -96,7 +96,7 @@ @@ -110,7 +110,7 @@ @@ -124,7 +124,7 @@ @@ -138,7 +138,7 @@ @@ -152,7 +152,7 @@ @@ -166,7 +166,7 @@ @@ -180,7 +180,7 @@ @@ -194,7 +194,7 @@ @@ -208,7 +208,7 @@ @@ -222,7 +222,7 @@ @@ -236,7 +236,7 @@ @@ -250,7 +250,7 @@ @@ -265,7 +265,7 @@ @@ -279,7 +279,7 @@ @@ -293,7 +293,7 @@ @@ -307,7 +307,7 @@ @@ -321,7 +321,7 @@ @@ -335,7 +335,7 @@ @@ -349,7 +349,7 @@ @@ -363,7 +363,7 @@ @@ -377,7 +377,7 @@ @@ -391,7 +391,7 @@ diff --git a/strgen/strgen.c b/strgen/strgen.c index 6fbccfb242..1bf6cf9847 100644 --- a/strgen/strgen.c +++ b/strgen/strgen.c @@ -1,9 +1,14 @@ /* $Id$ */ -#define STRGEN +#if defined(WIN32) || defined(WIN64) || defined(__CYGWIN__) +#define WIN32 +#else +#define UNIX +#endif #include "../stdafx.h" #include "../macros.h" +#include "../string.h" #include #include #include @@ -13,12 +18,16 @@ #include #endif +#if defined WIN32 || defined __WATCOMC__ +#include +#endif /* WIN32 || __WATCOMC__ */ + #ifdef __MORPHOS__ #ifdef stderr #undef stderr #endif #define stderr stdout -#endif // __MORPHOS__ +#endif /* __MORPHOS__ */ #ifdef __WATCOMC__ uint _map_log_x; // an unpleasant hack required because Watcom is insisting on @@ -26,7 +35,7 @@ uint _map_size_y; uint _map_tile_mask; uint _map_size; -#endif +#endif /* __WATCOMC__ */ /* Compiles a list of strings into a compiled string list */ @@ -160,7 +169,7 @@ static void CDECL Warning(const char *s, ...) char buf[1024]; va_list va; va_start(va, s); - vsprintf(buf, s, va); + vsnprintf(buf, lengthof(buf), s, va); va_end(va); fprintf(stderr, "%s" LINE_NUM_FMT ": Warning: %s\n", _file, _cur_line, buf); _warnings++; @@ -172,7 +181,7 @@ static void CDECL Error(const char *s, ...) char buf[1024]; va_list va; va_start(va, s); - vsprintf(buf, s, va); + vsnprintf(buf, lengthof(buf), s, va); va_end(va); fprintf(stderr, "%s" LINE_NUM_FMT ": Error: %s\n", _file, _cur_line, buf); _errors++; @@ -184,21 +193,12 @@ static void NORETURN CDECL Fatal(const char *s, ...) char buf[1024]; va_list va; va_start(va, s); - vsprintf(buf, s, va); + vsnprintf(buf, lengthof(buf), s, va); va_end(va); fprintf(stderr, "%s" LINE_NUM_FMT ": FATAL: %s\n", _file, _cur_line, buf); exit(1); } - -static void ttd_strlcpy(char *dst, const char *src, size_t len) -{ - assert(len > 0); - while (--len > 0 && *src != '\0') *dst++ = *src++; - *dst = '\0'; -} - - static void PutByte(byte c) { if (_put_pos == lengthof(_put_buf)) Fatal("Put buffer too small"); @@ -1205,9 +1205,36 @@ static void WriteLangfile(const char *filename, int show_todo) fclose(f); } +/** Multi-OS mkdirectory function */ +static inline void ottd_mkdir(const char *directory) +{ +#if defined(WIN32) || defined(__WATCOMC__) + mkdir(directory); +#else + mkdir(directory, 0755); +#endif +} + +/** Create a path consisting of an already existing path, a possible + * path seperator and the filename. The seperator is only appended if the path + * does not already end with a seperator */ +static inline char *mkpath(char *buf, size_t buflen, const char *path, const char *file) +{ + char *p; + ttd_strlcpy(buf, path, buflen); // copy directory into buffer + + p = strchr(buf, '\0'); // add path seperator if necessary + if (p[-1] != PATHSEPCHAR && (size_t)(p - buf) + 1 < buflen) *p++ = PATHSEPCHAR; + ttd_strlcpy(p, file, buflen - (size_t)(p - buf)); // catenate filename at end of buffer + return buf; +} + int CDECL main(int argc, char* argv[]) { + char pathbuf[256]; + const char *src_dir, *dest_dir; + int show_todo = 0; if (argc > 1 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { @@ -1215,14 +1242,12 @@ int CDECL main(int argc, char* argv[]) return 0; } - if (argc > 1 && - (strcmp(argv[1], "-t") == 0 || strcmp(argv[1], "--todo") == 0)) { + if (argc > 1 && (strcmp(argv[1], "-t") == 0 || strcmp(argv[1], "--todo") == 0)) { show_todo = 1; argc--, argv++; } - if (argc > 1 && - (strcmp(argv[1], "-w") == 0 || strcmp(argv[1], "--warning") == 0)) { + if (argc > 1 && (strcmp(argv[1], "-w") == 0 || strcmp(argv[1], "--warning") == 0)) { show_todo = 2; argc--, argv++; } @@ -1235,45 +1260,69 @@ int CDECL main(int argc, char* argv[]) puts( "strgen - $Revision$\n" " -v | --version print version information and exit\n" - " -h | -? | --help print this help message and exit\n" " -t | --todo replace any untranslated strings with ''\n" " -w | --warning print a warning for any untranslated strings\n" - " Run without parameters strgen will search for lang/english.txt and\n" - " parse it. Passing an argument, strgen will translate that language\n" - " file with lang/english.txt as a reference." + " -h | -? | --help print this help message and exit\n" + " -s | --source_dir search for english.txt in the specified directory\n" + " -d | --dest_dir put output file in the specified directory, create if needed\n" + " Run without parameters and strgen will search for english.txt and parse it,\n" + " creating strings.h. Passing an argument, strgen will translate that language\n" + " file using english.txt as a reference and output .lng." ); return 0; } + src_dir = dest_dir = "."; + if (argc > 2 && (strcmp(argv[1], "-s") == 0 || strcmp(argv[1], "--source_dir") == 0)) { + src_dir = dest_dir = argv[2]; // if dest_dir is not specified, it equals src_dir + argc -= 2, argv += 2; + } + + if (argc > 2 && (strcmp(argv[1], "-d") == 0 || strcmp(argv[1], "--dest_dir") == 0)) { + dest_dir = argv[2]; + argc -= 2, argv += 2; + } + + /* strgen has two modes of operation. If no (free) arguments are passed + * strgen generates strings.h to the destination directory. If it is supplied + * with a (free) parameter the program will translate that language to destination + * directory. As input english.txt is parsed from the source directory */ if (argc == 1) { + mkpath(pathbuf, lengthof(pathbuf), src_dir, "english.txt"); + + /* parse master file */ _masterlang = true; - // parse master file - ParseFile("lang/english.txt", true); + ParseFile(pathbuf, true); MakeHashOfStrings(); if (_errors) return 1; - // write english.lng and strings.h - - WriteLangfile("lang/english.lng", 0); - WriteStringsH("table/strings.h"); + /* write strings.h */ + ottd_mkdir(dest_dir); + mkpath(pathbuf, lengthof(pathbuf), dest_dir, "strings.h"); + WriteStringsH(pathbuf); } else if (argc == 2) { - char buf[256]; - char* r; + char *r; + mkpath(pathbuf, lengthof(pathbuf), src_dir, "english.txt"); + + /* parse master file and check if target file is correct */ _masterlang = false; - ParseFile("lang/english.txt", true); + ParseFile(pathbuf, true); MakeHashOfStrings(); - ParseFile(argv[1], false); - + ParseFile(argv[1], false); // target file if (_errors) return 1; - strcpy(buf, argv[1]); - r = strrchr(buf, '.'); - if (r == NULL || strcmp(r, ".txt") != 0) r = strchr(buf, 0); - strcpy(r, ".lng"); - WriteLangfile(buf, show_todo); + /* get the targetfile, strip any directories and append to destination path */ + r = strrchr(argv[1], PATHSEPCHAR); + mkpath(pathbuf, lengthof(pathbuf), dest_dir, (r != NULL) ? &r[1] : argv[1]); + + /* rename the .txt (input-extension) to .lng */ + r = strrchr(pathbuf, '.'); + if (r == NULL || strcmp(r, ".txt") != 0) r = strchr(pathbuf, '\0'); + ttd_strlcpy(r, ".lng", (size_t)(r - pathbuf)); + WriteLangfile(pathbuf, show_todo); } else { - fprintf(stderr, "invalid arguments\n"); + fprintf(stderr, "Invalid arguments\n"); } return 0; diff --git a/string.c b/string.c index bbf8627d3d..a0e6b42a64 100644 --- a/string.c +++ b/string.c @@ -52,7 +52,7 @@ char* CDECL str_fmt(const char* str, ...) char* p; va_start(va, str); - len = vsprintf(buf, str, va); + len = vsnprintf(buf, lengthof(buf), str, va); va_end(va); p = malloc(len + 1); if (p != NULL) memcpy(p, buf, len + 1); @@ -101,3 +101,27 @@ void strtolower(char *str) { for (; *str != '\0'; str++) *str = tolower(*str); } + +#ifdef WIN32 +int CDECL snprintf(char *str, size_t size, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = vsnprintf(str, size, format, ap); + va_end(ap); + return ret; +} + +#ifdef _MSC_VER +int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + int ret; + ret = _vsnprintf(str, size, format, ap); + if (ret < 0) str[size - 1] = '\0'; + return ret; +} +#endif /* _MSC_VER */ + +#endif /* WIN32 */ diff --git a/win32.c b/win32.c index 6c692dced7..4070f8546c 100644 --- a/win32.c +++ b/win32.c @@ -917,27 +917,6 @@ void DeterminePaths(void) CreateDirectory(_path.heightmap_dir, NULL); } -int CDECL snprintf(char *str, size_t size, const char *format, ...) -{ - va_list ap; - int ret; - - va_start(ap, format); - ret = vsnprintf(str, size, format, ap); - va_end(ap); - return ret; -} - -#ifdef _MSC_VER -int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap) -{ - int ret; - ret = _vsnprintf(str, size, format, ap); - if (ret < 0) str[size - 1] = '\0'; - return ret; -} -#endif - /** * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard * and append this up to the maximum length (either absolute or screenlength). If maxlength