eolian: more intuitive generation options and mrge impls into .c

Previously the output base name used to include extension, now
you don't need to specify an extension and it's determined from
the input file name instead.

Also, implementation boilerplate used to merge with .eo.c before,
which made no sense. Now it's merged with .c instead when it
exists or makes a new .c file when it doesn't.
This commit is contained in:
Daniel Kolesa 2017-11-10 14:46:00 +01:00
parent 7c0f1fdd34
commit 753359230a
1 changed files with 58 additions and 21 deletions

View File

@ -44,19 +44,23 @@ _print_usage(const char *progn, FILE *outf)
" -v print version and exit\n"
"\n"
"Available types:\n"
" h: C header file (.h)\n"
" l: Legacy C header file (.legacy.h)\n"
" s: Stub C header file (.stub.h)\n"
" c: C source file (.c)\n"
" i: Implementation file (added into .c)\n"
" h: C header file (.eo.h/.eot.h)\n"
" l: Legacy C header file (.eo.legacy.h/.eot.legacy.h)\n"
" s: Stub C header file (.eo.stub.h/.eot.stub.h)\n"
" c: C source file (.eo.c)\n"
" i: Implementation file (.c, merged with existing)\n"
"\n"
"By default, the 'hc' set is used ('h' for .eot files).\n"
"Output filenames are determined from input .eo filename.\n"
"Default filenames include input extension. (e.g. \".eo.c\")\n"
"Default output path is where the input file is.\n\n"
"Also, specifying a type-dependent input file automatically\n"
"adds it to generated files, so if you specify those, you\n"
"don't need to explicitly specify -g for those types anymore.\n");
"don't need to explicitly specify -g for those types anymore.\n\n"
"Explicit output base name is without extension. The extension\n"
"is determined from the input file name. If that is not possible\n"
"for some reason, it defaults to \".eo\". Obviously, this does not\n"
"affect specific filenames (-o x:y) as these are full names.\n"
"Implementation files are a special case (no \".eo\" added).\n");
}
static void
@ -100,20 +104,44 @@ _try_set_out(char t, char **outs, const char *val, int *what)
return EINA_TRUE;
}
static void _fill_all_outs(char **outs, const char *val)
static void _fill_all_outs(char **outs, const char *val, char *base)
{
size_t vlen = strlen(val);
const char *ext = strrchr(val, '.');
if (!ext)
ext = ".eo";
char *basen = base;
if (!basen)
{
basen = strdup(val);
char *p = strrchr(basen, '.');
if (p) *p = '\0';
}
size_t blen = strlen(basen),
elen = strlen(ext);
for (size_t i = 0; i < (sizeof(_dexts) / sizeof(char *)); ++i)
{
if (outs[i])
continue;
size_t dlen = strlen(_dexts[i]);
char *str = malloc(vlen + dlen + 1);
memcpy(str, val, vlen);
memcpy(str + vlen, _dexts[i], dlen);
str[vlen + dlen] = '\0';
outs[i] = str;
}
{
if (outs[i])
continue;
size_t dlen = strlen(_dexts[i]);
char *str = malloc(blen + elen + dlen + 1);
char *p = str;
memcpy(p, basen, blen);
p += blen;
if ((1 << i) != GEN_C_IMPL)
{
memcpy(p, ext, elen);
p += elen;
}
memcpy(p, _dexts[i], dlen);
p[dlen] = '\0';
outs[i] = str;
}
if (!base)
free(basen);
}
static Eina_Strbuf *
@ -406,6 +434,7 @@ main(int argc, char **argv)
eina_log_timing(_eolian_gen_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT);
char *outs[5] = { NULL, NULL, NULL, NULL, NULL };
char *basen = NULL;
int gen_what = 0;
for (int opt; (opt = getopt(argc, argv, "I:g:o:hv")) != -1;)
@ -459,7 +488,12 @@ main(int argc, char **argv)
goto end;
}
}
else _fill_all_outs(outs, optarg);
else
{
if (basen)
free(basen);
basen = strdup(optarg);
}
break;
case 'h':
_print_usage(argv[0], stdout);
@ -495,7 +529,7 @@ main(int argc, char **argv)
goto end;
}
_fill_all_outs(outs, input);
_fill_all_outs(outs, input, basen);
const char *eobn = _get_filename(input);
@ -524,8 +558,11 @@ end:
eina_log_timing(_eolian_gen_log_dom, EINA_LOG_STATE_START, EINA_LOG_STATE_SHUTDOWN);
eina_log_domain_unregister(_eolian_gen_log_dom);
}
for (size_t i = 0; i < (sizeof(_dexts) / sizeof(char *)); ++i)
free(outs[i]);
free(basen);
eolian_shutdown();
eina_shutdown();