cmake_cpputest_template/inc/misc/attic/temp_transition_helper.c
2025-03-08 17:34:07 -08:00

244 lines
5.6 KiB
C

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char *yes[] = {"SENTINEL_WILL_BE_REPLACED_BY_CMDLINE"}; // "CH32X03x", etc. element 0 is filled in by command-line
const char *no[] = {"CH32V10x", "CH32V30x", "CH32V20x", "CH32X03x", "CH32V003"};
char *WhitePull(const char **sti)
{
const char *st = *sti;
int len = 0;
while ((*st == ' ' || *st == '\t' || *st == '(') && *st)
{
st++;
}
const char *sts = st;
while (*st != ' ' && *st != '\t' && *st != '\n' && *st != ')' && *st != '(' && *st != 0)
{
st++;
len++;
}
if (*st == ')') { st++; }
char *ret = malloc(len + 1);
memcpy(ret, sts, len);
ret[len] = 0;
*sti = st;
return ret;
}
int NYI(const char *s)
{
int ret = 2;
char *wp = WhitePull(&s);
int i;
for (i = 0; i < sizeof(yes) / sizeof(yes[0]); i++)
if (strcmp(yes[i], wp) == 0) ret = 1;
if (ret != 1)
for (i = 0; i < sizeof(no) / sizeof(no[0]); i++)
if (strcmp(no[i], wp) == 0) ret = 0;
free(wp);
return ret;
}
int EvalSpec(const char *spl)
{
int rsofar = 0;
int i;
int lastv = 0;
int lasto = -1;
int ret = 0;
cont:
char *wp = WhitePull(&spl);
int def = -1;
if (strcmp(wp, "defined") == 0) def = 1;
if (strcmp(wp, "!defined") == 0) def = 2;
if (def < 0) return 2;
char *wpn = WhitePull(&spl);
i = NYI(wpn);
// printf( "SPIN: %s/%s/%d/%d/%d\n", wp, wpn, i, def, lasto );
if (i == 2) return 2;
if (def == 2) i = !i;
if (lasto == 1)
{
ret = lastv || i;
}
else if (lasto == 2)
ret = lastv && i;
else
ret = i;
char *wpa = WhitePull(&spl);
// printf( "WPA: \"%s\"\n", wpa );
lastv = ret;
lasto = -1;
// printf( "RET: %d\n", ret );
if (strcmp(wpa, "||") == 0)
{
lasto = 1;
goto cont;
}
else if (strcmp(wpa, "&&") == 0)
{
lasto = 2;
goto cont;
}
else
return ret;
}
// 0 for no
// 1 for yes
// 2 for indeterminate
int NoYesInd(const char *preprocc)
{
int ret;
int ofs = 0;
if (strncmp(preprocc, "#if ", 4) == 0) ofs = 4;
if (strncmp(preprocc, "#elif ", 6) == 0) ofs = 6;
if (ofs)
{
ret = EvalSpec(preprocc + ofs);
// printf( "SPEC: %d\n", ret );
}
else if (strncmp(preprocc, "#ifdef ", 7) == 0)
{
const char *ep = preprocc + 6;
char *wp = WhitePull(&ep);
ret = NYI(wp);
free(wp);
}
else if (strncmp(preprocc, "#ifndef ", 8) == 0)
{
const char *ep = preprocc + 6;
char *wp = WhitePull(&ep);
ret = NYI(wp);
if (ret < 2) ret = !ret;
free(wp);
}
else
ret = 2;
// printf( "%d-> %s\n", ret, preprocc );
return ret;
}
const char *sslineis(const char *line, const char *match)
{
while (*line == ' ' || *line == '\t')
line++;
const char *linestart = line;
while (*line && *match == *line)
{
line++;
match++;
}
if (*match == 0)
return linestart;
else
return 0;
}
int main(int argc, char **argv)
{
if (argc != 3)
{
fprintf(stderr, "Syntax: transition [#define to trigger on] [file to convert]\nNo'd architectures:\n");
int i;
for (i = 0; i < sizeof(no) / sizeof(no[0]); i++)
{
fprintf(stderr, "\t%s\n", no[i]);
}
return -1;
}
yes[0] = argv[1];
FILE *f = fopen(argv[2], "r");
if (!f)
{
fprintf(stderr, "Error: Could not open \"%s\"\n", argv[2]);
return -2;
}
char line[1024];
char *l;
int depth = 0;
// 0 = no
// 1 = yes
// 2 = indeterminate
// 3 = super no. (I.e. after a true #if clause)
int yesnoind[1024];
yesnoind[0] = 1;
while (l = fgets(line, sizeof(line) - 1, f))
{
const char *ss = 0;
int nyi = yesnoind[depth];
int waspre = 0;
if ((ss = sslineis(line, "#if ")) || (ss = sslineis(line, "#ifdef ")) || (ss = sslineis(line, "#ifndef ")))
{
waspre = 1;
// printf( "CHECK: %d/%s\n", depth, l );
nyi = NoYesInd(ss);
depth++;
yesnoind[depth] = nyi;
}
else if ((ss = sslineis(line, "#elif ")))
{
if (nyi != 2)
{
waspre = 1;
if (nyi == 1)
{
nyi = 3;
}
else
{
nyi = NoYesInd(ss);
}
// printf( "ELIF check: %s %d\n", ss, nyi );
yesnoind[depth] = nyi;
}
}
else if ((ss = sslineis(line, "#else")))
{
if (nyi != 2)
{
waspre = 1;
if (yesnoind[depth] == 1)
nyi = 3;
else
nyi = !yesnoind[depth];
yesnoind[depth] = nyi;
}
}
else if ((ss = sslineis(line, "#endif")))
{
waspre = 1;
depth--;
if (depth < 0)
{
fprintf(stderr, "UNTERMD IF\n");
}
}
int thisv = nyi;
int i;
for (i = 0; i <= depth; i++)
{
// printf( "%d", yesnoind[i] );
if (yesnoind[i] == 0 || yesnoind[i] == 3) thisv = 0;
}
// printf( ">>%s", l );
if (thisv != 0 && thisv != 3 && (thisv != 1 || !waspre))
{
printf("%s", l);
}
}
}