You are here

function _coder_read_and_parse_file in Coder 5

Same name and namespace in other branches
  1. 5.2 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()
1 call to _coder_read_and_parse_file()
do_coder_reviews in ./coder.module

File

./coder.module, line 700
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_quote_html = 0;
    $in_backslash = 0;
    $in_quote = 0;
    $in_heredoc = 0;
    $in_heredoc_html = '';
    $heredoc = '';
    $all_lines = array();
    $php_lines = array();
    $html_lines = array();
    $quote_lines = array();
    $doublequote_lines = array();
    $comment_lines = array();
    $this_all_lines = '';
    $this_php_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) != '') {
            $all_lines[$lineno] = $this_all_lines;
          }
          if (trim($this_php_lines) != '') {
            $php_lines[$lineno] = $this_php_lines;
          }
          if (trim($this_html_lines) != '') {
            $html_lines[$lineno] = $this_html_lines;
          }
          if (trim($this_quote_lines) != '') {
            $quote_lines[$lineno] = $this_quote_lines;
          }
          if (trim($this_doublequote_lines) != '') {
            $doublequote_lines[$lineno] = $this_doublequote_lines;
          }
          if (trim($this_comment_lines) != '') {
            $comment_lines[$lineno] = $this_comment_lines;
          }
        }

        // save this line and start a new line
        $lineno++;
        $this_all_lines = '';
        $this_php_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) {

        // 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;
          }
          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;
          $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 .= '\'\'';
                unset($char);
              }
              break;
          }
        }
        if (isset($char)) {
          $this_php_lines .= $char;
        }
      }
      else {
        switch ($char) {
          case '<':
            if ($content[$pos + 1] == '?') {
              if ($content[$pos + 2] == ' ') {
                $in_php = 1;
                $this_all_lines .= '? ';
                $pos += 2;
              }
              elseif (substr($content, $pos + 2, 3) == 'php') {
                $in_php = 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['#html_lines'] = $html_lines;
    $coder_args['#quote_lines'] = $quote_lines;
    $coder_args['#doublequote_lines'] = $doublequote_lines;
    $coder_args['#comment_lines'] = $comment_lines;
    return 1;
  }
}