Ai-Thinker-Open_RTL8710BX_A.../tools/cmd/linux32/bin2c.c
2020-06-18 22:04:32 +08:00

281 lines
6.7 KiB
C

#pragma warning(disable:4996) // Disable MSVC++ warnings about unsafe functions
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#if defined( _MSC_VER )
int getopt(int argc, char *argv[], const char *optstring);
char *optarg;
int optind = 0;
extern int getopt(int ac, char *av[], const char *optstring);
extern int optind;
extern char *optarg;
#elif defined __GNUC__
#define _GNU_SOURCE
#include <getopt.h>
#else
#error Need definition for getopt
#endif
#include <sys/stat.h>
int opt_bigendian = 0;
int opt_word = 0;
int opt_indent = 8;
int opt_maxcol = 79;
char *opt_utype = NULL;
#define SWAP32(x) ((((x) >> 24) & 0x000000ff) | \
(((x) >> 8) & 0x0000ff00) | \
(((x) << 8) & 0x00ff0000) | \
(((x) << 24) & 0xff000000))
int
convert(char *ifn, char *ofn, char *array_name)
{
FILE *ifp, *ofp;
int c, lc;
struct stat istat;
char *array_type;
int array_len;
if (stat(ifn, &istat) < 0) {
fprintf(stderr, "error: could not stat input file %s: %s\n",
ifn, strerror(errno));
return -1;
}
array_type = (opt_word ? "const unsigned int" : "const unsigned char");
array_len = (opt_word ? ((int)istat.st_size + 3) / 4 : (int)istat.st_size);
if ((ifp = fopen(ifn, "rb")) == NULL) {
fprintf(stderr, "error: could not open input file %s: %s\n",
ifn, strerror(errno));
return -1;
}
if ((ofp = fopen(ofn, "w")) == NULL) {
fclose(ifp);
fprintf(stderr, "error: could not open output file %s: %s\n",
ofn, strerror(errno));
return -1;
}
fprintf(ofp, "/* FILE-CSTYLED */\n");
if (opt_utype != NULL) {
fprintf(ofp,
"#define %s %s_align._%s\n"
"union %s_u {\n"
"%*s%s _%s[%d];\n"
"%*s%s align;\n"
"} %s_align = {{\n",
array_name, array_name, array_name,
array_name,
opt_indent, "", array_type, array_name, array_len,
opt_indent, "", opt_utype,
array_name);
} else {
fprintf(ofp,
"%s %s[%d] = {\n",
array_type, array_name, array_len);
}
lc = 0;
if (opt_word) {
while ((c = fgetc(ifp)) != EOF) {
int i;
unsigned int val = (unsigned int)c;
for (i = 0; i < 3; i++) {
if ((c = getc(ifp)) == EOF)
c = 0;
val = (val << 8) | (unsigned int)c;
}
if (!opt_bigendian)
val = SWAP32(val);
if (lc > 0 && lc >= opt_maxcol - 12) {
fprintf(ofp, ",\n");
lc = 0;
}
if (lc == 0)
lc += fprintf(ofp, "%*s0x%08x", opt_indent, "", val);
else
lc += fprintf(ofp, ", 0x%08x", val);
}
} else {
while ((c = getc(ifp)) != EOF) {
if (lc > 0 && lc >= opt_maxcol - 5) {
fprintf(ofp, ",\n");
lc = 0;
}
if (lc == 0)
lc += fprintf(ofp, "%*s%d", opt_indent, "", c);
else
lc += fprintf(ofp, ", %d", c);
}
}
if (lc > 0)
fprintf(ofp, "\n");
if (opt_utype != NULL)
fprintf(ofp, "}");
fprintf(ofp, "};\n");
(void)fclose(ifp);
if (fclose(ofp) < 0) {
fprintf(stderr, "error: could not close output file %s: %s\n",
ofn, strerror(errno));
return -1;
}
return 0;
}
void
usage(void)
{
fprintf(stderr,
"Usage: bin2c [-w] [-eb] [-u type] [-i indent] [-m maxcol]\n"
" <input> <output> <arrayname>\n"
" -w Output 32-bit ints instead of bytes\n"
" -eb Output for big-endian CPU (when used with -w)\n"
" -u type Output a union with specified alignment type\n"
" -i indent Indentation amount\n"
" -m maxcol Maximum output columns to use\n");
exit(1);
}
int
main(int argc, char **argv)
{
int c;
while ((c = getopt(argc, argv, "we:u:i:m:")) > 0)
switch (c) {
case 'w':
opt_word = 1;
break;
case 'e':
opt_bigendian = (optarg[0] == 'b');
break;
case 'u':
opt_utype = optarg;
break;
case 'i':
opt_indent = atoi(optarg);
break;
case 'm':
opt_maxcol = atoi(optarg);
break;
default:
usage();
}
if (optind + 3 != argc)
usage();
if (convert(argv[optind], argv[optind + 1], argv[optind + 2]) < 0)
exit(1);
exit(0);
}
#if defined( _MSC_VER )
// From XGetopt.cpp Version 1.2
//
// Author: Hans Dietrich
// hdietrich2@hotmail.com
//
// Description:
// XGetopt.cpp implements getopt(), a function to parse command lines.
//
// History
// Version 1.2 - 2003 May 17
// - Added Unicode support
//
// Version 1.1 - 2002 March 10
// - Added example to XGetopt.cpp module header
//
// This software is released into the public domain.
// You are free to use it in any way you like.
//
// This software is provided "as is" with no expressed
// or implied warranty. I accept no liability for any
// damage or loss of business that this software may cause.
//
///////////////////////////////////////////////////////////////////////////////
int getopt(int argc, char *argv[], const char *optstring)
{
char c;
char *cp;
static char *next = NULL;
if (optind == 0)
next = NULL;
optarg = NULL;
if (next == NULL || *next == '\0')
{
if (optind == 0)
optind++;
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
{
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
if (strcmp(argv[optind], "--") == 0)
{
optind++;
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
next = argv[optind];
next++; // skip past -
optind++;
}
c = *next++;
cp = strchr(optstring, c);
if (( cp == NULL ) || ( c == ':') )
return '?';
cp++;
if ( *cp == ':')
{
if (*next != '\0')
{
optarg = next;
next = NULL;
}
else if (optind < argc)
{
optarg = argv[optind];
optind++;
}
else
{
return '?';
}
}
return c;
}
#endif /* if defined( _MSC_VER ) */