Javascript GCC预处理器如何用空行替换define
我正在尝试将GCC预处理器与Javascript源代码一起使用 我希望保持原始源和输出之间的行号相同。因此,如果输出中的JS代码中有任何错误,行号应该与原始文件中的行号匹配 我希望通过此输入实现以下输出: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' 我怎样才能实现
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 $_'`