Javascript GCC预处理器如何用空行替换define

Javascript GCC预处理器如何用空行替换define,javascript,gcc,c-preprocessor,preprocessor,preprocessor-directive,Javascript,Gcc,C Preprocessor,Preprocessor,Preprocessor Directive,我正在尝试将GCC预处理器与Javascript源代码一起使用 我希望保持原始源和输出之间的行号相同。因此,如果输出中的JS代码中有任何错误,行号应该与原始文件中的行号匹配 我希望通过此输入实现以下输出: Line 1 // comment Line 2 #define ASDF 'asdf' Line 3 Line 4 var asdf = ASDF 输出: Line 1 // comment Line 2 Line 3 Line 4 var asdf = 'asdf' 我怎样才能实现

我正在尝试将GCC预处理器与Javascript源代码一起使用

我希望保持原始源和输出之间的行号相同。因此,如果输出中的JS代码中有任何错误,行号应该与原始文件中的行号匹配

我希望通过此输入实现以下输出:

Line 1 // comment
Line 2 #define ASDF 'asdf'
Line 3
Line 4 var asdf = ASDF
输出:

Line 1 // comment
Line 2 
Line 3 
Line 4 var asdf = 'asdf'
我怎样才能实现上述目标

到目前为止,我已经尝试:

/usr/bin/cpp-p-undef-Wundef-std=c99-nostdinc-Wtrigraphs-fdollars in identifiers-traditional cpp-E-C$infire-o$OUTFILE

传统的cpp保留空格,-E保留注释

是否可以用空行替换预处理器指令中的所有行?

正在运行

gcc-xc file.c-E-P-o file.txt 对着三条线

定义ASDF“ASDF” var asdf=asdf 产生1行

var asdf = 'asdf'
因此,并不是所有请求的行都是空的,而是它们被完全删除了。也许这符合你的目的?对于传统的cpp,有很多空行,不知道它们来自哪里。。。添加-v以查看gcc发出的子命令:

…/cc1-E-quiet-v-P-o file.txt 附录1:为了保留评论,添加-C

cpp file.c-E-p-c-nostinc


我需要-nostdinc,因为否则gcc将包含/usr/include/stdc predef.h。但是空行仍然会被删除。

我创建了一个Perl脚本来创建一个中间文件,该文件创建并确保正确的空行数,以便在预处理器运行后,输出将具有相同的行数,并与输入匹配行号

这是一个草案版本,有一些未完成/未使用的部分,但它已经可以解决上述问题中的主要问题,并且可能对处于相同情况的其他人有用。 到目前为止,我只对它进行了最低限度的测试

我将它与Makefile一起使用,下面是一个示例

保留\u预处理器\u emptylines.pl


谢谢,但是我想保持原始源和输出之间的行号相同。因此,如果输出中的JS代码中有任何错误,行号应该与原始文件中的行号匹配。我会用这个更新这个问题。如果没有参数-traditional cpp,它将删除所有空行和所有额外的空格。注释应该保留,因为它们可以是多行注释,如果删除它们,行号将不匹配,因此注释也应该保留。@gregn3:我添加了一个-C保留注释的注释。我创建了一个Perl脚本来创建预处理器的中间输入,这将产生正确的输出。我已经在下面发布了它。这是一项正在进行的工作,但我想与大家分享。我在identificates-C中找到了原始命令/usr/bin/cpp-P-unde-Wundef-std=c99-nostdinc-Wtrigraphs-fdollars,但是它本身并不足以保留行号。
#!/usr/bin/perl


# example usage of PPEXTRALINES:
#
#  #define SOMEFUNC__PPEXTRALINES_4_ \
#  function hello () \
#  { \
#    console.log ('hello world') \
#  } 
#
# # the above will be replaced with a single line
# SOMEFUNC__PPEXTRALINES_4_
#
#

# expecting the input filename on a line by itself preceding the input lines
my $input_filename;


my $multiline_sig = '__PPEXTRALINES_(\d+)_';

my $ensure_n_empty_lines_follow = 0;

my $line_num = -1 -1; # -1 gives the correct line numbers in the error message below... intended 0 here originally
                      # the second -1 is for the input filename that precedes the input


while (<STDIN>)
{
    $line_num++;

    if ($line_num == -1)
    {
        $input_filename = $_;
        chomp $input_filename;
        next;
    }


    my $is_empty_line = ($_ =~ /^\s*$/gm);
    if ($ensure_n_empty_lines_follow > 0)
    {
        if (!$is_empty_line)
        {
            chomp;
            my $n = $ensure_n_empty_lines_follow;
            my $es = $n == 1 ? '' : 's';
            print STDERR '(' . __FILE__ . "): \"$input_filename\": error on line $line_num: expected $n empty line$es here, but found non-empty line\nline: \"$_\"\n";
            exit -1
        }
        else
        {
            # ok ,remove this empty line, because it will be replaced by the contents of the preceding macro
            $ensure_n_empty_lines_follow--;
            next;
        }
    }

    #my $is_directiveline = ($_ =~ /^\s*([#!][ \t]{1,}?([A-z]{2,})[\s]{1,}?([A-z]{2,}[\s]{1,}?)?)([\\(]?[^\s\\)]{1,}[\\)]?)?/);
    my $is_directiveline = ($_ =~ /^\s*[#!][ \t]*([A-z]{2,})\s+([A-z0-9_]{2,})\b/);
    my $directive_name = $1;
    my $second_word = $2;
    my $has_multiline_sig = ($_ =~ /$multiline_sig/);
    my $n_extra_lines = int ($1);

    if ($has_multiline_sig)
    {
        if ($is_directiveline)
        {
            my $is_the_definition = (($directive_name eq 'define') && ($second_word =~ /$multiline_sig/));

            if ($is_the_definition)
            {
                # insert that number of lines + 1 above it
                print ("\n" x ($n_extra_lines + 1));
            }
            else
            {
                # otherwise it might be used in another macro, we should ignore it there

                # print one empty line above it, since it's a macro line
                print ("\n");
            }
        }
        else
        {   # is a usage
            # ensure at least ($n_extra_lines + 1) empty lines follow it.
            # fail with error if not.
            # then remove those empty lines, so they will be replaced by the macro's contents


            # this seems unnecessary, only would be needed if the macro expands to multiple lines, which the example above doesn't
            # uncomment the below line to enable ensuring enough empty lines follow the macro
            # might need to create a new special name for these
            # the current PPEXTRALINES one only supports a multiple-line definition, but single line expansion
            #$ensure_n_empty_lines_follow = $n_extra_lines + 1;
        }
    }
    elsif ($is_directiveline)
    {   # other macro line
        # print one empty line above it
        print ("\n");
    }

    print $_;   
}
%.js : %.P.js
    echo "$<" | cat - "$<" | ./keep_preprocessor_emptylines.pl > "$(patsubst %.P.js,%.Pke.js,$<)" 
    /usr/bin/cpp -P -undef -Wundef -std=c99 -nostdinc -Wtrigraphs -fdollars-in-identifiers -traditional-cpp -E -C "$(patsubst %.P.js,%.Pke.js,$<)" -o "$@" 
    rm "$(patsubst %.P.js,%.Pke.js,$<)" 
make `ls -1 *.P.js | perl -ne '$_ =~ s/\.P\.js$/\.js/; print $_'`