|
#!/usr/bin/perl |
|
|
|
use strict; |
|
use warnings; |
|
use Getopt::Std; |
|
|
|
my %opts; |
|
getopts('i:o:', \%opts); |
|
|
|
my $input_fh = \*STDIN; |
|
my $output_fh = \*STDOUT; |
|
|
|
if (defined $opts{i}) { |
|
open($input_fh, '<', $opts{i}) or die "Cannot open input file $opts{i}: $!\n"; |
|
} |
|
|
|
if (defined $opts{o}) { |
|
open($output_fh, '>', $opts{o}) or die "Cannot open output file $opts{o}: $!\n"; |
|
} |
|
|
|
=head1 NAME |
|
|
|
ErrorPP.pl - Generate error and warning functions based on DSL directives |
|
|
|
=head1 SYNOPSIS |
|
|
|
ErrorPP.pl [-i input_file] [-o output_file] |
|
|
|
=head1 DESCRIPTION |
|
|
|
This script reads DSL (Domain-Specific Language) directives from the input file or |
|
standard input and generates error and warning functions based on the provided directives. |
|
The DSL supports two types of directives: '#error-decl' and '#warning-decl'. The generated |
|
functions have colorful output for errors and warnings using ANSI escape codes. |
|
|
|
=head1 DSL DIRECTIVES |
|
|
|
=over 4 |
|
|
|
=item B<#error-decl> |
|
|
|
#error-decl f::function_name, m::"Error message", c::exit_code |
|
|
|
Declares an error function with the specified name, error message, and optional exit code. |
|
|
|
=item B<#warning-decl> |
|
|
|
#warning-decl f::function_name, m::"Warning message" |
|
|
|
Declares a warning function with the specified name and warning message. |
|
|
|
=back |
|
|
|
=head1 GENERATED FUNCTIONS |
|
|
|
The script generates the following types of functions: |
|
|
|
=over 4 |
|
|
|
=item B<Error Functions> |
|
|
|
void function_name(); |
|
|
|
Generates error functions with colorful output for error messages. The function exits |
|
with the specified exit code if provided. |
|
|
|
=item B<Warning Functions> |
|
|
|
void function_name(); |
|
|
|
Generates warning functions with colorful output for warning messages. |
|
|
|
=back |
|
|
|
=head1 EXAMPLE |
|
|
|
#error-decl f::"file_open_error", m::"Error occurred because of IO", c::22 |
|
#warning-decl f::"reallocation_warning", m::"This reallocation may be wrong" |
|
|
|
int main() { |
|
// Your code here |
|
|
|
// Generating errors and warnings |
|
file_open_error(); |
|
reallocation_warning(); |
|
|
|
return 0; |
|
} |
|
|
|
=head1 AUTHOR |
|
|
|
Chubak Bidpaa |
|
|
|
=head1 COPYRIGHT |
|
|
|
NU GENERAL PUBLIC LICENSE |
|
Version 3, June 2007 |
|
|
|
Preamble: |
|
The GNU General Public License is a free, copyleft license for software and other kinds of works. |
|
|
|
Terms and Conditions: |
|
- You are free to run, modify, and distribute the software. |
|
- Source code access is required for any distributed modifications. |
|
- Derivative works must be distributed under the GPL. |
|
|
|
Additional Permissions: |
|
- Propagation of covered works is permitted without modification. |
|
- Adding exceptions to this license is allowed. |
|
|
|
Disclaimer of Warranty: |
|
The software is provided without any warranty. |
|
|
|
Full License Text: |
|
The complete text of the GNU General Public License version 3.0 can be found at [GNU GPL v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html). |
|
|
|
=back |
|
|
|
=cut |
|
|
|
my @error_decls; |
|
my @warning_decls; |
|
my @bypasses; |
|
|
|
my @declarations; |
|
my @error_definitions; |
|
my @warning_definitions; |
|
|
|
while (<$input_fh>) { |
|
if (/^#error-decl\s+f::([A-Za-z_][A-Za-z0-9_]*)\s*,\s*m::"(.*)"\s*,\s*c::([0-9]+)\s*$/) { |
|
push @error_decls, { |
|
func_name => $1, |
|
message => $2, |
|
exit_code => $3 + 0, |
|
}; |
|
} elsif (/^#warning-decl\s+f::([A-Za-z_][A-Za-z0-9_]*)\s*,\s*m::"(.*)"\s*$/) { |
|
push @warning_decls, { |
|
func_name => $1, |
|
message => $2, |
|
}; |
|
} else { |
|
push @bypasses, $_; |
|
} |
|
} |
|
|
|
sub generate_declarations { |
|
my ($decls) = @_; |
|
foreach my $decl (@$decls) { |
|
push @declarations, "void $decl->{func_name}(void);"; |
|
} |
|
} |
|
|
|
sub generate_error_functions { |
|
my ($errors) = @_; |
|
foreach my $error (@$errors) { |
|
push @error_definitions, <<"END_ERROR"; |
|
void $error->{func_name}() { |
|
fprintf(stderr, "\\e[1;31mError:\\e[0m $error->{message}\\n"); |
|
exit($error->{exit_code}); |
|
} |
|
END_ERROR |
|
} |
|
} |
|
|
|
sub generate_warning_functions { |
|
my ($warnings) = @_; |
|
foreach my $warning (@$warnings) { |
|
push @warning_definitions, <<"END_WARNING"; |
|
void $warning->{func_name}() { |
|
fprintf(stderr, "\\e[1;33mWarning:\\e[0m $warning->{message}\\n"); |
|
} |
|
END_WARNING |
|
} |
|
} |
|
|
|
generate_declarations(\@error_decls); |
|
generate_declarations(\@warning_decls); |
|
|
|
generate_error_functions(\@error_decls); |
|
generate_warning_functions(\@warning_decls); |
|
|
|
print $output_fh "\n", join("\n\n", @declarations), "\n\n"; |
|
print $output_fh "\n", join("", @bypasses), "\n\n"; |
|
print $output_fh "\n", join("\n\n", @error_definitions), "\n\n"; |
|
print $output_fh "\n", join("\n\n", @warning_definitions), "\n\n"; |
|
|
|
# Close files if not STDIN or STDOUT |
|
close($input_fh) if defined $opts{i}; |
|
close($output_fh) if defined $opts{o}; |