5 use options qw($options);
6 use output qw($output);
8 sub _update_c_position {
11 my $refcolumn = shift;
14 my $column = $$refcolumn;
17 if(s/^[^\n\t\'\"]*//s) {
18 $column += length($&);
23 while(/^./ && !s/^\'//) {
25 $column += length($1);
29 $column += length($1);
32 $column += length($1);
40 while(/^./ && !s/^\"//) {
42 $column += length($1);
46 $column += length($1);
49 $column += length($1);
59 $column = $column + 8 - $column % 8;
64 $$refcolumn = $column;
69 my $refcurrent = shift;
71 my $refcolumn = shift;
73 local $_ = $$refcurrent;
75 my $column = $$refcolumn;
78 _update_c_position($&, \$line, \$column);
85 $$refcolumn = $column;
90 sub parse_c_until_one_of {
91 my $characters = shift;
92 my $refcurrent = shift;
94 my $refcolumn = shift;
97 local $_ = $$refcurrent;
99 my $column = $$refcolumn;
101 if(!defined($line) || !defined($column)) {
102 $output->write("error: \$characters = '$characters' \$_ = '$_'\n");
106 if(!defined($match)) {
108 $match = \$blackhole;
112 while(/^[^$characters]/s) {
115 if(s/^[^$characters\n\t\'\"]*//s) {
121 while(/^./ && !s/^\'//) {
137 $$match .= $submatch;
138 $column += length($submatch);
141 while(/^./ && !s/^\"//) {
157 $$match .= $submatch;
158 $column += length($submatch);
162 $$match .= $submatch;
168 $$match .= $submatch;
169 $column = $column + 8 - $column % 8;
171 $$match .= $submatch;
172 $column += length($submatch);
178 $$refcolumn = $column;
183 my $refcurrent = shift;
185 my $refcolumn = shift;
186 my $refstatements = shift;
187 my $refstatements_line = shift;
188 my $refstatements_column = shift;
190 local $_ = $$refcurrent;
191 my $line = $$refline;
192 my $column = $$refcolumn;
202 parse_c_until_one_of("\\S", \$_, \$line, \$column);
204 my $statements_line = $line;
205 my $statements_column = $column;
210 parse_c_until_one_of("\\{\\}", \$_, \$line, \$column, \$match);
214 $statements .= $match;
230 $$refcolumn = $column;
231 $$refstatements = $statements;
232 $$refstatements_line = $statements_line;
233 $$refstatements_column = $statements_column;
238 sub parse_c_expression {
239 my $refcurrent = shift;
241 my $refcolumn = shift;
242 my $found_function_call_callback = shift;
244 my $line = $$refline;
245 my $column = $$refcolumn;
247 local $_ = $$refcurrent;
249 parse_c_until_one_of("\\S", \$_, \$line, \$column);
251 if(s/^(.*?)(\w+)(\s*)\(//s) {
252 my $begin_line = $line;
253 my $begin_column = $column + length($1) + 1;
256 $column = $begin_column + length("$2$3") - 1;
262 # $output->write("$name: $line.$column: '$_'\n");
266 my @argument_columns;
267 if(!parse_c_tuple(\$_, \$line, \$column, \@arguments, \@argument_lines, \@argument_columns)) {
271 if($name =~ /^sizeof$/) {
274 &$found_function_call_callback($begin_line, $begin_column, $line, $column,
278 while(defined(my $argument = shift @arguments) &&
279 defined(my $argument_line = shift @argument_lines) &&
280 defined(my $argument_column = shift @argument_columns))
282 parse_c_expression(\$argument, \$argument_line, \$argument_column, $found_function_call_callback);
284 } elsif(s/^return//) {
285 $column += length($&);
286 parse_c_until_one_of("\\S", \$_, \$line, \$column);
287 if(!parse_c_expression(\$_, \$line, \$column, $found_function_call_callback)) {
294 _update_c_position($_, \$line, \$column);
298 $$refcolumn = $column;
303 sub parse_c_statement {
304 my $refcurrent = shift;
306 my $refcolumn = shift;
307 my $found_function_call_callback = shift;
309 my $line = $$refline;
310 my $column = $$refcolumn;
312 local $_ = $$refcurrent;
314 parse_c_until_one_of("\\S", \$_, \$line, \$column);
316 if(s/^(?:case\s+)?(\w+)\s*://) {
317 $column += length($&);
318 parse_c_until_one_of("\\S", \$_, \$line, \$column);
321 # $output->write("$line.$column: '$_'\n");
328 my $statements_column;
329 if(!parse_c_block(\$_, \$line, \$column, \$statements, \$statements_line, \$statements_column)) {
332 if(!parse_c_statements(\$statements, \$statements_line, \$statements_column, $found_function_call_callback)) {
335 } elsif(/^(for|if|switch|while)(\s*)\(/) {
336 $column += length("$1$2");
343 my @argument_columns;
344 if(!parse_c_tuple(\$_, \$line, \$column, \@arguments, \@argument_lines, \@argument_columns)) {
348 parse_c_until_one_of("\\S", \$_, \$line, \$column);
349 if(!parse_c_statement(\$_, \$line, \$column, $found_function_call_callback)) {
352 parse_c_until_one_of("\\S", \$_, \$line, \$column);
354 while(defined(my $argument = shift @arguments) &&
355 defined(my $argument_line = shift @argument_lines) &&
356 defined(my $argument_column = shift @argument_columns))
358 parse_c_expression(\$argument, \$argument_line, \$argument_column, $found_function_call_callback);
361 $column += length($&);
362 if(!parse_c_statement(\$_, \$line, \$column, $found_function_call_callback)) {
365 } elsif(parse_c_expression(\$_, \$line, \$column, $found_function_call_callback)) {
368 # $output->write("error '$_'\n");
372 _update_c_position($_, \$line, \$column);
376 $$refcolumn = $column;
381 sub parse_c_statements {
382 my $refcurrent = shift;
384 my $refcolumn = shift;
385 my $found_function_call_callback = shift;
387 my $line = $$refline;
388 my $column = $$refcolumn;
390 local $_ = $$refcurrent;
392 parse_c_until_one_of("\\S", \$_, \$line, \$column);
394 my $statement_line = $line;
395 my $statement_column = $column;
399 while($plevel > 0 || $blevel > 0) {
401 parse_c_until_one_of("\\(\\)\\[\\]\\{\\};", \$_, \$line, \$column, \$match);
403 # $output->write("'$match' '$_'\n");
406 $statement .= $match;
410 } elsif(s/^[\)\]]//) {
413 $output->write("error $plevel: '$statement' '$match' '$_'\n");
424 if(!parse_c_statement(\$statement, \$statement_line, \$statement_column, $found_function_call_callback)) {
427 parse_c_until_one_of("\\S", \$_, \$line, \$column);
429 $statement_line = $line;
430 $statement_column = $column;
433 if($plevel == 1 && $blevel == 1) {
434 if(!parse_c_statement(\$statement, \$statement_line, \$statement_column, $found_function_call_callback)) {
438 parse_c_until_one_of("\\S", \$_, \$line, \$column);
440 $statement_line = $line;
441 $statement_column = $column;
445 } elsif(/^\s*$/ && $statement =~ /^\s*$/ && $match =~ /^\s*$/) {
449 $output->write("error $plevel: '$statement' '$match' '$_'\n");
454 _update_c_position($_, \$line, \$column);
458 $$refcolumn = $column;
464 my $refcurrent = shift;
466 my $refcolumn = shift;
468 # FIXME: Should not write directly
470 my $item_lines = shift;
471 my $item_columns = shift;
473 local $_ = $$refcurrent;
475 my $line = $$refline;
476 my $column = $$refcolumn;
486 my $item_line = $line;
487 my $item_column = $column + 1;
492 parse_c_until_one_of("\\(,\\)", \$_, \$line, \$column, \$match);
500 push @$item_lines, $item_line;
501 push @$item_columns, $item_column;
512 push @$item_lines, $item_line;
513 push @$item_columns, $item_column;
515 parse_c_until_one_of("\\S", \$_, \$line, \$column);
517 $item_column = $column + 1;
529 $$refcolumn = $column;