0

いくつかの C ファイルを分析し、見つかったすべての #define を出力する必要があります。正規表現ではそれほど難しくありません(たとえば)

def with_regexp(fname):
    print("{0}:".format(fname))
    for line in open(fname):
        match = macro_regexp.match(line)
        if match is not None:
            print(match.groups())

しかし、たとえば、複数行の定義を処理しません。

たとえば、Cでそれを行う良い方法があります

gcc -E -dM file.c

問題は、指定されたファイルの #defines だけでなく、すべての #defines が返されることです。指定されたファイルのみを使用するオプションが見つかりません..

ヒントはありますか?ありがとう

編集: これは不要な定義を除外する最初の解決策であり、定義の名前が実際には元のファイルの一部であることを確認するだけで、完全ではありませんがうまく機能しているようです..

def with_gcc(fname):
    cmd = "gcc -dM -E {0}".format(fname)
    proc = Popen(cmd, shell=True, stdout=PIPE)
    out, err = proc.communicate()
    source = open(fname).read()
    res = set()

    for define in out.splitlines():
        name = define.split(' ')[1]
        if re.search(name, source):
            res.add(define)

    return res
4

3 に答える 3

2

シェルワンライナーの仕事のように聞こえます!

私がやりたい#includeのは、C ファイルからすべての s を削除して (他のファイルからジャンクを取得しないようにするため)、それを に渡し、組み込みgcc -E -dMのすべての#definesを削除することです。_linuxunix

アンダースコアで始まる s がある場合#define、これは約束どおりには機能しません。

こんなふうになります:

sed -e '/#include/d' foo.c | gcc -E -dM - | sed -e '/#define \(linux\|unix\|_\)/d'

おそらく数行の Python でも実行できます。

于 2012-06-15T11:57:56.877 に答える
1

PowerShell では、次のようなことができます。

function Get-Defines {
  param([string] $Path)

  "$Path`:"
  switch -regex -file $Path {
    '\\$' {
      if ($multiline) { $_ }
    }
    '^\s*#define(.*)$' {
      $multiline = $_.EndsWith('\');
      $_
    }
    default {
      if ($multiline) { $_ }
      $multiline = $false
    }
  }
}

次のサンプル ファイルの使用

#define foo "bar"
blah
#define FOO \
  do { \
    do_stuff_here \
    do_more_stuff \
  } while (0)
blah
blah
    #define X

それは印刷します

\x.c:
#define foo "bar"
#define FOO \
  do { \
    do_stuff_here \
    do_more_stuff \
  } while (0)
        #define X

少なくとも慣用的な PowerShell 関数がどのように機能するかは理想的ではありませんが、必要に応じて十分に機能するはずです。

于 2012-06-15T10:31:04.440 に答える
1

純粋な python でこれを行うには、小さなステート マシンを使用します。

def getdefines(fname):
    """ return a list of all define statements in the file """
    lines = open(fname).read().split("\n") #read in the file as a list of lines
    result = [] #the result list
    current = []#a temp list that holds all lines belonging to a define
    lineContinuation = False #was the last line break escaped with a '\'?

    for line in lines:
        #is the current line the start or continuation of a define statement?
        isdefine = line.startswith("#define") or lineContinuation
        if isdefine:
            current.append(line) #append to current result
            lineContinuation = line.endswith("\\") #is the line break escaped?
            if not lineContinuation:
                #we reached the define statements end - append it to result list
                result.append('\n'.join(current))
                current = [] #empty the temp list

    return result
于 2012-06-15T20:14:42.733 に答える