Merge pull request #178 from DOCGroup/elliottc/more_databases
[MPC.git] / modules / Parser.pm
blobeeb06d6e3ec953dd78ba7748e835f84482e1182a
1 package Parser;
3 # ************************************************************
4 # Description : A basic parser that requires a parse_line override
5 # Author : Chad Elliott
6 # Create Date : 5/16/2002
7 # ************************************************************
9 # ************************************************************
10 # Pragmas
11 # ************************************************************
13 use strict;
14 use FileHandle;
16 use mpc_debug;
17 use OutputMessage;
18 use StringProcessor;
19 use DirectoryManager;
21 use vars qw(@ISA);
22 @ISA = qw(OutputMessage StringProcessor DirectoryManager);
24 # ************************************************************
25 # Data Section
26 # ************************************************************
28 my %filecache;
30 # ************************************************************
31 # Subroutine Section
32 # ************************************************************
34 sub new {
35 my($class, $inc) = @_;
36 my $self = $class->SUPER::new();
38 ## Set up the internal data members.
39 $self->{'line_number'} = 0;
40 $self->{'include'} = $inc;
42 return $self;
46 sub strip_comments {
47 my($self, $line) = @_;
49 $line =~ s/\/\/.*//;
50 return $line;
54 sub strip_lt_whitespace {
55 my($self, $line, $keep_leading_whitespace) = @_;
57 $line =~ s/^\s+// if !$keep_leading_whitespace;
58 $line =~ s/\s+$//;
59 return $line;
63 sub is_blank_line {
64 my($self, $line) = @_;
65 return m/^\s+$/;
69 sub strip_line {
70 my($self, $line) = @_;
72 ## Keep track of our line number
73 ++$self->{'line_number'};
75 $line = $self->strip_comments($line);
76 $line = $self->strip_lt_whitespace($line);
78 return $line;
82 sub preprocess_line {
83 #my $self = shift;
84 #my $fh = shift;
85 #my $line = shift;
86 return $_[0]->strip_line($_[2]);
90 sub read_file {
91 my($self, $input, $cache) = @_;
92 my $ih = new FileHandle();
93 my $status = 1;
94 my $errorString;
96 mpc_debug::chkpnt_pre_read_file($input, $cache);
97 $self->{'line_number'} = 0;
98 if (open($ih, $input)) {
99 $self->debug("Open $input");
100 if ($cache) {
101 ## If we don't have an array for this file, then start one
102 $filecache{$input} = [] if (!defined $filecache{$input});
104 while(<$ih>) {
105 ## Preprocess the line
106 my $line = $self->preprocess_line($ih, $_);
108 ## Push the line onto the array for this file
109 push(@{$filecache{$input}}, $line);
111 ## Parse the line
112 ($status, $errorString) = $self->parse_line($ih, $line);
114 ## Stop reading the file if we've encountered an error
115 last if (!$status);
118 else {
119 ## We're not caching, so we just preprocess and parse in one call.
120 while(<$ih>) {
121 ($status, $errorString) = $self->parse_line(
122 $ih, $self->preprocess_line($ih, $_));
124 ## Stop reading the file if we've encountered an error
125 last if (!$status);
128 $self->debug("Close $input");
129 close($ih);
131 else {
132 $errorString = "Unable to open \"$input\" for reading";
133 $status = 0;
135 mpc_debug::chkpnt_post_read_file($input, $cache, $status, $errorString);
137 return $status, $errorString;
141 sub cached_file_read {
142 my($self, $input) = @_;
143 my $lines = $filecache{$input};
145 if (defined $lines) {
146 my $status = 1;
147 my $error;
148 $self->{'line_number'} = 0;
149 foreach my $line (@$lines) {
150 ++$self->{'line_number'};
152 ## Since we're "reading" a cached file, we must pass undef as the
153 ## file handle to parse_line().
154 ($status, $error) = $self->parse_line(undef, $line);
156 ## Stop "reading" the file if we've encountered an error
157 last if (!$status);
159 return $status, $error;
162 ## We haven't cached this file yet, read it and cache it.
163 return $self->read_file($input, 1);
167 sub get_line_number {
168 return $_[0]->{'line_number'};
172 sub set_line_number {
173 my($self, $number) = @_;
174 $self->{'line_number'} = $number;
178 sub slash_to_backslash {
179 ## This method is here solely for convenience. It's used to make the
180 ## calling code look cleaner.
181 my($self, $file) = @_;
182 $file =~ s/\//\\/g;
183 return $file;
187 sub get_include_path {
188 return $_[0]->{'include'};
192 sub search_include_path {
193 my($self, $file) = @_;
195 foreach my $include ('.', @{$self->{'include'}}) {
196 return "$include/$file" if (-r "$include/$file");
199 return undef;
203 sub escape_regex_special {
204 my($self, $name) = @_;
205 $name =~ s/([\+\-\\\$\[\]\(\)\.])/\\$1/g;
206 return $name;
210 # ************************************************************
211 # Virtual Methods To Be Overridden
212 # ************************************************************
214 sub parse_line {
215 #my $self = shift;
216 #my $ih = shift;
217 #my $line = shift;