2016-07-14 6 views
0

sagen, dass ich eine Datei, die übersetzt TARGET definiert in FEATURE definiert:Halten Sie umfassen Anweisung in vorverarbeiteten Ausgang

// File options.h 
#ifdef TARGET_A 
#define FEATURE_X 
#endif 
#ifdef TARGET_B 
#define FEATURE_Y 
#endif 
struct foo { 
    int a; 
    int b; 
}; 

Und ich habe eine Reihe von Dateien ifdef ‚ed mit FEATURE definiert:

// File foo.c 
#include "options.h" 
#ifdef FEATURE_X 
int x; 
#endif 
#ifdef FEATURE_Y 
int y; 
#endif 

Wie kann ich dann foo.c so vorverarbeiten, dass es die Include-Anweisung verarbeitet, aber in der Datei behält?

Etwas wie:

$ some-pre-process-tool -DTARGET_A -I. -o foo.pp.c foo.c 
$ cat foo.pp.c 
// File foo.c 
#include "options.h" 
int x; 
$ 
+0

können Sie wahrscheinlich bekommst du was du brauchst (wenn auch möglicherweise nicht ganz so einfach) mit [coan] (http://coan2.sourceforge.net/). Viel Glück. – rici

+0

Das habe ich gesehen, als ich nach einer Lösung gegoogelt habe - aber für diesen Zweck sah es nach einem zu großen Aufwand aus. Benutzt du es/weißt du, und ist es gut für diese Art von Dingen? Ich frage, denn die Lösung, mit der ich endete, ist das Entfernen von zufälligen Leerstellen, was lästig ist ... – Allan

+0

Ich habe Coan verwendet und es hat die Probleme gelöst, die ich lösen wollte. Ich weiß nicht, wie einfach es ist, dein Problem zu lösen: Ich denke, du brauchst zwei Schritte, in denen du zuerst das Merkmal definierst, das aus einer Zielauswahl resultiert (was du mit GCC machen kannst, solange du es hast) eine Möglichkeit, die relevanten Feature-Makros nach Namen zu identifizieren) und dann coan verwenden, um selektiv nur diese Makros zu behandeln. – rici

Antwort

-1

Ich habe Angst, dass vorverarbeiteten Datei # nur innerhalb char oder Stringliterale und zu Beginn der Hilfsleitung Datensätze enthalten kann.

2

Erstens, warum möchten Sie #include im vorverarbeiteten Code halten? Planen Sie, es erneut durch den Präprozessor zu laufen, oder ist es nur hilfreich, wenn Sie das Ergebnis lesen?

Sie können bekommen, was Sie wollen mit der gcc Flagge -Wp,-dI. -dI ist hier dokumentiert: https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-dI-1113

Beachten Sie, dass die Ausgabedatei auch #include ‚s aus dem Inneren der Dateien enthalten und alle ihr Kind #include‘ haben s.

+0

Okay, mein Fehler, ich war nicht spezifisch genug ... Ich möchte den Inhalt der enthaltenen Datei nicht in der Ausgabe sehen. Ich habe das Beispiel aktualisiert, um dies zu berücksichtigen. Zu Ihrer Information: Ich möchte das, weil ich versuche, Code zu verstehen, der in vielen verschiedenen Varianten kompiliert ist, und ich möchte die Unterschiede sehen. – Allan

+0

Sie wollen den Inhalt nicht sehen, aber Sie wollen immer noch die # define's in der Include-Datei verwenden, richtig? –

+0

Nein, ich bin nicht daran interessiert, die Definitionen zu sehen. Ich bin nur an dem Pre-Prozessor interessiert, der die Defines auswertet. – Allan

0

Es geben richtig bessere Möglichkeiten, dies zu tun - aber ich am Ende einen kleinen Wrapper-Skript zu schreiben, die die Ausgabe von cpp

#!/usr/bin/env ruby 
# File: pp.rb 

f = open("| cpp -C -dI #{ARGV.join(" ")}") 

# First line 
f.gets =~ /"([^"]+)"/ 
file = $1 
ll = [] 

# Skip "invisible" includes 
while l = f.gets 
    if l =~ /^#\s*1\s*"#{file}"$/ 
     ll = [] 
    else 
     ll.push l 
    end 
end 

inc = false 
skip = false 
skip_line = nil 
ll.each do |l| 
    if inc and l =~ /^#\s*(\d+)\s*"#{file}"$/ 
     inc = false 
     skip = true 
     skip_line = $1.to_i 
    elsif skip and l =~ /^#\s*(\d+)\s*"#{file}"/ 
     inc = false 
     if $1.to_i == skip_line + 1 
      skip = false 
     end 
    elsif skip 
     inc = false 
    elsif l =~ /\s*#\s*include/ 
     puts l 
     inc = true 
    elsif l =~ /^#\s*(\d+)\s*"#{file}"/ 
    else 
     inc = false 
     puts l 
    end 
end 

ich so verarbeiten genannt werden kann:

$ ./pp.rb -DTARGET_A -I. foo.c > foo.pp.c 
$ cat foo.pp.c 
// File foo.c 
#include "options.h" 

int x;