⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 templateparser.pm

📁 ACE源码
💻 PM
📖 第 1 页 / 共 2 页
字号:
    my($ret) = 1;
    foreach my $v (split(/\s*\&\&\s*/, $str)) {
      $ret &&= $self->process_compound_if($v);
      if ($ret == 0) {
        return 0;
      }
    }
    $status = 1;
  }
  else {
    ## See if we need to reverse the return value
    my($not) = 0;
    if ($str =~ /^!(.*)/) {
      $not = 1;
      $str = $1;
    }

    ## Get the value based on the string
    my($val) = ($str =~ /flag_overrides\(([^\)]+),\s*([^\)]+)\)/ ?
                               $self->get_flag_overrides($1, $2) :
                               $self->get_value($str));

    ## See if any portion of the value is defined and not empty
    my($ret) = 0;
    if (defined $val) {
      if (UNIVERSAL::isa($val, 'ARRAY')) {
        foreach my $v (@$val) {
          if ($v ne '') {
            $ret = 1;
            last;
          }
        }
      }
      elsif ($val ne '') {
        $ret = 1;
      }
    }
    return ($not ? !$ret : $ret);
  }

  return $status;
}


sub handle_if {
  my($self)   = shift;
  my($val)    = shift;
  my($name)   = 'endif';

  push(@{$self->{'lstack'}}, $self->get_line_number() . " $val");
  if ($self->{'if_skip'}) {
    push(@{$self->{'sstack'}}, "*$name");
  }
  else {
    ## Determine if we are skipping the portion of this if statement
    ## $val will always be defined since we won't get into this method
    ## without properly parsing the if statement.
    $self->{'if_skip'} = !$self->process_compound_if($val);
    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';
  my($status)      = 1;
  my($errorString) = undef;

  push(@{$self->{'lstack'}}, $self->get_line_number());
  if (!$self->{'if_skip'}) {
    my($vname) = undef;
    if ($val =~ /([^,]+),(.*)/) {
      $vname = $1;
      $val   = $2;
      $vname =~ s/^\s+//;
      $vname =~ s/\s+$//;
      $val   =~ s/^\s+//;
      $val   =~ s/\s+$//;

      ## Due to the way flag_overrides works, we can't allow
      ## the user to name the foreach variable when dealing
      ## with custom types.
      if ($val =~ /^custom_type\->/ || $val eq 'custom_types') {
        $status = 0;
        $errorString = 'The foreach variable can not be ' .
                       'named when dealing with custom types';
      }
      elsif ($val =~ /^grouped_.*_file\->/ || $val =~ /^grouped_.*files$/) {
        $status = 0;
        $errorString = 'The foreach variable can not be ' .
                       'named when dealing with grouped files';
      }
    }

    push(@{$self->{'sstack'}}, $name);
    ++$self->{'foreach'}->{'count'};

    my($index) = $self->{'foreach'}->{'count'};
    $self->{'foreach'}->{'name'}->[$index]  = $vname;
    $self->{'foreach'}->{'names'}->[$index] = $val;
    $self->{'foreach'}->{'text'}->[$index]  = '';
    $self->{'foreach'}->{'scope'}->[$index] = {};
  }
  else {
    push(@{$self->{'sstack'}}, "*$name");
  }

  return $status, $errorString;
}


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->{'if_skip'}) {
    if ($self->get_value($name)) {
      $self->append_current($val);
    }
  }
}


sub handle_uc {
  my($self) = shift;
  my($name) = shift;

  if (!$self->{'if_skip'}) {
    $self->append_current(uc($self->get_value_with_default($name)));
  }
}


sub handle_lc {
  my($self) = shift;
  my($name) = shift;

  if (!$self->{'if_skip'}) {
    $self->append_current(lc($self->get_value_with_default($name)));
  }
}


sub handle_ucw {
  my($self) = shift;
  my($name) = shift;

  if (!$self->{'if_skip'}) {
    my($val) = $self->get_value_with_default($name);
    substr($val, 0, 1) = uc(substr($val, 0, 1));
    while($val =~ /[_\s]([a-z])/) {
      my($uc) = uc($1);
      $val =~ s/(_|\s)([a-z])/$1$uc/;
    }
    $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'}) {
    $self->append_current(
              $self->dirname($self->get_value_with_default($name)));
  }
}


