mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-06-01 17:12:15 +00:00
[qfcc] Support generating a C array of the output
I'd far rather use #embed, but gotta wait for gcc-15.
This commit is contained in:
parent
a3a4ca90b5
commit
0071c138bd
6 changed files with 71 additions and 12 deletions
|
@ -239,6 +239,12 @@ command line.
|
||||||
Unsupported options are ignored.
|
Unsupported options are ignored.
|
||||||
The following options are supported by \*[qfcc]'s \fB\-\-code\fP argument:
|
The following options are supported by \*[qfcc]'s \fB\-\-code\fP argument:
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B c-array[=name]
|
||||||
|
Generate a C source file with an array instead of the default binary format
|
||||||
|
for the target. Optionally, the default name (generated from the source file
|
||||||
|
name) can be overriden.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B const-initializers
|
.B const-initializers
|
||||||
Treat initialized globals as constants.
|
Treat initialized globals as constants.
|
||||||
|
|
|
@ -60,6 +60,9 @@ typedef struct {
|
||||||
bool no_int; // int type is not supported
|
bool no_int; // int type is not supported
|
||||||
bool no_vararg; // variadic functions (...) not supported
|
bool no_vararg; // variadic functions (...) not supported
|
||||||
|
|
||||||
|
bool c_array; // produce a C array for output
|
||||||
|
const char *c_array_name; // override for array name
|
||||||
|
|
||||||
bool help;
|
bool help;
|
||||||
} code_options_t;
|
} code_options_t;
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,7 @@ extern pr_info_t pr;
|
||||||
|
|
||||||
#define POINTER_OFS(s,p) ((pr_type_t *) (p) - (s)->data)
|
#define POINTER_OFS(s,p) ((pr_type_t *) (p) - (s)->data)
|
||||||
|
|
||||||
|
bool write_output (const char *filename, void *data, size_t bytes);
|
||||||
const char *file_basename (const char *filename, int keepdot) __attribute__((pure));
|
const char *file_basename (const char *filename, int keepdot) __attribute__((pure));
|
||||||
|
|
||||||
extern int pre_yydebug;
|
extern int pre_yydebug;
|
||||||
|
|
|
@ -228,6 +228,9 @@ code_usage (void)
|
||||||
printf ("%s - QuakeForge Code Compiler\n", this_program);
|
printf ("%s - QuakeForge Code Compiler\n", this_program);
|
||||||
printf ("Code generation options\n");
|
printf ("Code generation options\n");
|
||||||
printf (
|
printf (
|
||||||
|
" c-array[=name] Generate a C file with an array instead of the\n"
|
||||||
|
" default output for the target, with optional\n"
|
||||||
|
" override for the array name\n"
|
||||||
" [no-]const-initializers Treat initialized globals as constants.\n"
|
" [no-]const-initializers Treat initialized globals as constants.\n"
|
||||||
" [no-]cow Allow assignment to initialized globals.\n"
|
" [no-]cow Allow assignment to initialized globals.\n"
|
||||||
" [no-]cpp Preprocess all input files with cpp.\n"
|
" [no-]cpp Preprocess all input files with cpp.\n"
|
||||||
|
@ -574,6 +577,14 @@ parse_code_option (const char *opt)
|
||||||
if (OPTION(code, opt, "const-initializers", const_initializers, flag)) {
|
if (OPTION(code, opt, "const-initializers", const_initializers, flag)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (OPTION(code, opt, "c-array", c_array, flag)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!strncasecmp (opt, "c-array=", 8)) {
|
||||||
|
options.code.c_array = true;
|
||||||
|
options.code.c_array_name = save_string (opt + 8);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <QF/cbuf.h>
|
#include <QF/cbuf.h>
|
||||||
#include <QF/crc.h>
|
#include <QF/crc.h>
|
||||||
|
@ -205,7 +206,6 @@ static int
|
||||||
WriteProgs (dprograms_t *progs, int size)
|
WriteProgs (dprograms_t *progs, int size)
|
||||||
{
|
{
|
||||||
//pr_debug_header_t debug;
|
//pr_debug_header_t debug;
|
||||||
QFile *h;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
dstatement_t *statements;
|
dstatement_t *statements;
|
||||||
|
@ -251,13 +251,7 @@ WriteProgs (dprograms_t *progs, int size)
|
||||||
for (i = 0; i < progs->globals.count; i++)
|
for (i = 0; i < progs->globals.count; i++)
|
||||||
globals[i].value = LittleLong (globals[i].value);
|
globals[i].value = LittleLong (globals[i].value);
|
||||||
|
|
||||||
if (!(h = Qopen (options.output_file, "wb")))
|
return write_output (options.output_file, progs, size);
|
||||||
Sys_Error ("%s: %s\n", options.output_file, strerror(errno));
|
|
||||||
Qwrite (h, progs, size);
|
|
||||||
|
|
||||||
Qclose (h);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -330,6 +324,52 @@ begin_compilation (void)
|
||||||
pr.error_count = 0;
|
pr.error_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
write_output (const char *filename, void *data, size_t bytes)
|
||||||
|
{
|
||||||
|
QFile *file = Qopen (filename, "wb");
|
||||||
|
if (!file) {
|
||||||
|
Sys_Error ("%s: %s\n", filename, strerror(errno));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (options.code.c_array) {
|
||||||
|
const char *name = options.code.c_array_name;
|
||||||
|
uint32_t *words = data;
|
||||||
|
size_t count = bytes / 4;//FIXME asumes bytes is multiple of 4
|
||||||
|
const char *src = GETSTR (pr.loc.file);
|
||||||
|
char buf[strlen (src) + 1];
|
||||||
|
if (!name) {
|
||||||
|
for (char *d = buf; (*d = *src); d++, src++) {
|
||||||
|
if (!isalnum ((unsigned char) *d)) {
|
||||||
|
*d = '_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name = buf;
|
||||||
|
}
|
||||||
|
Qprintf (file, "uint32_t %s[] = {\n", name);
|
||||||
|
if (count) {
|
||||||
|
Qprintf (file, "\t");
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
Qprintf (file, "0x%08x,", words[i]);
|
||||||
|
if (i + 1 < count) {
|
||||||
|
if ((i + 1) % 4) {
|
||||||
|
Qprintf (file, " ");
|
||||||
|
} else {
|
||||||
|
Qprintf (file, "\n\t");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Qprintf (file, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Qprintf (file, "};");
|
||||||
|
} else {
|
||||||
|
Qwrite (file, data, bytes);
|
||||||
|
}
|
||||||
|
Qclose (file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
file_basename (const char *filename, int keepdot)
|
file_basename (const char *filename, int keepdot)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2113,10 +2113,8 @@ spirv_write (struct pr_info_s *pr, const char *filename)
|
||||||
ADD_DATA (space, mod->func_declarations);
|
ADD_DATA (space, mod->func_declarations);
|
||||||
ADD_DATA (space, mod->func_definitions);
|
ADD_DATA (space, mod->func_definitions);
|
||||||
|
|
||||||
QFile *file = Qopen (filename, "wb");
|
return write_output (filename, space->data,
|
||||||
Qwrite (file, space->data, space->size * sizeof (pr_type_t));
|
space->size * sizeof (pr_type_t));
|
||||||
Qclose (file);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue