Skip to content

Commit 4feada5

Browse files
committed
tools: xxd-c: new helper tool to convert files to C static array defs
this tool is a simple clone of 'xxd -i' function to be used by Fluent Bit build system to integrate static configuration files. Signed-off-by: Eduardo Silva <eduardo@treasure-data.com>
1 parent 577567f commit 4feada5

File tree

3 files changed

+216
-0
lines changed

3 files changed

+216
-0
lines changed

tools/xxd-c/CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
set(src
2+
xxd-c.c
3+
)
4+
5+
add_executable(xxd-c ${src})

tools/xxd-c/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# xxd-c utility
2+
3+
xxd-c is a tool created originally to create static array definitions from a text file. It's a simple clone of LLVM xxd utility.
4+
5+
Originally created to be used by Fluent Bit CMake build system.
6+

tools/xxd-c/xxd-c.c

+205
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2+
3+
/* Fluent Bit / xxd-c
4+
* ==================
5+
* Copyright (C) 2015-2018 Treasure Data Inc.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
20+
/*
21+
* xxd-c is a really simple tool to convert text files to C static
22+
* arrays definitions, it emulate the behavior of 'xxd -i' but with
23+
* some other features required by Fluent Bit to ingest static
24+
* configuration files and do registration in a proper way.
25+
*/
26+
27+
#include <stdio.h>
28+
#include <stdlib.h>
29+
#include <string.h>
30+
#include <getopt.h>
31+
#include <unistd.h>
32+
33+
#define XXDC_CHUNK 1024
34+
35+
int xxdc_verbose;
36+
37+
static void xxdc_help(int rc)
38+
{
39+
fprintf(stderr, "Usage: xxd-c -i FILE_INPUT [-o FILE_OUTPUT] "
40+
"[-s NAME]\n\n");
41+
fprintf(stderr, " -i input text file\n");
42+
fprintf(stderr, " -o output C header file\n");
43+
fprintf(stderr, " -s C struct array name name\n");
44+
fprintf(stderr, " -h print this help\n\n");
45+
exit(rc);
46+
}
47+
48+
static char *xxdc_struct_name(char *in, char *name)
49+
{
50+
int i;
51+
int len;
52+
char *p;
53+
char *sname = NULL;
54+
55+
if (name) {
56+
sname = strdup(name);
57+
}
58+
else {
59+
p = strrchr(in, '/');
60+
if (!p) {
61+
sname = strdup(in);
62+
}
63+
else {
64+
sname = strdup(p);
65+
}
66+
}
67+
68+
if (!sname) {
69+
perror("strdup");
70+
return NULL;
71+
}
72+
73+
/* sanitize name */
74+
len = strlen(sname);
75+
for (i = 0; i < len; i++) {
76+
if (sname[i] == '-' || sname[i] == '.') {
77+
sname[i] = '_';
78+
}
79+
}
80+
return sname;
81+
}
82+
83+
static int xxdc_convert(char *in, char *out, char *name)
84+
{
85+
int i;
86+
int len;
87+
size_t size;
88+
char tmp[128];
89+
char *sname;
90+
char buf[XXDC_CHUNK];
91+
FILE *f_in;
92+
FILE *f_out;
93+
94+
/* If no output file is given just print to stdout */
95+
if (!out) {
96+
f_out = stdout;
97+
}
98+
else {
99+
f_out = fopen(out, "w");
100+
if (!f_out) {
101+
perror("fopen");
102+
fprintf(stderr, "error opening output file: %s\n", out);
103+
return -1;
104+
}
105+
}
106+
107+
f_in = fopen(in, "r");
108+
if (!f_in) {
109+
perror("fopen");
110+
fprintf(stderr, "error opening input file: %s\n", in);
111+
return -1;
112+
}
113+
114+
/* Get target struct name */
115+
sname = xxdc_struct_name(in, name);
116+
if (!sname) {
117+
fclose(f_in);
118+
if (out) {
119+
fclose(f_out);
120+
}
121+
return -1;
122+
}
123+
124+
len = snprintf(tmp, sizeof(tmp) - 1,
125+
"unsigned char __%s[] = {", sname);
126+
fwrite(tmp, len, 1, f_out);
127+
while ((size = fread(buf, sizeof(char), XXDC_CHUNK, f_in)) > 0) {
128+
for (i = 0; i < size; i++) {
129+
if (i % 12 == 0) {
130+
fwrite("\n ", 5, 1, f_out);
131+
}
132+
len = snprintf(tmp, sizeof(tmp) - 1,
133+
"0x%02x%s ", buf[i], (i+1 < size) ? ",": "");
134+
fwrite(tmp, len, 1, f_out);
135+
}
136+
}
137+
fwrite("\n};\n", 4, 1, f_out);
138+
fclose(f_in);
139+
140+
if (out) {
141+
fclose(f_out);
142+
}
143+
144+
if (xxdc_verbose) {
145+
fprintf(stderr, "[xxdc] converted '%s' to '%s'\n",
146+
in, out ? out: "STDOUT");
147+
}
148+
return 0;
149+
}
150+
151+
int main(int argc, char **argv)
152+
{
153+
int opt;
154+
int ret;
155+
char *in = NULL;
156+
char *out = NULL;
157+
char *stname = NULL;
158+
159+
/* Setup long-options */
160+
static const struct option long_opts[] = {
161+
{ "input", required_argument, NULL, 'i' },
162+
{ "output", optional_argument, NULL, 'o' },
163+
{ "stname", optional_argument, NULL, 's' },
164+
{ "verbose", no_argument , NULL, 'v' },
165+
{ "help", required_argument, NULL, 'h' },
166+
{ NULL, 0, NULL, 0 }
167+
};
168+
169+
xxdc_verbose = 0;
170+
171+
while ((opt = getopt_long(argc, argv, "i:o:s:vh",
172+
long_opts, NULL)) != -1) {
173+
switch (opt) {
174+
case 'i':
175+
in = strdup(optarg);
176+
break;
177+
case 'o':
178+
out = strdup(optarg);
179+
break;
180+
case 's':
181+
stname = strdup(optarg);
182+
break;
183+
case 'v':
184+
xxdc_verbose = 1;
185+
break;
186+
case 'h':
187+
xxdc_help(EXIT_SUCCESS);
188+
default:
189+
xxdc_help(EXIT_FAILURE);
190+
}
191+
}
192+
193+
if (!in) {
194+
fprintf(stderr, "Error: input file not set\n\n");
195+
xxdc_help(EXIT_FAILURE);
196+
}
197+
198+
ret = xxdc_convert(in, out, stname);
199+
200+
free(in);
201+
free(out);
202+
free(stname);
203+
204+
return ret;
205+
}

0 commit comments

Comments
 (0)