Last active
March 6, 2024 19:52
-
-
Save imaami/5d81c30861dac2944af782789e520e59 to your computer and use it in GitHub Desktop.
#template<>
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
file="$1" | |
[[ -e "$file" ]] || exit 1 | |
declare -r B='[[:blank:]]' | |
declare -a sed_args=() | |
lines="$(grep -En "^$B*#$B*template$B*<$B*[^>[:blank:]]+($B+-[DU][^>[:blank:]]+)*$B*>$B*(/[/\*].*)?$" "$file")" | |
while read -r line; do | |
[[ $line ]] || continue | |
lnum="${line%%:*}" | |
line="${line#*:}" | |
prefix="${line%%template*}" | |
hdr_file=$(sed -En "s/^[^<]+<$B*([^>[:blank:]]+).*$/\1/p" <<< "$line") | |
raw_opt=($(sed -En "s/^[^<]+<$B*[^>[:blank:]]+(($B+-[DU][^>[:blank:]]+)*)$B*>.*$/\1/p" <<< "$line")) | |
declare -a opts=() | |
for raw in "${raw_opt[@]}"; do | |
if [[ "$raw" == -D* ]]; then | |
name="${raw:2}" | |
name="${name%%=*}" | |
opts+=("-D$name") | |
elif [[ "$raw" == -U* ]]; then | |
name="${raw:2}" | |
opts+=("-U$name") | |
fi | |
done | |
out="" | |
for opt in "${opts[@]}"; do | |
name="${opt:2}" | |
out+="${prefix}pragma push_macro(\"$name\")\n" | |
done | |
for raw in "${raw_opt[@]}"; do | |
name="${raw:2}" | |
name="${name%%=*}" | |
if [[ "$raw" == -D* ]]; then | |
value="${raw/#-D$name}" | |
value="${value/#=}" | |
out+="${prefix}define $name${value:+ $value}\n" | |
elif [[ "$raw" == -U* ]]; then | |
out+="${prefix}undef $name\n" | |
fi | |
done | |
out+="${prefix}include \"$hdr_file\"\n" | |
for opt in "${opts[@]}"; do | |
name="${opt:2}" | |
out+="${prefix}pragma pop_macro(\"$name\")\n" | |
done | |
out="${out%\\n}" | |
out="${out//\//\\/}" | |
sed_args+=("-e '${lnum}s/.*/${out}/'") | |
done <<< "$lines" | |
if (( (n = ${#sed_args[@]}) )); then | |
cmnd='sed' | |
for ((i = n - 1; i >= 0; i--)) ; do | |
cmnd+=" ${sed_args[i]}" | |
done | |
eval "$cmnd ${file@Q}" | |
else | |
cat "$file" | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
override BIN := test | |
override SRC := test.c msg.c | |
override OBJ := $(SRC:%=%.o) | |
override DEP := $(SRC:%=%.d) | |
CFLAGS := -O2 -march=native -mtune=native -flto | |
$(BIN): $(OBJ) | |
$(CC) $(CFLAGS) -o $@ $^ | |
msg.c.o: c_template.sh | |
%.c.o: %.c | |
$(if $(filter c_template.sh,$^),./c_template.sh $< | $(CC) -xc -,$(CC) $<) $(CFLAGS) -o $@ -I. -c -MMD -MQ $@ -MF $<.d | |
-include $(DEP) | |
.PHONY: clean | |
clean: | |
rm -f $(BIN) $(OBJ) $(DEP) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stddef.h> | |
#include <stdint.h> | |
#include "msg.h" | |
#define VAR(line, data) char SYM_(line)[sizeof(data)] | |
#define SYM(line) SYM_(line) | |
#define SYM_(line) str##line | |
static const union { | |
struct { | |
#template<msg_defs.h -D_S(n,s)=VAR(__LINE__,s);> | |
}; | |
char data[0]; | |
} str = { { | |
#template<msg_defs.h -D_S(n,s)=s,> | |
} }; | |
typedef __typeof__(_Generic( | |
&(char[1u + (sizeof(str) - 1u > 0xfful) | |
+ (sizeof(str) - 1u > 0xfffful) | |
+ (sizeof(str) - 1u > 0xfffffffful)]){0} | |
, char(*)[1]: (uint8_t)0, char(*)[2]: (uint16_t)0 | |
, char(*)[3]: (uint32_t)0, char(*)[4]: (uint64_t)0 | |
)) off_type; | |
static const off_type off[] = { | |
#template<msg_defs.h -D_S(n,s)=[n]=offsetof(__typeof__(str),SYM(__LINE__)),> | |
}; | |
char const *msg_string (enum msg msg) { | |
return &str.data[off[msg]]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MSG_H_ | |
#define MSG_H_ | |
enum msg { MSG1, MSG2, MSG3 }; | |
extern char const *msg_string (enum msg msg); | |
#endif /* MSG_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_S(MSG1, "first message string") | |
_S(MSG3, "third message string") | |
_S(MSG2, "second message string") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "msg.h" | |
int main (void) { | |
printf("[MSG1] = \"%s\"\n[MSG2] = \"%s\"\n[MSG3] = \"%s\"\n", | |
msg_string(MSG1), msg_string(MSG2), msg_string(MSG3)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment