?? templateparser.pm
字號:
foreach my $ma (keys %{$prjc->{'matching_assignments'}}) {
if ($ma eq $key) {
foreach my $aname (@{$prjc->{'matching_assignments'}->{$ma}}) {
if ($aname eq $type &&
defined $$fo{$key}->{$of}->{$aname}) {
$value = $$fo{$key}->{$of}->{$aname};
last;
}
}
last;
}
}
last;
}
}
last;
}
}
return $value;
}
sub handle_if {
my($self) = shift;
my($val) = shift;
my($name) = 'endif';
push(@{$self->{'lstack'}}, $self->line_number() . " $val");
if (!$self->{'if_skip'}) {
my($true) = 1;
push(@{$self->{'sstack'}}, $name);
if ($val =~ /^!(.*)/) {
$val = $1;
$val =~ s/^\s+//;
$true = 0;
}
if ($val =~ /flag_overrides\(([^\)]+),\s*([^\)]+)\)/) {
$val = $self->get_flag_overrides($1, $2);
}
else {
$val = $self->get_value($val)
}
if (!defined $val) {
$self->{'if_skip'} = $true;
}
else {
$self->{'if_skip'} = !$true;
}
}
else {
push(@{$self->{'sstack'}}, "*$name");
}
}
sub handle_else {
my($self) = shift;
my(@scopy) = @{$self->{'sstack'}};
## This method does not take into account that
## multiple else clauses could be supplied to a single if.
## Someday, this may be fixed.
if (defined $scopy[$#scopy] && $scopy[$#scopy] eq 'endif') {
$self->{'if_skip'} ^= 1;
}
}
sub handle_foreach {
my($self) = shift;
my($val) = shift;
my($name) = 'endfor';
push(@{$self->{'lstack'}}, $self->line_number());
if (!$self->{'if_skip'}) {
push(@{$self->{'sstack'}}, $name);
++$self->{'foreach'}->{'count'};
my($index) = $self->{'foreach'}->{'count'};
$self->{'foreach'}->{'names'}->[$index] = $val;
$self->{'foreach'}->{'text'}->[$index] = '';
$self->{'foreach'}->{'scope'}->[$index] = {};
}
else {
push(@{$self->{'sstack'}}, "*$name");
}
}
sub handle_special {
my($self) = shift;
my($name) = shift;
my($val) = shift;
## If $name (fornotlast, forfirst, etc.) is set to 1
## Then we append the $val onto the current string that's
## being built.
if ($self->get_value($name)) {
$self->append_current($val);
}
}
sub handle_noextension {
my($self) = shift;
my($name) = shift;
if (!$self->{'if_skip'}) {
my($val) = $self->get_value_with_default($name);
$val =~ s/\.[^\.]+$//;
$self->append_current($val);
}
}
sub handle_dirname {
my($self) = shift;
my($name) = shift;
if (!$self->{'if_skip'}) {
my($val) = $self->dirname($self->get_value_with_default($name));
$self->append_current($val);
}
}
sub handle_basename {
my($self) = shift;
my($name) = shift;
if (!$self->{'if_skip'}) {
my($val) = $self->basename($self->get_value_with_default($name));
$self->append_current($val);
}
}
sub handle_basenoextension {
my($self) = shift;
my($name) = shift;
if (!$self->{'if_skip'}) {
my($val) = $self->basename($self->get_value_with_default($name));
$val =~ s/\.[^\.]+$//;
$self->append_current($val);
}
}
sub handle_flag_overrides {
my($self) = shift;
my($name) = shift;
my($type) = '';
($name, $type) = split(/,\s*/, $name);
if (!$self->{'if_skip'}) {
my($value) = $self->get_flag_overrides($name, $type);
if (defined $value) {
$self->append_current($value);
}
}
}
sub handle_marker {
my($self) = shift;
my($name) = shift;
if (!$self->{'if_skip'}) {
my($value) = $self->{'prjc'}->get_verbatim($name);
if (defined $value) {
$self->append_current($value);
}
}
}
## Given a line that starts with an identifier, we split
## then name from the possible value stored inside ()'s and
## we stop looking at the line when we find the %> ending
sub split_name_value {
my($self) = shift;
my($line) = shift;
my($length) = length($line);
my($name) = undef;
my($val) = undef;
for(my $i = 0; $i < $length; ++$i) {
my($ch) = substr($line, $i, 1);
if (!defined $name && $ch eq '(') {
$name = substr($line, 0, $i);
$val = '';
}
elsif (!defined $name && $ch eq '%') {
if (substr($line, $i + 1, 1) eq '>') {
$name = substr($line, 0, $i);
last;
}
}
elsif (defined $val && $ch ne ')') {
$val .= $ch;
}
elsif (defined $val && $ch eq ')') {
if (substr($line, $i + 1, 2) eq '%>') {
last;
}
else {
$val .= $ch;
}
}
}
return $name, $val;
}
sub process_name {
my($self) = shift;
my($line) = shift;
my($length) = 0;
my($status) = 1;
my($errorString) = '';
if ($line eq '') {
}
elsif ($line =~ /^(\w+)(\(([^\)]+|\".*\"|flag_overrides\([^\)]+,\s*[^\)]+\))\))?%>/) {
my($name, $val) = $self->split_name_value($line);
$length += length($name);
if (defined $val) {
$length += length($val) + 2;
}
if (defined $keywords{$name}) {
if ($name eq 'endif' || $name eq 'endfor') {
($status, $errorString) = $self->handle_end($name);
}
elsif ($name eq 'if') {
$self->handle_if($val);
}
elsif ($name eq 'else') {
$self->handle_else();
}
elsif ($name eq 'foreach') {
$self->handle_foreach($val);
}
elsif ($name eq 'fornotlast' || $name eq 'forlast' ||
$name eq 'fornotfirst' || $name eq 'forfirst') {
$self->handle_special($name, $self->process_special($val));
}
elsif ($name eq 'comment') {
## Ignore the contents of the comment
}
elsif ($name eq 'flag_overrides') {
$self->handle_flag_overrides($val);
}
elsif ($name eq 'marker') {
$self->handle_marker($val);
}
elsif ($name eq 'noextension') {
$self->handle_noextension($val);
}
elsif ($name eq 'dirname') {
$self->handle_dirname($val);
}
elsif ($name eq 'basename') {
$self->handle_basename($val);
}
elsif ($name eq 'basenoextension') {
$self->handle_basenoextension($val);
}
}
else {
if (!$self->{'if_skip'}) {
if (defined $val && !defined $self->{'defaults'}->{$name}) {
$self->{'defaults'}->{$name} = $self->process_special($val);
}
$val = $self->get_value_with_default($name);
$self->append_current($val);
}
}
}
else {
my($error) = $line;
my($length) = length($line);
for(my $i = 0; $i < $length; ++$i) {
my($part) = substr($line, $i, 2);
if ($part eq '%>') {
$error = substr($line, 0, $i + 2);
last;
}
}
$status = 0;
$errorString = "ERROR: Unable to parse line starting at $error";
}
return $status, $errorString, $length;
}
sub collect_data {
my($self) = shift;
my($prjc) = $self->{'prjc'};
## Save crlf so we don't have to keep going back to the prjc
$self->{'crlf'} = $prjc->crlf();
## Collect the components into {'values'} somehow
foreach my $key (keys %{$prjc->{'valid_components'}}) {
my(@list) = $prjc->get_component_list($key);
if (defined $list[0]) {
$self->{'values'}->{$key} = "@list";
}
}
## A tiny hack (mainly for VC6 projects)
## for the workspace generator. It needs to know the
## target names to match up with the project name.
$prjc->update_project_info($self, 0, ['project_name']);
## This is for all projects
$prjc->update_project_info($self, 1, ['depends']);
## VC7 Projects need to know the GUID.
## We need to save this value in our known values
## since each guid generated will be different. We need
## this to correspond to the same guid used in the workspace.
my($guid) = $prjc->update_project_info($self, 1, ['guid']);
$self->{'values'}->{'guid'} = $guid;
}
sub is_only_keyword {
my($self) = shift;
my($line) = shift;
## Does the line contain only a keyword?
if ($line =~ /^<%(.*)%>$/) {
my($part) = $1;
if ($part !~ /%>/) {
$part =~ s/\(.*//;
return (defined $keywords{$part} ? 1 : 0);
}
}
return 0;
}
sub parse_line {
my($self) = shift;
my($ih) = shift;
my($line) = shift;
my($status) = 1;
my($errorString) = '';
my($length) = length($line);
my($name) = 0;
my($crlf) = $self->{'crlf'};
my($clen) = length($crlf);
my($startempty) = ($line eq '' ? 1 : 0);
my($append_name) = 0;
## If processing a foreach or the line only
## contains a keyword, then we do
## not need to add a newline to the end.
if ($self->{'foreach'}->{'processing'} == 0 &&
!$self->is_only_keyword($line)) {
$line .= $crlf;
$length += $clen;
}
if ($self->{'foreach'}->{'count'} < 0) {
$self->{'built'} = '';
}
for(my $i = 0; $i < $length; ++$i) {
my($part) = substr($line, $i, 2);
if ($part eq '<%') {
++$i;
$name = 1;
}
elsif ($part eq '%>') {
++$i;
$name = 0;
if ($append_name) {
$append_name = 0;
if (!$self->{'if_skip'}) {
$self->append_current($part);
}
}
}
elsif ($name) {
my($substr) = substr($line, $i);
my($efcheck) = ($substr =~ /^endfor\%\>/);
my($focheck) = ($substr =~ /^foreach\(/);
if ($focheck && $self->{'foreach'}->{'count'} >= 0) {
++$self->{'foreach'}->{'nested'};
}
if ($self->{'foreach'}->{'count'} < 0 ||
$self->{'foreach'}->{'processing'} > $self->{'foreach'}->{'nested'} ||
(($efcheck || $focheck) &&
$self->{'foreach'}->{'nested'} == $self->{'foreach'}->{'processing'})) {
my($nlen) = 0;
($status,
$errorString,
$nlen) = $self->process_name($substr);
if ($status && $nlen == 0) {
$errorString = "ERROR: Could not parse this line at column $i";
$status = 0;
}
if (!$status) {
last;
}
$i += ($nlen - 1);
}
else {
$name = 0;
if (!$self->{'if_skip'}) {
$self->append_current('<%' . substr($line, $i, 1));
$append_name = 1;
}
}
if ($efcheck && $self->{'foreach'}->{'nested'} > 0) {
--$self->{'foreach'}->{'nested'};
}
}
else {
if (!$self->{'if_skip'}) {
$self->append_current(substr($line, $i, 1));
}
}
}
if ($self->{'foreach'}->{'count'} < 0) {
## If the line started out empty and we're not
## skipping from the start or the built up line is not empty
if ($startempty ||
($self->{'built'} ne $crlf && $self->{'built'} ne '')) {
push(@{$self->{'lines'}}, $self->{'built'});
}
}
return $status, $errorString;
}
sub parse_file {
my($self) = shift;
my($input) = shift;
$self->collect_data();
my($status, $errorString) = $self->read_file($input);
if ($status) {
my($sstack) = $self->{'sstack'};
if (defined $$sstack[0]) {
my($lstack) = $self->{'lstack'};
$status = 0;
$errorString = "ERROR: missing an $$sstack[0] starting at $$lstack[0]";
}
}
if (!$status) {
my($linenumber) = $self->line_number();
$errorString = "$input: line $linenumber: $errorString\n";
}
return $status, $errorString;
}
sub get_lines {
my($self) = shift;
return $self->{'lines'};
}
1;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -