coder_format.inc in Coder 5
File
scripts/coder_format/coder_format.incView source
<?php
/**
* Recursively process .module and .inc files in directory.
*
* @param bool undo Whether to undo batch replacements.
*/
function coder_format_recursive($root, $undo = false, $file_inc = null) {
// Convert Windows paths
$root = str_replace("\\", '/', $root);
// Check if directory exists
if (!file_exists($root)) {
echo 'ERROR: ' . $root . ' does not exist!';
return;
}
// Trim root directory
if (substr($root, -1) == '/') {
$root = substr($root, 0, -1);
}
// Include Drupal's file.inc
if (!isset($file_inc)) {
if (!file_exists($root . '/includes/file.inc')) {
echo 'ERROR: ' . $root . '/includes/file.inc not found!';
return;
}
}
else {
if (!file_exists($file_inc)) {
echo 'ERROR: ' . $file_inc . ' not found!';
return;
}
}
require_once !isset($file_inc) ? $root . '/includes/file.inc' : $file_inc;
if (!$undo) {
// Fetch files to process
$mask = '.module$|.inc$|.install|.profile$';
$nomask = array(
'.',
'..',
'CVS',
'.svn',
);
$files = file_scan_directory($root, $mask, $nomask, 0, true);
foreach ($files as $file) {
// file_copy() assigns $file->filename by reference
$sourcefile = $file->filename;
echo $file->filename . "\n";
file_copy($file->filename, $file->filename . '.coder.orig');
coder_format_file($sourcefile, $sourcefile);
}
}
else {
// Fetch files to process
$mask = '.coder.orig$';
$nomask = array(
'.',
'..',
'CVS',
'.svn',
);
$files = file_scan_directory($root, $mask, $nomask, 0, true);
foreach ($files as $file) {
$file->origname = str_replace('.coder.orig', '', $file->filename);
echo $file->origname . "\n";
file_move($file->filename, $file->origname, FILE_EXISTS_REPLACE);
}
}
}
/**
* Reads, processes and writes the source code from and to a file.
*/
function coder_format_file($sourcefile = null, $targetfile = null) {
if (!isset($sourcefile) || !isset($targetfile)) {
return;
}
// Read source code from source file
$fd = fopen($sourcefile, 'r');
$code = fread($fd, filesize($sourcefile));
fclose($fd);
if ($code !== false) {
// Preprocess source code
$code = coder_exec_processors($code, 'coder_preprocessor');
// Process source code
$code = coder_format_string($code);
// Postprocess source code
$code = coder_exec_processors($code, 'coder_postprocessor');
// Fix beginning and end of code
$code = coder_trim_php($code);
if ($code !== false) {
// Write formatted source code to target file
$fd = fopen($targetfile, 'w');
$status = fwrite($fd, $code);
fclose($fd);
return $status;
}
}
return false;
}
/**
* Format the source code according to Drupal coding style guidelines.
*
* This function uses PHP's tokenizer functions.
* @see <http://www.php.net/manual/en/ref.tokenizer.php>
*
* To achieve the desired coding style, we have to take some special cases
* into account. These are:
*
* Indent-related:
* $_coder_indent int Indent level
* The number of indents for the next line. This is
* - increased after {, : (after case and default).
* - decreased after }, break, case and default (after a previous case).
* $in_case bool
* Is true after case and default. Is false after break and return, if
* $braces_in_case is not greater than 0.
* $braces_in_case int Count of braces
* The number of currently opened curly braces in a case. This is needed
* to support arbitrary function exits inside of a switch control strucure.
* $parenthesis int Parenthesis level
* The number of currently opened parenthesis. This
* - prevents line feeds in brackets (f.e. in arguments of for()).
* - is the base for formatting of multiline arrays. Note: If the last
* ');' is not formatted to the correct indent level then there is no
* ',' (comma) behind the last array value.
* $in_brace bool
* Is true after left curly braces if they are in quotes, an object or
* after a dollar sign. Prevents line breaks around such variable
* statements.
* $in_heredoc bool
* Is true after heredoc output method and false after heredoc delimiter.
* Prevents line breaks in heredocs.
* $first_php_tag bool
* Is false after the first PHP tag. Allows inserting a line break after
* the first one.
* $in_do_while bool
* Is true after a do {} statement and set to false in the next while
* statement. Prevents a line break in the do {...} while() construct.
*
* Whitespace-related:
* $in_object bool
* Prevents whitespace after ->.
* Is true after ->. Is reset to false after the next string or variable.
* $in_at bool
* Prevents whitespace after @.
* Is true after @. Is reset to false after the next string or variable.
* $in_quote bool
* Prevents
* - removal of whitespace in double quotes.
* - injection of new line feeds after brackets in double quotes.
* $inline_if bool
* Controls formatting of ? and : for inline ifs until a ; (semicolon) is
* processed.
*
* @param string $code
* The source code to format.
*
* @return mixed $result
* Returns the formatted code or false if it fails.
*/
function coder_format_string($code = '') {
global $_coder_indent;
// indent controls
$_coder_indent = 0;
$in_case = false;
$parenthesis = 0;
$braces_in_case = 0;
$in_brace = false;
$in_heredoc = false;
$first_php_tag = true;
$in_do_while = false;
// whitespace controls
$in_object = false;
$in_at = false;
$in_php = false;
$in_quote = false;
$inline_if = false;
$result = '';
$lasttoken = array(
0,
);
$tokens = token_get_all($code);
// Mask T_ML_COMMENT (PHP4) as T_COMMENT (PHP5).
// Mask T_DOC_COMMENT (PHP5) as T_ML_COMMENT (PHP4).
if (!defined('T_ML_COMMENT')) {
define('T_ML_COMMENT', T_COMMENT);
}
else {
if (!defined('T_DOC_COMMENT')) {
define('T_DOC_COMMENT', T_ML_COMMENT);
}
}
foreach ($tokens as $token) {
if (is_string($token)) {
// simple 1-character token
$text = trim($token);
switch ($text) {
case '{':
// Write curly braces at the end of lines followed by a line break if
// not in quotes (""), object ($foo->{$bar}) or in variables (${foo}).
// [T_DOLLAR_OPEN_CURLY_BRACES exists but is never assigned.]
if (!$in_quote && !$in_object && substr(rtrim($result), -1) != '$') {
if ($in_case) {
++$braces_in_case;
}
++$_coder_indent;
$result = rtrim($result) . ' ' . $text . coder_br();
}
else {
$in_brace = true;
$result .= $text;
}
break;
case '}':
if (!$in_quote && !$in_brace && !$in_heredoc) {
if ($in_case) {
--$braces_in_case;
}
--$_coder_indent;
if ($braces_in_case < 0) {
// Decrease indent if last case in a switch is not terminated
--$_coder_indent;
$in_case = false;
$braces_in_case = 0;
}
$result = rtrim($result);
if (substr($result, -1) != '{') {
// Avoid line break in empty curly braces
$result .= coder_br();
}
$result .= $text . coder_br();
}
else {
$in_brace = false;
$result .= $text;
}
break;
case ';':
$result = rtrim($result) . $text;
if (!$parenthesis && !$in_heredoc) {
$result .= coder_br();
}
else {
$result .= ' ';
}
if ($inline_if) {
$inline_if = false;
}
break;
case '?':
$inline_if = true;
$result .= ' ' . $text . ' ';
break;
case ':':
if ($inline_if) {
$result .= ' ' . $text . ' ';
}
else {
if ($in_case) {
++$_coder_indent;
}
$result = rtrim($result) . $text . coder_br();
}
break;
case '(':
$result .= $text;
++$parenthesis;
break;
case ')':
if (!$in_quote && !$in_heredoc && substr(rtrim($result), -1) == ',') {
// Fix indent of right parenthesis in multiline arrays by
// increasing indent for each parenthesis and decreasing one level.
$_coder_indent = $_coder_indent + $parenthesis - 1;
$result = rtrim($result) . coder_br() . $text;
$_coder_indent = $_coder_indent - $parenthesis + 1;
}
else {
$result .= $text;
}
if ($parenthesis) {
--$parenthesis;
}
break;
case '@':
$in_at = true;
$result .= $text;
break;
case ',':
$result .= $text . ' ';
break;
case '.':
if (substr(rtrim($result), -1) == "'" || substr(rtrim($result), -1) == '"') {
// Write string concatenation character directly after strings
$result = rtrim($result) . $text . ' ';
}
else {
$result = rtrim($result) . ' ' . $text . ' ';
}
break;
case '=':
case '<':
case '>':
case '+':
case '*':
case '/':
case '|':
case '^':
case '%':
$result = rtrim($result) . ' ' . $text . ' ';
break;
case '&':
if (substr(rtrim($result), -1) == '=' || substr(rtrim($result), -1) == '(' || substr(rtrim($result), -1) == ',') {
$result .= $text;
}
else {
$result = rtrim($result) . ' ' . $text . ' ';
}
break;
case '-':
$result = rtrim($result);
// Do not add a space before negative numbers or variables
if (substr($result, -1) == '>' || substr($result, -1) == '=' || substr($result, -1) == ',' || substr($result, -1) == ':') {
$result .= ' ' . $text;
}
else {
$result .= ' ' . $text . ' ';
}
break;
case '"':
// toggle quote if the char is not escaped
if (rtrim($result) != "\\") {
$in_quote = $in_quote ? false : true;
}
if (substr($result, -3) == ' . ') {
// Write string concatenation character directly before strings
$result = rtrim($result);
}
$result .= $text;
break;
default:
$result .= $text;
break;
}
}
else {
// If we get here, then we have found not a single char, but a token.
// See <http://www.php.net/manual/en/tokens.php> for a reference.
// Fetch token array
list($id, $text) = $token;
// Debugging
/*
if ($lasttoken[0] == T_WHITESPACE) {
$result .= token_name($id);
}
*/
switch ($id) {
case T_ARRAY:
// Write array in lowercase
$result .= strtolower(trim($text));
break;
case T_OPEN_TAG:
case T_OPEN_TAG_WITH_ECHO:
$in_php = true;
// Add a line break between two PHP tags
if (substr(rtrim($result), -2) == '?>') {
$result .= coder_br();
}
$result .= trim($text);
if ($first_php_tag) {
$result .= coder_br();
$first_php_tag = false;
}
else {
$result .= ' ';
}
break;
case T_CLOSE_TAG:
$in_php = false;
// Remove preceding line break for inline PHP output in HTML
if (substr(rtrim($result), -1) == ';' || substr(rtrim($result), -1) == ':') {
$result = rtrim($result) . ' ';
}
$result .= trim($text);
break;
case T_OBJECT_OPERATOR:
$in_object = true;
$result .= trim($text);
break;
case T_CONSTANT_ENCAPSED_STRING:
if (substr($result, -2) == '. ') {
// Write string concatenation character directly before strings
$result = rtrim($result);
}
// Move on to T_STRING / T_VARIABLE
case T_STRING:
case T_VARIABLE:
if ($in_object || $in_at) {
// No space after object operator ($foo->bar) and error suppression (@function())
$result = rtrim($result) . trim($text);
$in_object = false;
$in_at = false;
}
else {
if (!in_array($lasttoken[0], array(
T_ARRAY_CAST,
T_BOOL_CAST,
T_DOUBLE_CAST,
T_INT_CAST,
T_OBJECT_CAST,
T_STRING_CAST,
T_UNSET_CAST,
))) {
// Insert a space after right parenthesis, but not after type casts
coder_add_space($result);
}
$result .= trim($text);
}
break;
case T_ENCAPSED_AND_WHITESPACE:
$result .= $text;
break;
case T_WHITESPACE:
// Avoid duplicate line feeds outside arrays
$c = $parenthesis ? 0 : 1;
for ($c, $cc = substr_count($text, chr(10)); $c < $cc; ++$c) {
if ($parenthesis) {
// Add extra indent for each parenthesis in multiline definitions (f.e. arrays)
$_coder_indent = $_coder_indent + $parenthesis;
$result = rtrim($result) . coder_br();
$_coder_indent = $_coder_indent - $parenthesis;
}
else {
// Discard any whitespace, just insert a line break
$result .= coder_br();
}
}
break;
case T_IF:
case T_FOR:
case T_FOREACH:
case T_SWITCH:
case T_GLOBAL:
case T_STATIC:
case T_ECHO:
case T_PRINT:
case T_NEW:
case T_REQUIRE:
case T_REQUIRE_ONCE:
case T_INCLUDE:
case T_INCLUDE_ONCE:
coder_add_space($result);
// Append a space
$result .= trim($text) . ' ';
break;
case T_DO:
$result .= trim($text);
$in_do_while = true;
break;
case T_WHILE:
if ($in_do_while) {
// Write while after right parenthesis for do {...} while()
$result = rtrim($result) . ' ';
$in_do_while = false;
}
// Append a space
$result .= trim($text) . ' ';
break;
case T_ELSE:
case T_ELSEIF:
// Write else and else if to a new line
$result = rtrim($result) . coder_br() . trim($text) . ' ';
break;
case T_CASE:
case T_DEFAULT:
$braces_in_case = 0;
$result = rtrim($result);
if (!$in_case) {
$in_case = true;
// Add a line break between cases
if (substr($result, -1) != '{') {
$result .= coder_br();
}
}
else {
// Decrease current indent to align multiple cases
--$_coder_indent;
}
$result .= coder_br() . trim($text) . ' ';
break;
case T_BREAK:
// Write break to a new line
$result = rtrim($result) . coder_br() . trim($text);
if ($in_case && !$braces_in_case) {
--$_coder_indent;
$in_case = false;
}
break;
case T_RETURN:
case T_CONTINUE:
coder_add_space($result);
$result .= trim($text) . ' ';
// Decrease indent only if we're not in a control structure inside a case
if ($in_case && !$braces_in_case) {
--$_coder_indent;
$in_case = false;
}
break;
case T_FUNCTION:
case T_CLASS:
// Write function and class to new lines
$result = rtrim($result);
if (substr($result, -1) == '}') {
$result .= coder_br();
}
$result .= coder_br() . trim($text) . ' ';
break;
case T_AND_EQUAL:
case T_AS:
case T_BOOLEAN_AND:
case T_BOOLEAN_OR:
case T_CONCAT_EQUAL:
case T_DIV_EQUAL:
case T_DOUBLE_ARROW:
case T_IS_EQUAL:
case T_IS_NOT_EQUAL:
case T_IS_IDENTICAL:
case T_IS_NOT_IDENTICAL:
case T_IS_GREATER_OR_EQUAL:
case T_IS_SMALLER_OR_EQUAL:
case T_LOGICAL_AND:
case T_LOGICAL_OR:
case T_LOGICAL_XOR:
case T_MINUS_EQUAL:
case T_MOD_EQUAL:
case T_MUL_EQUAL:
case T_OR_EQUAL:
case T_PLUS_EQUAL:
case T_SL:
case T_SL_EQUAL:
case T_SR:
case T_SR_EQUAL:
case T_XOR_EQUAL:
// Surround operators with spaces
if (substr($result, -1) != ' ') {
// $result must not be trimmed to allow multi-line if-clauses
$result .= ' ';
}
$result .= trim($text) . ' ';
break;
case T_COMMENT:
case T_ML_COMMENT:
case T_DOC_COMMENT:
if (substr($text, 0, 3) == '/**') {
// Prepend a new line
$result = rtrim($result) . coder_br() . coder_br();
// Remove carriage returns
$text = str_replace("\r", '', $text);
$lines = explode("\n", $text);
$params_fixed = false;
for ($l = 0; $l < count($lines); ++$l) {
$lines[$l] = trim($lines[$l]);
// Add a new line between function description and first parameter description.
if (!$params_fixed && substr($lines[$l], 0, 8) == '* @param' && $lines[$l - 1] != '*') {
$result .= ' *' . coder_br();
$params_fixed = true;
}
else {
if (!$params_fixed && substr($lines[$l], 0, 8) == '* @param') {
// Do nothing if parameter description is properly formatted.
$params_fixed = true;
}
}
// Add a new line between function params and return.
if (substr($lines[$l], 0, 9) == '* @return' && $lines[$l - 1] != '*') {
$result .= ' *' . coder_br();
}
// Add one space indent to get ' *[...]'
if ($l > 0) {
$result .= ' ';
}
$result .= $lines[$l];
if ($l < count($lines)) {
$result .= coder_br();
}
}
}
else {
$result .= trim($text);
if ($parenthesis) {
// Add extra indent for each parenthesis in multiline definitions (f.e. arrays)
$_coder_indent = $_coder_indent + $parenthesis;
$result = rtrim($result) . coder_br();
$_coder_indent = $_coder_indent - $parenthesis;
}
else {
// Discard any whitespace, just insert a line break
$result .= coder_br();
}
}
break;
case T_INLINE_HTML:
$result .= $text;
break;
case T_START_HEREDOC:
$result .= trim($text) . coder_br(false);
$in_heredoc = true;
break;
case T_END_HEREDOC:
$result .= trim($text) . coder_br(false);
$in_heredoc = false;
break;
default:
$result .= trim($text);
break;
}
// Store last token
$lasttoken = $token;
}
}
return $result;
}
/**
* Generate a line feed including current line indent.
*
* @param bool $add_indent
* Whether to add current line indent after line feed.
*
* @return string
* The resulting string.
*/
function coder_br($add_indent = true) {
global $_coder_indent;
$output = "\n";
if ($add_indent && $_coder_indent >= 0) {
$output .= str_repeat(' ', $_coder_indent);
}
return $output;
}
/**
* Write a space in certain conditions.
*
* A conditional space is needed after a right parenthesis of an if statement
* that is not followed by curly braces.
*
* @param string $result
* Current result string that will be checked.
*
* @return string
* Resulting string with or without an additional space.
*/
function coder_add_space(&$result) {
if (substr($result, -1) == ')') {
$result .= ' ';
}
}
/**
* Trim overall code.
*
* Strips whitespace at the beginning and end of code,
* removes the closing PHP tag and appends two empty lines.
*/
function coder_trim_php($code) {
// Remove surrounding whitespace
$code = trim($code);
// Insert CVS keyword Id
// Search in the very first 1000 chars, insert only one instance.
if (strpos(substr($code, 0, 1000), '$Id') === false) {
$code = preg_replace('/<\\?php\\n/', "<?php\n// \$Id\$\n\n", $code, 1);
}
// Remove closing PHP tag
if (substr($code, -2) == '?>') {
$code = rtrim($code, '?>');
}
// Append two empty lines
$code .= str_repeat(chr(10), 2);
return $code;
}
/**
* Execute special tasks on source code.
*
* This function works similar to the Drupal hook and forms system. It searches
* for all defined functions with the given prefix and performs a preg_replace
* on the source code for each of these functions.
*
* Processor functions are defined with a associative array containing the
* following keys with the corresponding values:
* #title
* A human readable text describing what the processor actually does.
* #search
* The regular expression to search for.
* #replace
* The replacement text for each match.
*
* Optional definitions:
* #debug
* Set this to true to directly output the results of preg_match_all and
* exit script execution after this processor.
*
* @param string $code
* The source code to process.
* @param string $prefix
* Prefix of the functions to execute.
*
* @return string
* The processed source code.
*/
function coder_exec_processors($code, $prefix = '') {
if (empty($prefix)) {
return;
}
$tasks = get_defined_functions();
$tasks = $tasks['user'];
for ($c = 0, $cc = count($tasks); $c < $cc; ++$c) {
if (strpos($tasks[$c], $prefix) === false) {
unset($tasks[$c]);
}
else {
$tasks[$tasks[$c]] = call_user_func($tasks[$c]);
unset($tasks[$c]);
}
}
uasort($tasks, 'coder_order_processors');
foreach ($tasks as $func => $task) {
if (!isset($task['#search']) || !isset($task['#replace']) && !isset($task['#replace_callback'])) {
continue;
}
if (isset($task['#debug'])) {
// Output regular expression results if debugging is enabled.
preg_match_all($task['#search'], $code, $matches, PREG_SET_ORDER);
echo "<pre>";
var_dump($matches);
echo "</pre>\n";
// Exit immediately in debugging mode.
exit;
}
if (isset($task['#replace_callback'])) {
$code = preg_replace_callback($task['#search'], $task['#replace_callback'], $code);
}
else {
$code = preg_replace($task['#search'], $task['#replace'], $code);
}
}
return $code;
}
/**
* Orders preprocessors by weight.
*/
function coder_order_processors($a, $b) {
if (isset($a['#weight']) && isset($b['#weight'])) {
return $a['#weight'] - $b['#weight'];
}
else {
return isset($a['#weight']) ? false : true;
}
}
/**
* @defgroup coder_preprocessor Preprocessors.
* @{
*/
function coder_preprocessor_line_breaks_win() {
return array(
'#title' => 'Convert Windows line breaks to Unix format.',
'#weight' => 1,
'#search' => "/\r\n/",
'#replace' => "\n",
);
}
function coder_preprocessor_line_breaks_mac() {
return array(
'#title' => 'Convert Macintosh line breaks to Unix format.',
'#weight' => 2,
'#search' => "/\r/",
'#replace' => "\n",
);
}
function coder_preprocessor_ml_array_add_comma() {
// @bug coder.module:1010
return array(
'#title' => 'Append a comma to the last value of multiline arrays.',
// ^[\040\t]*(?!\*|\/\/)[^\*\/\n]*? matches anything in front of array, but not comments
// \sarray\( prevents matching of in_array() and function calls
// (\n|(?X>!\);).+?,?\n) matches a line break or the first array item
// (.*?[^,;]) matches the rest array items
// ,?(\n\s*)\); matches the end of multiline array, optionally including a comma
'#search' => '/(^[\\040\\t]*(?!\\*|\\/\\/)[^\\*\\/\\n]*?\\sarray\\()(\\n|(?>!\\);).+?,?\\n)(.*?[^,;]),?(\\n\\s*\\);)/ism',
'#replace' => '$1$2$3,$4',
);
}
function coder_preprocessor_inline_comment() {
return array(
'#title' => 'Move inline comments above remarked line.',
'#weight' => 2,
// [\040\t] matches only a space or tab
// (?!case) prevents matching of case statements
// \S prevents matching of lines containing only a comment
// [^:] prevents matching of URL protocols
// [^;\$] prevents matching of CVS keyword Id comment and double slashes
// in quotes (f.e. "W3C//DTD")
'#search' => '@^([\\040\\t]*)(?!case)(\\S.+?)[\\040\\t]*[^:]//\\s*([^;\\$]+?)$@m',
'#replace' => "\$1// \$3\n\$1\$2",
);
}
function coder_preprocessor_php() {
return array(
'#title' => 'Always use <?php ?> to delimit PHP code, not the <? ?> shorthands.',
'#search' => '/<\\?(\\s)/',
'#replace' => "<?php\$1",
);
}
function coder_preprocessor_switch_duplicate_exit() {
return array(
'#title' => 'Either exit a switch case with return *or* break.',
'#search' => '/(return\\s+.+;)\\s+break;/',
);
}
/**
* @} End of "defgroup coder_preprocessor".
*/
/**
* @defgroup coder_postprocessor Postprocessors.
* @{
*/
function coder_postprocessor_cvs_id() {
return array(
'#title' => 'If the CVS keyword Id already exists, append a new line after it.',
'#search' => '@^(//.*\\$Id.*\\$)$@m',
'#replace' => "\$1\n",
);
}
function coder_postprocessor_multiple_vars() {
// @todo Prevent matching of multiple lines separated by a blank line 26/03/2007 sun
return array(
'#title' => 'Align equal signs of multiple variable assignments in the same column.',
// \s* matches whitespace including new lines
// \$.+? matches variable names
// {3,} requires the pattern to match at least 3 times
'#search' => '/^(\\s*\\$.+? = .+?$){3,}/m',
'#replace_callback' => 'coder_replace_multiple_vars',
);
}
function coder_replace_multiple_vars($matches) {
// Retrieve all variable name = variable value pairs
preg_match_all('/^(\\s*)(\\$.+?) (.?)= (.+?$)/m', $matches[0], $vars, PREG_SET_ORDER);
// Determine the longest variable name
$maxlength = 0;
foreach ($vars as $var) {
if (strlen($var[2]) > $maxlength) {
$maxlength = strlen($var[2] . $var[3]);
}
}
// Realign variable values at the longest variable names
$return = '';
$extra_spaces = 0;
for ($c = 0, $cc = count($vars); $c < $cc; ++$c) {
if ($maxlength <= 20) {
$extra_spaces = $maxlength - strlen($vars[$c][2] . $vars[$c][3]);
}
$return .= $vars[$c][1] . $vars[$c][2];
$return .= str_repeat(' ', $extra_spaces) . ' ' . $vars[$c][3] . '= ';
$return .= $vars[$c][4];
if ($c < $cc - 1) {
// Append a line break, but not to the last variable assignment
$return .= "\n";
}
}
return $return;
}
function coder_postprocessor_array_rearrange() {
// @bug common.inc, comment.module:1506->1519, comment.module:1525->1550,
// user.module:913->934
// not yet working properly 25/03/2007 sun
return array(
'#title' => 'Break array elements into separate lines, indented one level.',
// ([\040\t]*) matches blanks and tabs
// (.*?array\() matches anything and 'array('
// ((.+ => .+, ){3,}) matches all array items, except the last one
// (.+ => ([^\(\)]+)) matches the last array item, excluding
// arrays or functions (starting with a left parenthesis) [not supported yet]
#'#search' => '/^([\040\t]*)(.*?array\()((.+ => .+, ){3,})(.+ => ([^\(\)]+))\)/m',
'#replace_callback' => 'coder_replace_array_rearrange',
);
}
function coder_replace_array_rearrange($matches) {
// Retrieve all array items, except the last one
preg_match_all('/(.+? => .+?,) /', $matches[3], $items);
// The original line including array(
$return = $matches[1] . $matches[2] . "\n";
foreach ($items[1] as $item) {
// All array items, except the last one, with extra indent
$return .= $matches[1] . ' ' . $item . "\n";
}
// Last array item, with extra indent and comma
$return .= $matches[1] . ' ' . $matches[5] . ",\n";
// Closing parenthesis (on a new line)
$return .= $matches[1] . ')';
return $return;
}
function coder_postprocessor_if_curly_braces() {
// @todo This is just a starting point for manual replacement at the moment.
return array(
'#title' => 'Use curly braces even in situations where they are technically optional.',
'#search' => '/if \\(.+\\) [^\\{]+;/',
);
}
/**
* @} End of "defgroup coder_postprocessor".
*/
/**
* @defgroup coder_format_stub_functions
* @{
*/
if (!function_exists('variable_get')) {
function variable_get($name, $default) {
global $conf;
return isset($conf[$name]) ? $conf[$name] : $default;
}
}
if (!function_exists('variable_set')) {
function variable_set($name, $value) {
global $conf;
$conf[$name] = $value;
}
}
if (!function_exists('t')) {
function t($string, $args = 0) {
if (!$args) {
return $string;
}
else {
return strtr($string, $args);
}
}
}
if (!function_exists('drupal_set_message')) {
function drupal_set_message($message = NULL, $type = 'status') {
echo $message;
}
}
if (!function_exists('watchdog')) {
function watchdog($type, $message, $severity = 0, $link = null) {
return;
}
}
if (!function_exists('check_plain')) {
function check_plain($text) {
return htmlspecialchars($text, ENT_QUOTES);
}
}
/**
* @} End of "defgroup coder_format_stub_functions".
*/
Functions
Name | Description |
---|---|
coder_add_space | Write a space in certain conditions. |
coder_br | Generate a line feed including current line indent. |
coder_exec_processors | Execute special tasks on source code. |
coder_format_file | Reads, processes and writes the source code from and to a file. |
coder_format_recursive | Recursively process .module and .inc files in directory. |
coder_format_string | Format the source code according to Drupal coding style guidelines. |
coder_order_processors | Orders preprocessors by weight. |
coder_postprocessor_array_rearrange | |
coder_postprocessor_cvs_id | |
coder_postprocessor_if_curly_braces | |
coder_postprocessor_multiple_vars | |
coder_preprocessor_inline_comment | |
coder_preprocessor_line_breaks_mac | |
coder_preprocessor_line_breaks_win | |
coder_preprocessor_ml_array_add_comma | |
coder_preprocessor_php | |
coder_preprocessor_switch_duplicate_exit | |
coder_replace_array_rearrange | |
coder_replace_multiple_vars | |
coder_trim_php | Trim overall code. |