diff --git a/include/extern/getopt.h b/include/extern/getopt.h index 4eead270..ec0db21f 100644 --- a/include/extern/getopt.h +++ b/include/extern/getopt.h @@ -1,5 +1,5 @@ /* - * Copyright © 2005-2019 Rich Felker, et al. + * Copyright © 2005-2020 Rich Felker, et al. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -23,8 +23,8 @@ /* This implementation was taken from musl and modified for RGBDS */ -#ifndef _GETOPT_H -#define _GETOPT_H +#ifndef RGBDS_EXTERN_GETOPT_H +#define RGBDS_EXTERN_GETOPT_H extern char *optarg; extern int optind, opterr, optopt, optreset; diff --git a/include/hashmap.h b/include/hashmap.h index 1b5abbc0..fddb0eae 100644 --- a/include/hashmap.h +++ b/include/hashmap.h @@ -15,7 +15,7 @@ #define HASH_NB_BITS 32 #define HALF_HASH_NB_BITS 16 -_Static_assert(HALF_HASH_NB_BITS * 2 == HASH_NB_BITS, ""); +static_assert(HALF_HASH_NB_BITS * 2 == HASH_NB_BITS, ""); #define HASHMAP_NB_BUCKETS (1 << HALF_HASH_NB_BITS) /* HashMapEntry is internal, please do not attempt to use it */ diff --git a/include/platform.h b/include/platform.h new file mode 100644 index 00000000..6c6170d6 --- /dev/null +++ b/include/platform.h @@ -0,0 +1,35 @@ +/* + * This file is part of RGBDS. + * + * Copyright (c) 2020 RGBDS contributors. + * + * SPDX-License-Identifier: MIT + */ + +/* platform-specific hacks */ + +#ifndef RGBDS_PLATFORM_H +#define RGBDS_PLATFORM_H + +/* MSVC doesn't have strncasecmp, use a suitable replacement */ +#ifdef _MSC_VER +# include +# define strncasecmp _strnicmp +#else +# include +#endif + +/* MSVC has deprecated strdup in favor of _strdup */ +#ifdef _MSC_VER +# define strdup _strdup +#endif + +/* MSVC prefixes the names of S_* macros with underscores, + and doesn't define any S_IS* macros. Define them ourselves */ +#ifdef _MSC_VER +# define S_IFMT _S_IFMT +# define S_IFDIR _S_IFDIR +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif + +#endif /* RGBDS_PLATFORM_H */ diff --git a/src/asm/asmy.y b/src/asm/asmy.y index da6b7b4c..d51e683c 100644 --- a/src/asm/asmy.y +++ b/src/asm/asmy.y @@ -15,7 +15,6 @@ #include #include #include -#include #include "asm/asm.h" #include "asm/charmap.h" @@ -34,6 +33,7 @@ #include "extern/utf8decoder.h" #include "linkdefs.h" +#include "platform.h" // strncasecmp, strdup uint32_t nListCountEmpty; char *tzNewMacro; diff --git a/src/asm/fstack.c b/src/asm/fstack.c index ca8e675c..f984c725 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "asm/fstack.h" #include "asm/lexer.h" @@ -30,6 +29,7 @@ #include "extern/err.h" +#include "platform.h" // S_ISDIR (stat macro) #include "types.h" static struct sContext *pFileStack; diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 0c567f63..cb993aaa 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "asm/asm.h" #include "asm/fstack.h" @@ -27,6 +26,7 @@ #include "extern/err.h" #include "asmy.h" +#include "platform.h" // strncasecmp, strdup struct sLexString { char *tzName; diff --git a/src/asm/output.c b/src/asm/output.c index 7954fdf1..163ce694 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -30,6 +30,7 @@ #include "extern/err.h" #include "linkdefs.h" +#include "platform.h" // strdup struct Patch { char tzFilename[_MAX_PATH + 1]; diff --git a/src/asm/section.c b/src/asm/section.c index 4961a8e3..1af1133b 100644 --- a/src/asm/section.c +++ b/src/asm/section.c @@ -14,6 +14,7 @@ #include "asm/warning.h" #include "extern/err.h" +#include "platform.h" // strdup struct SectionStackEntry { struct Section *pSection; diff --git a/src/extern/getopt.c b/src/extern/getopt.c index c0bf371b..16214d12 100644 --- a/src/extern/getopt.c +++ b/src/extern/getopt.c @@ -1,5 +1,5 @@ /* - * Copyright © 2005-2019 Rich Felker, et al. + * Copyright © 2005-2020 Rich Felker, et al. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -26,40 +26,128 @@ #include #include #include -#include +#ifndef _MSC_VER +# include +#endif #include #include +#include + #include "extern/getopt.h" -static int __optpos, __optreset; +#ifdef _MSC_VER +char *optarg; +int optind=1, opterr=1, optopt; +#endif +int optreset=0; +static int optpos; -void musl__getopt_msg(const char *a, const char *b, const char *c, size_t l) +static void musl_getopt_msg(const char *a, const char *b, const char *c, size_t l) { FILE *f = stderr; - (void)(fputs(a, f)>=0 - && fwrite(b, strlen(b), 1, f) - && fwrite(c, 1, l, f)==l - && putc('\n', f)); + + if (fputs(a, f) >= 0 && + fwrite(b, strlen(b), 1, f) && + fwrite(c, 1, l, f) == l) + putc('\n', f); } +#ifdef _MSC_VER +static int getopt(int argc, char *argv[], const char *optstring) +{ + int i; + wchar_t c, d; + int k, l; + char *optchar; + + if (!optind || optreset) { + optreset = 0; + optpos = 0; + optind = 1; + } + + if (optind >= argc || !argv[optind]) + return -1; + + if (argv[optind][0] != '-') { + if (optstring[0] == '-') { + optarg = argv[optind++]; + return 1; + } + return -1; + } + + if (!argv[optind][1]) + return -1; + + if (argv[optind][1] == '-' && !argv[optind][2]) + return optind++, -1; + + if (!optpos) optpos++; + if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) { + k = 1; + c = 0xfffd; /* replacement char */ + } + optchar = argv[optind]+optpos; + optpos += k; + + if (!argv[optind][optpos]) { + optind++; + optpos = 0; + } + + if (optstring[0] == '-' || optstring[0] == '+') + optstring++; + + i = 0; + d = 0; + do { + l = mbtowc(&d, optstring+i, MB_LEN_MAX); + if (l>0) i+=l; else i++; + } while (l && d != c); + + if (d != c || c == ':') { + optopt = c; + if (optstring[0] != ':' && opterr) + musl_getopt_msg(argv[0], ": unrecognized option: ", optchar, k); + return '?'; + } + if (optstring[i] == ':') { + optarg = 0; + if (optstring[i+1] != ':' || optpos) { + optarg = argv[optind++] + optpos; + optpos = 0; + } + if (optind > argc) { + optopt = c; + if (optstring[0] == ':') return ':'; + if (opterr) musl_getopt_msg(argv[0], + ": option requires an argument: ", + optchar, k); + return '?'; + } + } + return c; +} +#endif /* _MSC_VER */ + static void permute(char **argv, int dest, int src) { - char **av = (char **)argv; - char *tmp = av[src]; + char *tmp = argv[src]; int i; for (i=src; i>dest; i--) - av[i] = av[i-1]; - av[dest] = tmp; + argv[i] = argv[i-1]; + argv[dest] = tmp; } -static int musl__getopt_long_core(int argc, char **argv, const char *optstring, const struct option *longopts, int *idx, int longonly); +static int musl_getopt_long_core(int argc, char **argv, const char *optstring, const struct option *longopts, int *idx, int longonly); -static int musl__getopt_long(int argc, char **argv, const char *optstring, const struct option *longopts, int *idx, int longonly) +static int musl_getopt_long(int argc, char **argv, const char *optstring, const struct option *longopts, int *idx, int longonly) { int ret, skipped, resumed; - if (!optind || __optreset) { - __optreset = 0; - __optpos = 0; + if (!optind || optreset) { + optreset = 0; + optpos = 0; optind = 1; } if (optind >= argc || !argv[optind]) return -1; @@ -73,7 +161,7 @@ static int musl__getopt_long(int argc, char **argv, const char *optstring, const optind = i; } resumed = optind; - ret = musl__getopt_long_core(argc, argv, optstring, longopts, idx, longonly); + ret = musl_getopt_long_core(argc, argv, optstring, longopts, idx, longonly); if (resumed > skipped) { int i, cnt = optind-resumed; for (i=0; inext = symbolLists; symbolLists = symbolList; - uint32_t nbSymPerSect[nbSections ? nbSections : 1]; - - memset(nbSymPerSect, 0, sizeof(nbSymPerSect)); + uint32_t *nbSymPerSect = calloc(nbSections ? nbSections : 1, + sizeof(*nbSymPerSect)); verbosePrint("Reading %" PRIu32 " symbols...\n", nbSymbols); for (uint32_t i = 0; i < nbSymbols; i++) { @@ -475,7 +474,8 @@ void obj_ReadFile(char const *fileName) } /* This file's sections, stored in a table to link symbols to them */ - struct Section *fileSections[nbSections ? nbSections : 1]; + struct Section **fileSections = malloc(sizeof(*fileSections) + * (nbSections ? nbSections : 1)); verbosePrint("Reading %" PRIu32 " sections...\n", nbSections); for (uint32_t i = 0; i < nbSections; i++) { @@ -501,6 +501,8 @@ void obj_ReadFile(char const *fileName) sect_AddSection(fileSections[i]); } + free(nbSymPerSect); + /* Give symbols pointers to their sections */ for (uint32_t i = 0; i < nbSymbols; i++) { int32_t sectionID = fileSymbols[i]->sectionID; @@ -539,6 +541,7 @@ void obj_ReadFile(char const *fileName) assertions = assertion; } + free(fileSections); fclose(file); }