+sub next_line
+{
+ my $file = shift;
+ my ($in, $out);
+ my $pre_sub_tri_graphs = 1;
+
+ READ: while (not eof IN) {
+ $in .= <IN>;
+ chomp $in;
+ next unless length $in;
+
+ while (length $in) {
+ if ($pre_sub_tri_graphs) {
+ # Preprocess all tri-graphs
+ # including things stuck in quoted string constants.
+ $in =~ s/\?\?=/#/g; # | ??=| #|
+ $in =~ s/\?\?\!/|/g; # | ??!| ||
+ $in =~ s/\?\?'/^/g; # | ??'| ^|
+ $in =~ s/\?\?\(/[/g; # | ??(| [|
+ $in =~ s/\?\?\)/]/g; # | ??)| ]|
+ $in =~ s/\?\?\-/~/g; # | ??-| ~|
+ $in =~ s/\?\?\//\\/g; # | ??/| \|
+ $in =~ s/\?\?</{/g; # | ??<| {|
+ $in =~ s/\?\?>/}/g; # | ??>| }|
+ }
+ if ($in =~ /^\#ifdef __LANGUAGE_PASCAL__/) {
+ # Tru64 disassembler.h evilness: mixed C and Pascal.
+ while (<IN>) {
+ last if /^\#endif/;
+ }
+ next READ;
+ }
+ if ($in =~ /^extern inline / && # Inlined assembler.
+ $^O eq 'linux' && $file =~ m!(?:^|/)asm/[^/]+\.h$!) {
+ while (<IN>) {
+ last if /^}/;
+ }
+ next READ;
+ }
+ if ($in =~ s/\\$//) { # \-newline
+ $out .= ' ';
+ next READ;
+ } elsif ($in =~ s/^([^"'\\\/]+)//) { # Passthrough
+ $out .= $1;
+ } elsif ($in =~ s/^(\\.)//) { # \...
+ $out .= $1;
+ } elsif ($in =~ /^'/) { # '...
+ if ($in =~ s/^('(\\.|[^'\\])*')//) {
+ $out .= $1;
+ } else {
+ next READ;
+ }
+ } elsif ($in =~ /^"/) { # "...
+ if ($in =~ s/^("(\\.|[^"\\])*")//) {
+ $out .= $1;
+ } else {
+ next READ;
+ }
+ } elsif ($in =~ s/^\/\/.*//) { # //...
+ # fall through
+ } elsif ($in =~ m/^\/\*/) { # /*...
+ # C comment removal adapted from perlfaq6:
+ if ($in =~ s/^\/\*[^*]*\*+([^\/*][^*]*\*+)*\///) {
+ $out .= ' ';
+ } else { # Incomplete /* */
+ next READ;
+ }
+ } elsif ($in =~ s/^(\/)//) { # /...
+ $out .= $1;
+ } elsif ($in =~ s/^([^\'\"\\\/]+)//) {
+ $out .= $1;
+ } elsif ($^O eq 'linux' &&
+ $file =~ m!(?:^|/)linux/byteorder/pdp_endian\.h$! &&
+ $in =~ s!\'T KNOW!!) {
+ $out =~ s!I DON$!I_DO_NOT_KNOW!;
+ } else {
+ if ($opt_e) {
+ warn "Cannot parse $file:\n$in\n";
+ $bad_file{$file} = 1;
+ $in = '';
+ $out = undef;
+ last READ;
+ } else {
+ die "Cannot parse:\n$in\n";
+ }
+ }
+ }
+
+ last READ if $out =~ /\S/;
+ }
+
+ return $out;
+}
+
+