mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-27 06:02:22 +00:00
A command line interface for the PAK utility, made it a seperate build target too.
This commit is contained in:
parent
a568d43487
commit
eabb92f7b4
2 changed files with 149 additions and 5 deletions
15
Makefile
15
Makefile
|
@ -9,14 +9,14 @@ CYGWIN = $(findstring CYGWIN, $(UNAME))
|
|||
MINGW = $(findstring MINGW32, $(UNAME))
|
||||
|
||||
CC ?= clang
|
||||
CFLAGS += -Wall -Wextra -I. -fno-strict-aliasing -fsigned-char
|
||||
CFLAGS += -Wall -Wextra -Werror -I. -fno-strict-aliasing -fsigned-char
|
||||
ifneq ($(shell git describe --always 2>/dev/null),)
|
||||
CFLAGS += -DGMQCC_GITINFO="\"$(shell git describe --always)\""
|
||||
endif
|
||||
#turn on tons of warnings if clang is present
|
||||
# but also turn off the STUPID ONES
|
||||
ifeq ($(CC), clang)
|
||||
CFLAGS += \
|
||||
CFLAGS += \
|
||||
-Weverything \
|
||||
-Wno-padded \
|
||||
-Wno-format-nonliteral \
|
||||
|
@ -41,7 +41,8 @@ ifeq ($(track), no)
|
|||
CFLAGS += -DNOTRACK
|
||||
endif
|
||||
|
||||
OBJ_D = util.o code.o ast.o ir.o conout.o ftepp.o opts.o fs.o utf8.o correct.o pak.o
|
||||
OBJ_D = util.o code.o ast.o ir.o conout.o ftepp.o opts.o fs.o utf8.o correct.o
|
||||
OBJ_P = util.o fs.o conout.o opts.o pak.o
|
||||
OBJ_T = test.o util.o conout.o fs.o
|
||||
OBJ_C = main.o lexer.o parser.o fs.o
|
||||
OBJ_X = exec-standalone.o util.o conout.o fs.o
|
||||
|
@ -56,6 +57,7 @@ ifneq ("$(CYGWIN)", "")
|
|||
QCVM = qcvm.exe
|
||||
GMQCC = gmqcc.exe
|
||||
TESTSUITE = testsuite.exe
|
||||
PAK = pak.exe
|
||||
else
|
||||
ifneq ("$(MINGW)", "")
|
||||
#nullify the common variables that
|
||||
|
@ -67,6 +69,7 @@ ifneq ("$(MINGW)", "")
|
|||
QCVM = qcvm.exe
|
||||
GMQCC = gmqcc.exe
|
||||
TESTSUITE = testsuite.exe
|
||||
PAK = pak.exe
|
||||
else
|
||||
#arm support for linux .. we need to allow unaligned accesses
|
||||
#to memory otherwise we just segfault everywhere
|
||||
|
@ -77,6 +80,7 @@ else
|
|||
QCVM = qcvm
|
||||
GMQCC = gmqcc
|
||||
TESTSUITE = testsuite
|
||||
PAK = pak
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -148,7 +152,10 @@ $(GMQCC): $(OBJ_C) $(OBJ_D)
|
|||
$(TESTSUITE): $(OBJ_T)
|
||||
$(CC) -o $@ $^ $(CFLAGS)
|
||||
|
||||
all: $(GMQCC) $(QCVM) $(TESTSUITE)
|
||||
$(PAK): $(OBJ_P)
|
||||
$(CC) -o $@ $^ $(CFLAGS)
|
||||
|
||||
all: $(GMQCC) $(QCVM) $(TESTSUITE) $(PAK)
|
||||
|
||||
check: all
|
||||
@ ./$(TESTSUITE)
|
||||
|
|
139
pak.c
139
pak.c
|
@ -28,7 +28,7 @@
|
|||
* The PAK format uses a FOURCC concept for storing the magic ident within
|
||||
* the header as a uint32_t.
|
||||
*/
|
||||
#define PAK_FOURCC ((uint32_t)(('P' << 24) | ('A' << 16) | ('C' << 8) | 'K'))
|
||||
#define PAK_FOURCC ((uint32_t)(('P' | ('A' << 8) | ('C' << 16) | ('K' << 24))))
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic; /* "PACK" */
|
||||
|
@ -441,3 +441,140 @@ bool pak_close(pak_file_t *pak) {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fancy GCC-like LONG parsing allows things like --opt=param with
|
||||
* assignment operator. This is used for redirecting stdout/stderr
|
||||
* console to specific files of your choice.
|
||||
*/
|
||||
static bool parsecmd(const char *optname, int *argc_, char ***argv_, char **out, int ds, bool split) {
|
||||
int argc = *argc_;
|
||||
char **argv = *argv_;
|
||||
|
||||
size_t len = strlen(optname);
|
||||
|
||||
if (strncmp(argv[0]+ds, optname, len))
|
||||
return false;
|
||||
|
||||
/* it's --optname, check how the parameter is supplied */
|
||||
if (argv[0][ds+len] == '=') {
|
||||
*out = argv[0]+ds+len+1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!split || argc < ds) /* no parameter was provided, or only single-arg form accepted */
|
||||
return false;
|
||||
|
||||
/* using --opt param */
|
||||
*out = argv[1];
|
||||
--*argc_;
|
||||
++*argv_;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
bool extract = true;
|
||||
char *redirout = (char*)stdout;
|
||||
char *redirerr = (char*)stderr;
|
||||
char *directory = NULL;
|
||||
char *file = NULL;
|
||||
char **files = NULL;
|
||||
pak_file_t *pak = NULL;
|
||||
size_t iter = 0;
|
||||
|
||||
con_init();
|
||||
|
||||
/*
|
||||
* Command line option parsing commences now We only need to support
|
||||
* a few things in the test suite.
|
||||
*/
|
||||
while (argc > 1) {
|
||||
++argv;
|
||||
--argc;
|
||||
|
||||
if (argv[0][0] == '-') {
|
||||
if (parsecmd("redirout", &argc, &argv, &redirout, 1, false))
|
||||
continue;
|
||||
if (parsecmd("redirerr", &argc, &argv, &redirerr, 1, false))
|
||||
continue;
|
||||
if (parsecmd("directory", &argc, &argv, &directory, 1, false))
|
||||
continue;
|
||||
if (parsecmd("file", &argc, &argv, &file, 1, false))
|
||||
continue;
|
||||
|
||||
con_change(redirout, redirerr);
|
||||
|
||||
switch (argv[0][1]) {
|
||||
case 'e': extract = true; continue;
|
||||
case 'c': extract = false; continue;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0]+1, "debug")) {
|
||||
OPTS_OPTION_BOOL(OPTION_DEBUG) = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[0]+1, "memchk")) {
|
||||
OPTS_OPTION_BOOL(OPTION_MEMCHK) = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[0]+1, "nocolor")) {
|
||||
con_color(0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
vec_push(files, argv[0]);
|
||||
}
|
||||
con_change(redirout, redirerr);
|
||||
|
||||
|
||||
if (!file) {
|
||||
con_err("-file must be specified for output/input PAK file\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (extract) {
|
||||
if (!(pak = pak_open(file, "r"))) {
|
||||
con_err("failed to open PAK file %s\n", file);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!pak_extract_all(pak, (directory) ? directory : "./")) {
|
||||
con_err("failed to extract PAK %s (files may be missing)\n", file);
|
||||
pak_close(pak);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* not possible */
|
||||
if (!pak_close(pak))
|
||||
abort();
|
||||
|
||||
util_meminfo();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (!(pak = pak_open(file, "w"))) {
|
||||
con_err("failed to open PAK %s for writing\n", file);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (directory && !fs_dir_change(directory)) {
|
||||
con_err("failed to change directory %s\n", directory);
|
||||
pak_close(pak);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (iter = 0; iter < vec_size(files); iter++) {
|
||||
if (!(pak_insert_one(pak, files[iter]))) {
|
||||
con_err("failed inserting %s for PAK %s\n", files[iter], file);
|
||||
pak_close(pak);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* not possible */
|
||||
if (!pak_close(pak))
|
||||
abort();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue