Modernize carray(1) and fix missing allocation checks.
Add short options for most long options. Rename the -i option to -H, but support -i for compatibility until the next release cycle, where -i will become the short option of --identifier. Rename --include to --headers and support --include until the next release cycle. Add carray(1) manual page which makes --help unnecessary, and remove --version as it surely matches your local Sortix version.
This commit is contained in:
parent
7c974240f2
commit
64dc3cb2be
|
@ -6,7 +6,6 @@ include ../build-aux/dirs.mak
|
|||
OPTLEVEL?=$(DEFAULT_OPTLEVEL)
|
||||
CFLAGS?=$(OPTLEVEL)
|
||||
|
||||
CPPFLAGS:=$(CPPFLAGS) -DVERSIONSTR=\"$(VERSION)\"
|
||||
CFLAGS:=$(CFLAGS) -Wall -Wextra
|
||||
|
||||
ifeq ($(HOST_IS_SORTIX),0)
|
||||
|
@ -22,6 +21,8 @@ all: $(BINARY)
|
|||
install: all
|
||||
mkdir -p $(DESTDIR)$(BINDIR)
|
||||
install $(BINARY) $(DESTDIR)$(BINDIR)
|
||||
mkdir -p $(DESTDIR)$(MANDIR)/man1
|
||||
cp carray.1 $(DESTDIR)$(MANDIR)/man1/carray.1
|
||||
|
||||
%: %.c
|
||||
$(CC) -std=gnu11 $(CFLAGS) $(CPPFLAGS) $< -o $@
|
||||
|
|
|
@ -0,0 +1,237 @@
|
|||
.Dd $Mdocdate: August 12 2016 $
|
||||
.Dt CARRAY 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm carray
|
||||
.Nd convert binary file to C array
|
||||
.Sh SYNOPSIS
|
||||
.Nm carray
|
||||
.\" After releasing Sortix 1.1, make this change to match carray.c:
|
||||
.\".Op Fl ceEgHrsv
|
||||
.\" Compatibility:
|
||||
.Op Fl ceEgHirsv
|
||||
.\" (End)
|
||||
.Op Fl G Ar guard
|
||||
.\" After releasing Sortix 1.1, make this change to match carray.c:
|
||||
.\".Op Fl i Ar identifier
|
||||
.\" Compatibility:
|
||||
.Op Fl \-identifier Ns "=" Ns Ar identifier
|
||||
.\" (End)
|
||||
.Op Fl \-includes Ns "=" Ns Ar include-statements
|
||||
.Op Fl o Ar output
|
||||
.Op Fl t Ar type
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
encodes its input as the source code for a C array of hexadecimal constants.
|
||||
The input is the specified
|
||||
.Ar file
|
||||
operands concatenated, or the standard input if no input files are specified.
|
||||
.Nm
|
||||
writes the source code for a C array to the standard output, or
|
||||
.Ar output
|
||||
if the
|
||||
.Fl o
|
||||
option is given.
|
||||
The default type is an array of
|
||||
.Sy unsigned char .
|
||||
The array contents are indented with tabs
|
||||
and the lines don't exceed 80 columns (tabs have the width of 8 spaces).
|
||||
.Pp
|
||||
The default array name is the output path if set, or the path of the first
|
||||
input file (if any), or otherwise
|
||||
.Sy carray .
|
||||
The default array name has all file extensions removed (but a leading period
|
||||
in the file name is kept). The default array name is converted to the
|
||||
characters
|
||||
a-z, A-Z,
|
||||
.Sq _ ,
|
||||
and 0-9. 0-9 cannot be the first character of an identifier.
|
||||
.Sq +
|
||||
will be replaced by
|
||||
.Sq x .
|
||||
Any other characters are replaced by
|
||||
.Sq _
|
||||
unless it is the first character, in which case it is replaced by
|
||||
.Sq x .
|
||||
.Pp
|
||||
A guard macro is optionally used by the
|
||||
.Fl g
|
||||
and
|
||||
.Fl G
|
||||
options. The default guard macro is the output path if set, or the path of the
|
||||
first input file (if any) followed by
|
||||
.Sy _H ,
|
||||
or otherwise
|
||||
.Sy CARRAY_H .
|
||||
The default guard macro is converted to the characters A-Z,
|
||||
.Sq _ ,
|
||||
and 0-9. 0-9 cannot be the first character of an identifier. The lower-case
|
||||
a-z is converted to the upper-case A-Z.
|
||||
.Sq +
|
||||
is replaced by
|
||||
.Sq X .
|
||||
Any other characters are replaced by
|
||||
.Sq _ .
|
||||
.Pp
|
||||
Parts of the output are optional, but the output will be in this order: The
|
||||
opening guard macro check, the guard macro definition, the inclusion of
|
||||
prerequisite headers, the opening
|
||||
.Sy extern """C"""
|
||||
block, the array declaration and initialization, the closing
|
||||
.Sy extern """C"""
|
||||
block, and the closing guard macro check.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width "12345678"
|
||||
.It Fl c , Fl \-const
|
||||
Declare the array with the
|
||||
.Sy const
|
||||
keyword.
|
||||
.It Fl e , Fl \-extern
|
||||
Declare the array with the
|
||||
.Sy extern
|
||||
keyword. This option is mutually incompatible with the
|
||||
.Fl s
|
||||
option.
|
||||
.It Fl E , Fl \-extern-c
|
||||
Wrap the array in
|
||||
.Sy extern """C""" { }
|
||||
subject to a preprocessor check for C++.
|
||||
.It Fl f , Fl \-forward
|
||||
Forward declare the array only, do not initialize it with contents. The input
|
||||
files are not opened and the standard input is unused. This option is mutually
|
||||
incompatible with the
|
||||
.Fl r
|
||||
option.
|
||||
.It Fl g , Fl \-use-guard
|
||||
Wrap the output in a preprocessor conditional checking the guard macro is not
|
||||
set, and declare the macro if it is not set. This conditional is a classic C
|
||||
include guard that ensures only the first inclusion of a header has any effect.
|
||||
.It Fl G , Fl \-guard Ar guard
|
||||
Sets the guard macro to
|
||||
.Ar guard
|
||||
and enables the guard macro check as if the
|
||||
.Fl g
|
||||
option was set as well. The guard macro is unrestricted and untransformed and
|
||||
will be be output verbatim.
|
||||
.It Fl H , Fl \-headers
|
||||
Output inclusions of all the prerequisite headers. By default, there are no
|
||||
prerequisite headers, unless the array type is one of the
|
||||
.In stdint.h
|
||||
types, in which case
|
||||
.In stdint.h
|
||||
is the only prerequisite header.
|
||||
.\" After releasing Sortix 1.1, make this change to match carray.c:
|
||||
.\".It Fl i , Fl \-identifier Ar identifier
|
||||
.\" Compatibility:
|
||||
.It Fl \-identifier Ar identifier
|
||||
.\" (End)
|
||||
Sets the name of the array to
|
||||
.Ar identifier .
|
||||
The identifier is unrestricted and will be be output verbatim.
|
||||
.It Fl \-includes Ar include-statements
|
||||
Sets the C preprocessor statements
|
||||
.Ar include-statements
|
||||
as how to include all the prerequisite headers and enables inclusion of the
|
||||
prerequisite headers as if the
|
||||
.Fl H
|
||||
option was set. The preprocessor statements are unrestricted and untransformed
|
||||
and will be be output verbatim.
|
||||
.It Fl o , Fl output Ar output
|
||||
Write the output to the
|
||||
.Ar output
|
||||
path rather than the standard output.
|
||||
.It Fl r , Fl \-raw
|
||||
Output only the hexadecimally encoded array contents, and the guard macro check
|
||||
if set by the
|
||||
.Fl g
|
||||
option. This option is mutually incompatible with the
|
||||
.Fl f
|
||||
option.
|
||||
.It Fl s , Fl \-static
|
||||
Declare the array with the
|
||||
.Sy static
|
||||
keyword.
|
||||
.It Fl t , Fl \-type Ar type
|
||||
Declare the array as an array of the specified
|
||||
.Ar type .
|
||||
The type is unrestricted and will be be output verbatim.
|
||||
.It Fl v , Fl \-volatile
|
||||
Declare the array with the
|
||||
.Sy volatile
|
||||
keyword.
|
||||
.El
|
||||
.Pp
|
||||
In addition to the
|
||||
.Fl t
|
||||
option, the array type can be set by the following options:
|
||||
.Bl -tag -width "--unsigned-char"
|
||||
.It Fl \-char
|
||||
Declare as array of
|
||||
.Sy char .
|
||||
.It Fl \-signed-char
|
||||
Declare as array of
|
||||
.Sy signed char .
|
||||
.It Fl \-unsigned-char
|
||||
Declare as array of
|
||||
.Sy unsigned char .
|
||||
.It Fl \-int8_t
|
||||
Declare as array of
|
||||
.Sy int8_t .
|
||||
.It Fl \-uint8_t
|
||||
Declare as array of
|
||||
.Sy uint8_t .
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Nm
|
||||
will exit 0 on success and non-zero otherwise.
|
||||
.Sh EXAMPLES
|
||||
.Bd -literal
|
||||
$ echo foo | carray
|
||||
unsigned char carray[] = {
|
||||
0x66, 0x6F, 0x6F, 0x0A,
|
||||
};
|
||||
.Ed
|
||||
.Bd -literal
|
||||
$ echo foo | carray -cs -o foo.inc
|
||||
$ cat foo.inc
|
||||
static const unsigned char foo[] = {
|
||||
0x66, 0x6F, 0x6F, 0x0A,
|
||||
};
|
||||
.Ed
|
||||
.Bd -literal
|
||||
$ echo foo | carray -ceEfgH -t uint8_t -o foo.h
|
||||
$ cat foo.h
|
||||
#ifndef FOO_H
|
||||
#define FOO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const uint8_t foo[];
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
.Ed
|
||||
.Bd -literal
|
||||
$ echo foo | carray -cH -t uint8_t -o foo.c
|
||||
$ cat foo.c
|
||||
#include <stdint.h>
|
||||
|
||||
const uint8_t foo[] = {
|
||||
0x66, 0x6F, 0x6F, 0x0A,
|
||||
};
|
||||
.Ed
|
||||
.Bd -literal
|
||||
$ echo foo | carray -r
|
||||
0x66, 0x6F, 0x6F, 0x0A,
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr gcc 1
|
255
carray/carray.c
255
carray/carray.c
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -38,112 +37,64 @@ static void compact_arguments(int* argc, char*** argv)
|
|||
}
|
||||
}
|
||||
|
||||
bool get_option_variable(const char* option, char** varptr,
|
||||
const char* arg, int argc, char** argv, int* ip,
|
||||
const char* argv0)
|
||||
bool get_option_variable(const char* option, const char** varptr,
|
||||
const char* arg, int argc, char** argv, int* ip)
|
||||
{
|
||||
size_t option_len = strlen(option);
|
||||
if ( strncmp(option, arg, option_len) != 0 )
|
||||
return false;
|
||||
if ( arg[option_len] == '=' )
|
||||
{
|
||||
*varptr = strdup(arg + option_len + 1);
|
||||
*varptr = arg + option_len + 1;
|
||||
return true;
|
||||
}
|
||||
if ( arg[option_len] != '\0' )
|
||||
return false;
|
||||
if ( *ip + 1 == argc )
|
||||
{
|
||||
fprintf(stderr, "%s: expected operand after `%s'\n", argv0, option);
|
||||
exit(1);
|
||||
}
|
||||
*varptr = strdup(argv[++*ip]), argv[*ip] = NULL;
|
||||
errx(1, "expected operand after `%s'\n", option);
|
||||
*varptr = argv[++*ip];
|
||||
argv[*ip] = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define GET_OPTION_VARIABLE(str, varptr) \
|
||||
get_option_variable(str, varptr, arg, argc, argv, &i, argv0)
|
||||
get_option_variable(str, varptr, arg, argc, argv, &i)
|
||||
|
||||
void get_short_option_variable(char c, char** varptr,
|
||||
const char* arg, int argc, char** argv, int* ip,
|
||||
const char* argv0)
|
||||
void get_short_option_variable(char c, const char** varptr,
|
||||
const char* arg, int argc, char** argv, int* ip)
|
||||
{
|
||||
free(*varptr);
|
||||
if ( *(arg+1) )
|
||||
{
|
||||
*varptr = strdup(arg + 1);
|
||||
}
|
||||
*varptr = arg + 1;
|
||||
else
|
||||
{
|
||||
if ( *ip + 1 == argc )
|
||||
{
|
||||
warn("option requires an argument -- '%c'", c);
|
||||
fprintf(stderr, "Try `%s --help' for more information.\n", argv0);
|
||||
exit(1);
|
||||
}
|
||||
*varptr = strdup(argv[*ip + 1]);
|
||||
errx(1, "option requires an argument -- '%c'", c);
|
||||
*varptr = argv[*ip + 1];
|
||||
argv[++(*ip)] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define GET_SHORT_OPTION_VARIABLE(c, varptr) \
|
||||
get_short_option_variable(c, varptr, arg, argc, argv, &i, argv0)
|
||||
|
||||
static void help(FILE* fp, const char* argv0)
|
||||
{
|
||||
fprintf(fp, "Usage: %s [OPTION]... [INPUT...] -o OUTPUT\n", argv0);
|
||||
fprintf(fp, "Convert a binary file to a C array.\n");
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "Mandatory arguments to long options are mandatory for short options too.\n");
|
||||
fprintf(fp, " -c, --const add const keyword\n");
|
||||
fprintf(fp, " -e, --extern add extern keyword\n");
|
||||
fprintf(fp, " --extern-c use C linkage\n");
|
||||
fprintf(fp, " -f, --forward forward declare rather than define\n");
|
||||
fprintf(fp, " --guard=MACRO use include guard macro MACRO\n");
|
||||
fprintf(fp, " -g, --use-guard add include guard\n");
|
||||
fprintf(fp, " -i, --include include prerequisite headers\n");
|
||||
fprintf(fp, " --identifier=NAME use identifier NAME\n");
|
||||
fprintf(fp, " --includes=INCLUDES emit raw preprocessor INCLUDES\n");
|
||||
fprintf(fp, " -o, --output=FILE write result to FILE\n");
|
||||
fprintf(fp, " -r, --raw emit only raw \n");
|
||||
fprintf(fp, " -s, --static add static keyword\n");
|
||||
fprintf(fp, " --type=TYPE use type TYPE [unsigned char]\n");
|
||||
fprintf(fp, " -v, --volatile add volatile keyword\n");
|
||||
fprintf(fp, " --char use type char\n");
|
||||
fprintf(fp, " --signed-char use type signed char\n");
|
||||
fprintf(fp, " --unsigned-char use type unsigned char\n");
|
||||
fprintf(fp, " --int8_t use type int8_t\n");
|
||||
fprintf(fp, " --uint8_t use type uint8_t\n");
|
||||
fprintf(fp, " --help display this help and exit\n");
|
||||
fprintf(fp, " --version output version information and exit\n");
|
||||
}
|
||||
|
||||
static void version(FILE* fp, const char* argv0)
|
||||
{
|
||||
fprintf(fp, "%s (Sortix) %s\n", argv0, VERSIONSTR);
|
||||
}
|
||||
get_short_option_variable(c, varptr, arg, argc, argv, &i)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
bool flag_const = false;
|
||||
bool flag_extern_c = false;
|
||||
bool flag_extern = false;
|
||||
bool flag_forward = false;
|
||||
bool flag_guard = false;
|
||||
bool flag_include = false;
|
||||
bool flag_headers = false;
|
||||
bool flag_raw = false;
|
||||
bool flag_static = false;
|
||||
bool flag_volatile = false;
|
||||
|
||||
char* arg_guard = NULL;
|
||||
char* arg_identifier = NULL;
|
||||
char* arg_includes = NULL;
|
||||
char* arg_output = NULL;
|
||||
char* arg_type = NULL;
|
||||
const char* guard = NULL;
|
||||
const char* identifier = NULL;
|
||||
const char* includes = NULL;
|
||||
const char* output = NULL;
|
||||
const char* type = NULL;
|
||||
|
||||
const char* argv0 = argv[0];
|
||||
for ( int i = 1; i < argc; i++ )
|
||||
{
|
||||
const char* arg = argv[i];
|
||||
|
@ -159,33 +110,44 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
case 'c': flag_const = true; break;
|
||||
case 'e': flag_extern = true; break;
|
||||
case 'E': flag_extern_c = true; break;
|
||||
case 'f': flag_forward = true; break;
|
||||
case 'g': flag_guard = true; break;
|
||||
case 'i': flag_include = true; break;
|
||||
case 'o': GET_SHORT_OPTION_VARIABLE('o', &arg_output); arg = "o"; break;
|
||||
case 'G': GET_SHORT_OPTION_VARIABLE('G', &guard); arg = "G"; flag_guard = true; break;
|
||||
case 'H': flag_headers = true; break;
|
||||
// TODO: After releasing Sortix 1.1, change -i to --identifier
|
||||
// rather than -H (--headers).
|
||||
#if 0 // Future behavior:
|
||||
case 'i': GET_SHORT_OPTION_VARIABLE('i', &identifier); arg = "i"; break;
|
||||
#else // Compatibility:
|
||||
case 'i': flag_headers = true; break;
|
||||
#endif
|
||||
case 'o': GET_SHORT_OPTION_VARIABLE('o', &output); arg = "o"; break;
|
||||
case 'r': flag_raw = true; break;
|
||||
case 's': flag_static = true; break;
|
||||
case 't': GET_SHORT_OPTION_VARIABLE('t', &type); arg = "t"; break;
|
||||
case 'v': flag_volatile = true; break;
|
||||
default:
|
||||
fprintf(stderr, "%s: unknown option -- '%c'\n", argv0, c);
|
||||
help(stderr, argv0);
|
||||
exit(1);
|
||||
errx(1, "unknown option -- '%c'\n", c);
|
||||
}
|
||||
}
|
||||
else if ( !strcmp(arg, "--help") )
|
||||
help(stdout, argv0), exit(0);
|
||||
else if ( !strcmp(arg, "--version") )
|
||||
version(stdout, argv0), exit(0);
|
||||
else if ( !strcmp(arg, "--const") )
|
||||
flag_const = true;
|
||||
else if ( !strcmp(arg, "--extern") )
|
||||
flag_extern = true;
|
||||
else if ( !strcmp(arg, "--extern-c") )
|
||||
flag_extern_c = true;
|
||||
else if ( !strcmp(arg, "--forward") )
|
||||
flag_forward = true;
|
||||
else if ( !strcmp(arg, "--use-guard") )
|
||||
flag_guard = true;
|
||||
else if ( !strcmp(arg, "--headers") )
|
||||
flag_headers = true;
|
||||
// TODO: After releasing Sortix 1.1, remove --include.
|
||||
#if 1 // Compatibility:
|
||||
else if ( !strcmp(arg, "--include") )
|
||||
flag_include = true;
|
||||
flag_headers = true;
|
||||
#endif
|
||||
else if ( !strcmp(arg, "--raw") )
|
||||
flag_raw = true;
|
||||
else if ( !strcmp(arg, "--static") )
|
||||
|
@ -193,109 +155,112 @@ int main(int argc, char* argv[])
|
|||
else if ( !strcmp(arg, "--volatile") )
|
||||
flag_volatile = true;
|
||||
else if ( !strcmp(arg, "--char") )
|
||||
free(arg_type), arg_type = strdup("char");
|
||||
type = "char";
|
||||
else if ( !strcmp(arg, "--signed-char") )
|
||||
free(arg_type), arg_type = strdup("signed char");
|
||||
type = "signed char";
|
||||
else if ( !strcmp(arg, "--unsigned-char") )
|
||||
free(arg_type), arg_type = strdup("unsigned char");
|
||||
type = "unsigned char";
|
||||
else if ( !strcmp(arg, "--int8_t") )
|
||||
free(arg_type), arg_type = strdup("int8_t");
|
||||
type = "int8_t";
|
||||
else if ( !strcmp(arg, "--uint8_t") )
|
||||
free(arg_type), arg_type = strdup("uint8_t");
|
||||
else if ( GET_OPTION_VARIABLE("--guard", &arg_guard) )
|
||||
type = "uint8_t";
|
||||
else if ( GET_OPTION_VARIABLE("--guard", &guard) )
|
||||
flag_guard = true;
|
||||
else if ( GET_OPTION_VARIABLE("--identifier", &arg_identifier) ) { }
|
||||
else if ( GET_OPTION_VARIABLE("--includes", &arg_includes) )
|
||||
flag_include = true;
|
||||
else if ( GET_OPTION_VARIABLE("--output", &arg_output) ) { }
|
||||
else if ( GET_OPTION_VARIABLE("--type", &arg_type) ) { }
|
||||
else if ( !strcmp(arg, "--extern-c") )
|
||||
flag_extern_c = true;
|
||||
else if ( GET_OPTION_VARIABLE("--identifier", &identifier) ) { }
|
||||
else if ( GET_OPTION_VARIABLE("--includes", &includes) )
|
||||
flag_headers = true;
|
||||
else if ( GET_OPTION_VARIABLE("--output", &output) ) { }
|
||||
else if ( GET_OPTION_VARIABLE("--type", &type) ) { }
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: unknown option: %s\n", argv0, arg);
|
||||
help(stderr, argv0);
|
||||
exit(1);
|
||||
}
|
||||
errx(1, "unknown option: %s\n", arg);
|
||||
}
|
||||
|
||||
compact_arguments(&argc, &argv);
|
||||
|
||||
const char* output_path = arg_output;
|
||||
|
||||
if ( flag_extern && flag_static )
|
||||
errx(1, "the --extern and --static are mutually incompatible");
|
||||
errx(1, "the --extern and --static options are mutually incompatible");
|
||||
if ( flag_forward && flag_raw )
|
||||
errx(1, "the --forward and --raw are mutually incompatible");
|
||||
errx(1, "the --forward and --raw options are mutually incompatible");
|
||||
|
||||
if ( !arg_type )
|
||||
arg_type = strdup("unsigned char");
|
||||
if ( !type )
|
||||
type = "unsigned char";
|
||||
|
||||
char* guard = arg_guard;
|
||||
if ( !guard )
|
||||
{
|
||||
if ( output_path )
|
||||
guard = strdup(output_path);
|
||||
char* new_guard;
|
||||
if ( output )
|
||||
new_guard = strdup(output);
|
||||
else if ( 2 <= argc && strcmp(argv[1], "-") != 0 )
|
||||
asprintf(&guard, "%s_H", argv[1]);
|
||||
else
|
||||
guard = strdup("CARRAY_H");
|
||||
|
||||
for ( size_t i = 0; guard[i]; i++ )
|
||||
{
|
||||
if ( 'A' <= guard[i] && guard[i] <= 'Z' )
|
||||
if ( asprintf(&new_guard, "%s_H", argv[1]) < 0 )
|
||||
err(1, "asprintf");
|
||||
}
|
||||
else
|
||||
new_guard = strdup("CARRAY_H");
|
||||
if ( !new_guard )
|
||||
err(1, "strdup");
|
||||
|
||||
for ( size_t i = 0; new_guard[i]; i++ )
|
||||
{
|
||||
if ( 'A' <= new_guard[i] && new_guard[i] <= 'Z' )
|
||||
continue;
|
||||
else if ( 'a' <= guard[i] && guard[i] <= 'z' )
|
||||
guard[i] = 'A' + guard[i] - 'a';
|
||||
else if ( i != 0 && '0' <= guard[i] && guard[i] <= '9' )
|
||||
else if ( 'a' <= new_guard[i] && new_guard[i] <= 'z' )
|
||||
new_guard[i] = 'A' + new_guard[i] - 'a';
|
||||
else if ( i != 0 && '0' <= new_guard[i] && new_guard[i] <= '9' )
|
||||
continue;
|
||||
else if ( guard[i] == '+' )
|
||||
guard[i] = 'X';
|
||||
else if ( new_guard[i] == '+' )
|
||||
new_guard[i] = 'X';
|
||||
else if ( i == 0 )
|
||||
guard[i] = 'X';
|
||||
new_guard[i] = 'X';
|
||||
else
|
||||
guard[i] = '_';
|
||||
}
|
||||
new_guard[i] = '_';
|
||||
}
|
||||
|
||||
if ( flag_include && !arg_includes )
|
||||
guard = new_guard;
|
||||
}
|
||||
|
||||
if ( flag_headers && !includes )
|
||||
{
|
||||
if ( !strcmp(arg_type, "int8_t") ||
|
||||
!strcmp(arg_type, "uint8_t") )
|
||||
arg_includes = strdup("#include <stdint.h>");
|
||||
if ( !strcmp(type, "int8_t") ||
|
||||
!strcmp(type, "uint8_t") )
|
||||
includes = "#include <stdint.h>";
|
||||
}
|
||||
|
||||
char* identifier = arg_identifier;
|
||||
if ( !identifier )
|
||||
{
|
||||
if ( output_path )
|
||||
identifier = strdup(output_path);
|
||||
char* new_identifier;
|
||||
if ( output )
|
||||
new_identifier = strdup(output);
|
||||
else if ( 2 <= argc && strcmp(argv[1], "-") != 0 )
|
||||
identifier = strdup(argv[1]);
|
||||
new_identifier = strdup(argv[1]);
|
||||
else
|
||||
identifier = strdup("carray");
|
||||
new_identifier = strdup("carray");
|
||||
if ( !new_identifier )
|
||||
err(1, "strdup");
|
||||
|
||||
for ( size_t i = 0; identifier[i]; i++ )
|
||||
for ( size_t i = 0; new_identifier[i]; i++ )
|
||||
{
|
||||
if ( i && identifier[i] == '.' && !strchr(identifier + i, '/') )
|
||||
identifier[i] = '\0';
|
||||
else if ( 'a' <= identifier[i] && identifier[i] <= 'z' )
|
||||
if ( i && new_identifier[i] == '.' && !strchr(new_identifier + i, '/') )
|
||||
new_identifier[i] = '\0';
|
||||
else if ( 'a' <= new_identifier[i] && new_identifier[i] <= 'z' )
|
||||
continue;
|
||||
else if ( 'A' <= identifier[i] && identifier[i] <= 'Z' )
|
||||
identifier[i] = 'a' + identifier[i] - 'A';
|
||||
else if ( i != 0 && '0' <= identifier[i] && identifier[i] <= '9' )
|
||||
else if ( 'A' <= new_identifier[i] && new_identifier[i] <= 'Z' )
|
||||
new_identifier[i] = 'a' + new_identifier[i] - 'A';
|
||||
else if ( i != 0 && '0' <= new_identifier[i] && new_identifier[i] <= '9' )
|
||||
continue;
|
||||
else if ( guard[i] == '+' )
|
||||
identifier[i] = 'x';
|
||||
new_identifier[i] = 'x';
|
||||
else if ( i == 0 )
|
||||
identifier[i] = 'x';
|
||||
new_identifier[i] = 'x';
|
||||
else
|
||||
identifier[i] = '_';
|
||||
}
|
||||
new_identifier[i] = '_';
|
||||
}
|
||||
|
||||
if ( output_path && !freopen(output_path, "w", stdout) )
|
||||
err(1, "%s", output_path);
|
||||
identifier = new_identifier;
|
||||
}
|
||||
|
||||
if ( output && !freopen(output, "w", stdout) )
|
||||
err(1, "%s", output);
|
||||
|
||||
if ( flag_guard && guard )
|
||||
{
|
||||
|
@ -304,9 +269,9 @@ int main(int argc, char* argv[])
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
if ( flag_include && arg_includes )
|
||||
if ( flag_headers && includes )
|
||||
{
|
||||
printf("%s\n", arg_includes);
|
||||
printf("%s\n", includes);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
@ -327,7 +292,7 @@ int main(int argc, char* argv[])
|
|||
printf("const ");
|
||||
if ( flag_volatile )
|
||||
printf("volatile ");
|
||||
printf("%s %s[]", arg_type, identifier);
|
||||
printf("%s %s[]", type, identifier);
|
||||
if ( flag_forward )
|
||||
printf(";\n");
|
||||
else
|
||||
|
@ -399,7 +364,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
if ( ferror(stdout) || fflush(stdout) == EOF )
|
||||
err(1, "%s", output_path ? output_path : "stdout");
|
||||
err(1, "%s", output ? output : "stdout");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -200,10 +200,10 @@ endif
|
|||
kblayout-compiler --format=sortix-kblayout-1 --compression=none $< -o $@
|
||||
|
||||
kb/default-kblayout.h: kb/default-kblayout
|
||||
carray -cgis --uint8_t --guard=SORTIX_KB_DEFAULT_KBLAYOUT_H --identifier=default_kblayout $< -o $@
|
||||
carray -cgHs -t uint8_t -G SORTIX_KB_DEFAULT_KBLAYOUT_H --identifier=default_kblayout $< -o $@
|
||||
|
||||
vgafont.h: vgafont.f16
|
||||
carray -gis --uint8_t --guard=VGAFONT_H --identifier=vgafont $< -o $@
|
||||
carray -gHs -t uint8_t -G VGAFONT_H --identifier=vgafont $< -o $@
|
||||
|
||||
*.cpp */*.cpp */*/*.cpp: | kb/default-kblayout.h vgafont.h
|
||||
|
||||
|
|
Loading…
Reference in New Issue