You are here

function _coder_read_and_parse_file in Coder 5.2

Same name and namespace in other branches
  1. 5 coder.module \_coder_read_and_parse_file()
  2. 6.2 coder.module \_coder_read_and_parse_file()
  3. 6 coder.module \_coder_read_and_parse_file()

Parse and read a file into a format easy to validate.

Parameters

$coder_args: Coder arguments array variable to add file lines of code (with trailing newlines. The following array indices are added: '#all_lines', '#php_lines', '#allphp_lines', '#html_lines', '#quote_lines', '#doublequote_lines', '#comment_lines'. Their names should be self explanatory.

Return value

Integer 1 if success.

1 call to _coder_read_and_parse_file()
do_coder_reviews in ./coder.module
Perform batch coder reviews for multiple files.

File

./coder.module, line 864
Developer Module that assists with code review and version upgrade that supports a plug-in extensible hook system so contributed modules can define additional review standards.

Code

function _coder_read_and_parse_file(&$coder_args) {

  // Get the path to the module file.
  if ($filepath = realpath($coder_args['#filename'])) {

    // Read the file.
    $content = file_get_contents($filepath) . "\n";
    $content_length = drupal_strlen($content);
    $in_comment = 0;
    $beginning_of_line = 0;
    $in_php = 0;
    $in_allphp = 0;
    $in_quote_html = 0;
    $in_backslash = 0;
    $in_quote = 0;
    $in_heredoc = 0;
    $in_heredoc_html = '';
    $heredoc = '';
    $all_lines = array();
    $php_lines = array();
    $allphp_lines = array();
    $html_lines = array();
    $quote_lines = array();
    $doublequote_lines = array();
    $comment_lines = array();
    $this_all_lines = '';
    $this_php_lines = '';
    $this_allphp_lines = '';
    $this_html_lines = '';
    $this_quote_lines = '';
    $this_doublequote_lines = '';
    $this_comment_lines = '';

    // Parse the file:
    // - Strip comments,
    // - Strip quote content,
    // - Strip stuff not in php,
    // - Break into lines.
    $lineno = 0;
    for ($pos = 0; $pos < $content_length; $pos++) {

      // Get the current character.
      $char = $content[$pos];
      if ($char == "\n") {
        if ($in_comment && $in_comment == '/') {

          // End C++ style comments on newline.
          $in_comment = 0;
        }

        // Assume that html inside quotes doesn't span newlines.
        $in_quote_html = 0;

        // Remove blank lines now, so we avoid processing them over-and-over.
        if ($this_all_lines != '') {
          if (trim($this_all_lines, "\r\n") != '') {
            $all_lines[$lineno] = $this_all_lines;
          }
          if (trim($this_php_lines, "\r\n") != '') {
            $php_lines[$lineno] = $this_php_lines;
          }
          if (trim($this_allphp_lines, "\r\n") != '') {
            $allphp_lines[$lineno] = $this_allphp_lines;
          }
          if (trim($this_html_lines, "\r\n") != '') {
            $html_lines[$lineno] = $this_html_lines;
          }
          if (trim($this_quote_lines, "\r\n") != '') {
            $quote_lines[$lineno] = $this_quote_lines;
          }
          if (trim($this_doublequote_lines, "\r\n") != '') {
            $doublequote_lines[$lineno] = $this_doublequote_lines;
          }
          if (trim($this_comment_lines, "\r\n") != '') {
            $comment_lines[$lineno] = $this_comment_lines;
          }
        }

        // Save this line and start a new line.
        $lineno++;
        $this_all_lines = '';
        $this_php_lines = '';
        $this_allphp_lines = '';
        $this_html_lines = '';
        $this_quote_lines = '';
        $this_doublequote_lines = '';
        $this_comment_lines = '';
        $beginning_of_line = 1;
        continue;
      }
      if ($this_all_lines != '') {
        $beginning_of_line = 0;
      }
      $this_all_lines .= $char;
      if ($in_php || $in_allphp) {

        // When in a quoted string, look for the trailing quote
        // strip characters in the string, replacing with '' or "".
        if ($in_quote) {
          if ($in_backslash) {
            $in_backslash = 0;
          }
          elseif ($char == '\\') {
            $in_backslash = 1;
          }
          elseif ($char == $in_quote && !$in_backslash) {
            $in_quote = 0;
          }
          elseif ($char == '<') {
            $in_quote_html = '>';
          }
          if ($in_quote) {
            $this_quote_lines .= $char;
            if ($in_quote == '"') {
              $this_doublequote_lines .= $char;
            }
            if ($in_quote_html) {
              $this_html_lines .= $char;
            }
          }
          if ($char == $in_quote_html) {
            $in_quote_html = 0;
          }
          $this_allphp_lines .= $char;
          unset($char);

          // NOTE: Trailing char output with starting one.
        }
        elseif ($in_heredoc) {
          if ($beginning_of_line && $char == $in_heredoc[0] && substr($content, $pos, $in_heredoc_length) == $in_heredoc) {
            $this_all_lines .= substr($content, $pos + 1, $in_heredoc_length - 1);
            $in_heredoc = 0;
            $pos += $in_heredoc_length;
          }
          elseif ($char == '<') {
            $in_heredoc_html = '>';
          }
          if ($in_heredoc && $in_heredoc_html) {
            $this_html_lines .= $char;
          }
          if ($in_heredoc_html && $char == $in_heredoc_html) {
            $in_heredoc_html = '';
          }
          unset($char);
        }
        elseif ($char == '?' && $content[$pos + 1] == '>') {
          unset($char);
          $in_php = 0;
          $in_allphp = 0;
          $this_all_lines .= '>';
          $pos++;
        }
        elseif ($in_comment) {
          $this_comment_lines .= $char;
          if ($in_comment == '*' && $char == '*' && $content[$pos + 1] == '/') {
            $in_comment = 0;
            $this_all_lines .= '/';
            $this_comment_lines .= '/';
            $pos++;
          }
          unset($char);

          // Don't add comments to php output.
        }
        else {
          switch ($char) {
            case '\'':
            case '"':
              if ($content[$pos - 1] != '\\') {
                $this_php_lines .= $char;
                $in_quote = $char;
              }
              break;
            case '/':
              $next_char = $content[$pos + 1];
              if ($next_char == '/' || $next_char == '*') {
                unset($char);
                $in_comment = $next_char;
                $this_all_lines .= $next_char;
                $this_comment_lines .= '/' . $next_char;
                $pos++;
              }
              break;
            case '<':
              if ($content[$pos + 1] == '<' && $content[$pos + 2] == '<') {
                unset($char);
                $this_all_lines .= '<<';

                // Get the heredoc word.
                // Read until the end-of-line.
                for ($pos += 3; $pos < $content_length; $pos++) {
                  $char = $content[$pos];
                  if ($char == "\n") {
                    $pos--;
                    if (preg_match('/^\\s*(\\w+)/', $heredoc, $match)) {
                      $in_heredoc = $match[1];
                      $in_heredoc_length = drupal_strlen($in_heredoc);
                    }
                    break;
                  }
                  $this_all_lines .= $char;
                  $heredoc .= $char;
                }
                $heredoc = '';

                // Replace heredoc's with an empty string.
                $this_php_lines .= '\'\'';
                $this_allphp_lines .= '\'\'';
                unset($char);
              }
              break;
          }
        }
        if (isset($char)) {
          $this_php_lines .= $char;
          $this_allphp_lines .= $char;
        }
      }
      else {
        switch ($char) {
          case '<':
            if ($content[$pos + 1] == '?') {
              if ($content[$pos + 2] == ' ') {
                $in_php = 1;
                $in_allphp = 1;
                $this_all_lines .= '? ';
                $pos += 2;
              }
              elseif (substr($content, $pos + 2, 3) == 'php') {
                $in_php = 1;
                $in_allphp = 1;
                $this_all_lines .= '?php';
                $pos += 4;
              }
              break;
            }

          // FALTHROUGH
          default:
            $this_html_lines .= $char;
            break;
        }
      }
    }

    // Add the files lines to the arguments.
    $coder_args['#all_lines'] = $all_lines;
    $coder_args['#php_lines'] = $php_lines;
    $coder_args['#allphp_lines'] = $allphp_lines;
    $coder_args['#html_lines'] = $html_lines;
    $coder_args['#quote_lines'] = $quote_lines;
    $coder_args['#doublequote_lines'] = $doublequote_lines;
    $coder_args['#comment_lines'] = $comment_lines;
    return 1;
  }
}