J'essaie de trouver un moyen de lire un fichier d'en-tête C qui contient des # define et de convertir ces macros en variables bash accessibles par un script shell.

Voici ce que j'ai essayé en premier:

gcc -E -dM header_file.h|grep '^#define'|awk '{var=$2;$1=$2="";sub(/^[ \t]+/, "");print "export " var "=\"" $0 "\""}' > /tmp/tmp.sh
source /tmp/tmp.sh

Ce qui a fonctionné, mais je n'aimais vraiment pas que je génère ce fichier temporaire

Ce que j'ai essayé ensuite était similaire, dans l'espoir de me débarrasser du fichier temporaire:

gcc -E -dM  header_file.h|grep '^#define'|awk '{var=$2;$1=$2="";sub(/^[ \t]+/, "");print "export " var "=\"" $0 "\""}' |while read i
do
$i
done

Cela n'a pas fonctionné, cependant ... Il semble qu'il devrait y avoir une autre façon de faire cela, mais je ne peux pas y penser, et je suis presque sûr qu'une fois que quelqu'un publiera comment je vais me sentir vraiment stupide, mais J'apprécierais toujours le kickstart que tout le monde peut offrir pour me diriger dans la bonne direction.

2
markt1964 25 nov. 2017 à 10:38

3 réponses

Meilleure réponse

Une solution sophistiquée:

#!/bin/bash

source <(\ 
    sed -r '{
        /^#define/!d
        /#define[ \t]*[^ \t]*$/d
        s/[^ \t]*[ \t]*([^ \t]*)[ \t]*(.*)/\1="\2"/
        /(""|\([^\)]*\))/d
    }' <(gcc -E -dM HEADERFILE)
)

/^#define/!d conserve les lignes commençant par #define

/#define[ \t]*[^ \t]*$/d supprime les lignes avec des définitions de macro vides

s/[^ \t]*[ \t]*([^ \t]*)[ \t]*(.*)/\1=\2/ crée des égalités

, le processus est remplacé et le descripteur peut être obtenu.

3
ntj 25 nov. 2017 à 20:53

La syntaxe source <(...) nécessite Bash 4, ne fonctionne pas dans Bash 3 ou une version antérieure.

Utiliser eval est mal. Et en fait source - ce n'est pas mieux de toute façon.

Cela devrait être raisonnablement sûr et portable:

while read -r def var val; do
    printf -v $var "$val"
done < <(gcc -E -dM header_file.h | grep -E '^#define[ \t]+[a-zA-Z_][0-9a-zA-Z_]+')
1
janos 25 nov. 2017 à 11:27
eval $(sed -n 's/^#define  *\([^ ]*\)  *\(.*\) *$/export \1=\2/p' file.c)
1
perreal 25 nov. 2017 à 09:46
47483672