sub handle_basename {
  my($self) = shift;
  my($name) = shift;

  if (!$self->{'if_skip'}) {
    $self->append_current(
              $self->basename($self->get_value_with_default($name)));
  }
}


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);
    }
  }
}


sub process_name {
  my($self)        = shift;
  my($line)        = shift;
  my($length)      = 0;
  my($status)      = 1;
  my($errorString) = undef;

  if ($line eq '') {
  }
  elsif ($line =~ /^(\w+)(\(([^\)]+|\".*\"|flag_overrides\([^\)]+,\s*[^\)]+\))\)|\->\w+([\w\-\>]+)?)?%>/) {
    ## Split the line into a name and value
    my($name, $val) = ();
    if ($line =~ /([^%\(]+)(\(([^%]+)\))?%>/) {
      $name = lc($1);
      $val  = $3;
    }

    $length += length($name);
    if (defined $val) {
      ## Add the length of the value plus 2 for the surrounding ()
      $length += length($val) + 2;
    }

    if (defined $keywords{$name}) {
      if ($name eq 'endif') {
        ($status, $errorString) = $self->handle_endif($name);
      }
      elsif ($name eq 'if') {
        $self->handle_if($val);
      }
      elsif ($name eq 'endfor') {
        ($status, $errorString) = $self->handle_endfor($name);
      }
      elsif ($name eq 'foreach') {
        ($status, $errorString) = $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 'else') {
        $self->handle_else();
      }
      elsif ($name eq 'flag_overrides') {
        $self->handle_flag_overrides($val);
      }
      elsif ($name eq 'noextension') {
        $self->handle_noextension($val);
      }
      elsif ($name eq 'basenoextension') {
        $self->handle_basenoextension($val);
      }
      elsif ($name eq 'basename') {
        $self->handle_basename($val);
      }
      elsif ($name eq 'marker') {
        $self->handle_marker($val);
      }
      elsif ($name eq 'dirname') {
        $self->handle_dirname($val);
      }
      elsif ($name eq 'comment') {
        ## Ignore the contents of the comment
      }
      elsif ($name eq 'uc') {
        $self->handle_uc($val);
      }
      elsif ($name eq 'ucw') {
        $self->handle_ucw($val);
      }
      elsif ($name eq 'lc') {
        $self->handle_lc($val);
      }
    }
    else {
      if (!$self->{'if_skip'}) {
        if (defined $val && !defined $self->{'defaults'}->{$name}) {
          $self->{'defaults'}->{$name} = $self->process_special($val);
        }
        $self->append_current($self->get_value_with_default($name));
      }
    }
  }
  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 = "Unable to parse line starting at $error";
  }

  return $status, $errorString, $length;
}


sub collect_data {
  my($self)  = shift;
  my($prjc)  = $self->{'prjc'};
  my($cwd)   = $self->getcwd();
  my($relwd) = $prjc->reverse_relative($cwd);

  ## Set the current working directory
  if ($self->{'cslashes'}) {
    $cwd = $prjc->slash_to_backslash($cwd);
  }
  $self->{'values'}->{'cwd'} = $cwd;

  ## Set the relative working directory
  $relwd =~ s/\$\([^\)]+\)[\/\\]//;
  if ($self->{'cslashes'}) {
    $relwd = $prjc->slash_to_backslash($relwd);
  }
  $self->{'values'}->{'relwd'} = $relwd;

  ## 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 creator.  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, ['after']);

  ## 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 parse_line {
  my($self)        = shift;
  my($ih)          = shift;
  my($line)        = shift;
  my($status)      = 1;
  my($errorString) = undef;
  my($length)      = length($line);
  my($name)        = 0;
  my($startempty)  = ($length == 0 ? 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) {
    my($is_only_keyword) = undef;
    if ($line =~ /^\s*<%(\w+)(\([^\)]+\))?%>$/) {
      $is_only_keyword = defined $keywords{$1};
    }

    if (!$is_only_keyword) {
      $line   .= $self->{'crlf'};
      $length += $self->{'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) = ($efcheck ? 0 : ($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 = "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 $self->{'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 = "Missing an $$sstack[0] starting at $$lstack[0]";
    }
  }

  if (!$status) {
    my($linenumber) = $self->get_line_number();
    $errorString = "$input: line $linenumber:\n$errorString";
  }

  return $status, $errorString;
}


sub get_lines {
  my($self) = shift;
  return $self->{'lines'};
}


1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -