Ejemplo n.º 1
0
function ParseIt($data, $name = 'theater', $path = '', $level = 0)
{
    global $ordered_fields, $object_fields;
    $out = array();
    // Figure out if we are dealing with named objects, or section names
    // If this is an ordered field, parse the sub-items
    $path = $path ? "{$path}/{$name}" : $name;
    $objects = matchTheaterPath($path, $object_fields);
    $ordered = matchTheaterPath($path, $ordered_fields);
    //	echo "path: {$path} ordered: {$ordered}\n";
    if ($ordered) {
        $items = array();
        foreach ($data as $idx => $item) {
            foreach ($item as $key => $val) {
                $items[$key] = $val;
            }
        }
    } else {
        $items = $data;
    }
    foreach ($items as $key => $val) {
        $title = $objects ? "@name" : $key;
        if (is_array($val)) {
            $pdata = ParseIt($val, $title, $path, $level + 1);
            if (isset($out[$title])) {
                $pdata = theater_array_replace_recursive($out[$title], $pdata);
            }
            $out[$title] = $pdata;
            uksort($out[$title], "strnatcasecmp");
        } else {
            $out[$title] = vartype($val);
        }
    }
    uksort($out, "strnatcasecmp");
    return $out;
}
Ejemplo n.º 2
0
function parseKeyValues($KVString, $fixquotes = true, $debug = false)
{
    global $ordered_fields, $theater_conditions, $allow_duplicates_fields;
    // Escape all non-quoted values
    if ($fixquotes) {
        $KVString = preg_replace('/^(\\s*)([a-zA-Z]+)/m', '${1}"${2}"', $KVString);
    }
    $KVString = preg_replace('/^(\\s+)/m', '', $KVString);
    $KVLines = preg_split('/\\n|\\r\\n?/', $KVString);
    $len = strlen($KVString);
    // if ($debug) $len = 2098;
    $stack = array();
    $isInQuote = false;
    $quoteKey = "";
    $quoteValue = "";
    $quoteWhat = "key";
    $lastKey = "";
    $lastPath = "";
    $lastValue = "";
    $lastLine = "";
    $keys = array();
    $comments = array();
    $commentLines = 1;
    $ptr =& $stack;
    $c = "";
    $line = 1;
    $parents = array(&$ptr);
    $tree = array();
    $path = "";
    $sequential = '';
    $sequential_path = '';
    $conditional = '';
    $conditional_path = '';
    $allowdupes = '';
    for ($i = 0; $i < $len; $i++) {
        $l = $c;
        $c = $KVString[$i];
        // current char
        switch ($c) {
            case "\"":
                $commentLines = 1;
                if ($isInQuote) {
                    // EDIT: Use quoteWhat as a qualifier rather than quoteValue in case we have a "" value
                    if (strlen($quoteKey) && $quoteWhat == "value") {
                        if ($sequential) {
                            if (!$allowdupes) {
                                // Check to make sure this value does not already exist
                                if (is_array($ptr)) {
                                    foreach ($ptr as $item) {
                                        if (isset($item[$quoteKey])) {
                                            if ($item[$quoteKey] == $quoteValue) {
                                                $quoteValue = '';
                                            }
                                        }
                                    }
                                }
                            }
                            if ($quoteValue) {
                                $ptr[] = array($quoteKey => TypecastValue($quoteValue));
                            }
                        } else {
                            // If this value is already set, make it an array
                            if (isset($ptr[$quoteKey])) {
                                // If the item is not already an array, make it one
                                if (!is_array($ptr[$quoteKey])) {
                                    $ptr[$quoteKey] = array($ptr[$quoteKey]);
                                }
                                // Add this value to the end of the array
                                $ptr[$quoteKey][] = TypecastValue($quoteValue);
                            } else {
                                // Set the value otherwise
                                $ptr[$quoteKey] = TypecastValue($quoteValue);
                            }
                        }
                        $lastLine = $line;
                        $lastPath = "{$path}/{$quoteKey}";
                        $lastKey = $quoteKey;
                        $quoteKey = "";
                        $quoteValue = "";
                    }
                    if ($quoteWhat == "key") {
                        $quoteWhat = "value";
                    } else {
                        if ($quoteWhat == "value") {
                            $quoteWhat = "key";
                        }
                    }
                }
                $isInQuote = !$isInQuote;
                break;
                // Start new section
            // Start new section
            case "{":
                $commentLines = 1;
                if (strlen($quoteKey)) {
                    if (substr($quoteKey, 0, 1) == '?') {
                        $conditional = $quoteKey;
                        $conditional_path = $path;
                    } else {
                        // Add key to tree
                        $tree[] = $quoteKey;
                        // Update path in tree
                        $path = implode("/", $tree);
                        if ($conditional) {
                            $theater_conditions[$conditional][] = $path;
                        }
                        $sequential = matchTheaterPath($path, $ordered_fields);
                        if (!$sequential_path && $sequential) {
                            $sequential_path = $path;
                            //							echo "sequential {$sequential} path {$path} sequential_path {$sequential_path}\n";
                        }
                        if (!$allowdupes) {
                            //							echo "test allowdupes\n";
                            $allowdupes = matchTheaterPath($path, $allow_duplicates_fields);
                            //							echo "allowdupes {$allowdupes}\n";
                        }
                        // Update parents array with current pointer in the new path location
                        $parents[$path] =& $ptr;
                        // If the object already exists, create an array of objects
                        if ($quoteKey[0] == '?') {
                            $ptr =& $ptr[][$quoteKey];
                        } elseif (isset($ptr[$quoteKey])) {
                            // Get all the keys, this assumes that the data will have non-numeric keys.
                            $keys = implode('', array_keys($ptr[$quoteKey]));
                            // So when we see non-numeric keys, we push the existing data into an array of itself before appending the next object.
                            if (!is_numeric($keys)) {
                                $ptr[$quoteKey] = array($ptr[$quoteKey]);
                            }
                            // Move the pointer to a new array under the key
                            $ptr =& $ptr[$quoteKey][];
                        } else {
                            // Just put the object here if there is no existing object
                            $ptr =& $ptr[$quoteKey];
                        }
                        $lastPath = "{$path}/{$quoteKey}";
                        $lastKey = $quoteKey;
                    }
                    $quoteKey = "";
                    $quoteWhat = "key";
                }
                $lastLine = $line;
                break;
                // End of section
            // End of section
            case "}":
                $commentLines = 1;
                // Move pointer back to the parent
                if ($conditional_path != $path) {
                    $sequential = '';
                    if ($path == $allowdupes) {
                        $allowdupes = '';
                        //						echo "done allowdupes\n";
                    }
                    if ($sequential) {
                        //						echo "} sequential {$sequential} path {$path} sequential_path {$sequential_path}\n";
                        if ($path == $sequential_path) {
                            //							echo "unset\n";
                            $sequential_path = '';
                        }
                    }
                    $ptr =& $parents[$path];
                    // Take last element off tree as we back out
                    array_pop($tree);
                    // Update path now that we have backed out
                    $path = implode("/", $tree);
                } else {
                    $conditional = '';
                    $conditional_path = '';
                }
                $lastLine = $line;
                break;
            case "\t":
                break;
            case "/":
                // Comment "// " or "/*"
                if ($KVString[$i + 1] == "/" || $KVString[$i + 1] == "*") {
                    $comment = "";
                    // Get comment type
                    $ctype = $KVString[$i + 1];
                    while ($i < $len) {
                        // If type is "// " stop processing at newline
                        if ($ctype == '/' && $KVString[$i + 1] == "\n") {
                            // 							$i+=2;
                            break;
                        }
                        // If type is "/*" stop processing at "*/"
                        if ($ctype == '*' && $KVString[$i + 1] == "*" && $KVString[$i + 2] == "/") {
                            $i += 2;
                            $comment .= "*/";
                            break;
                        }
                        $comment .= $KVString[$i];
                        $i++;
                    }
                    $comment = trim($comment);
                    // Was this comment inline, or after the last item we processed?
                    $where = $lastLine == $line ? 'inline' : 'newline';
                    // If last line was also a comment, see if we can merge into a multi-line comment
                    // Use the commentLines to see how far back this started
                    $lcl = $line - $commentLines;
                    if (isset($comments[$lcl])) {
                        $lc = $comments[$lcl];
                        if ($lc['path'] == $lastPath) {
                            $comments[$lcl]['line_text'] .= "\n{$KVLines[$line - 1]}";
                            $comments[$lcl]['comment'] .= "\n{$comment}";
                            $comment = '';
                            $commentLines++;
                        }
                    }
                    // If we have a comment, add it to the list
                    if ($comment) {
                        $comments[$line] = array('path' => $lastPath, 'where' => $where, 'line' => $line, 'line_text' => $KVLines[$line - 1], 'comment' => $comment);
                    }
                    continue;
                }
            default:
                if ($isInQuote) {
                    if ($quoteWhat == "key") {
                        $quoteKey .= $c;
                    } else {
                        $quoteValue .= $c;
                    }
                }
                if ($c == "\n") {
                    $line++;
                }
        }
    }
    if ($debug) {
        echo "<hr><pre>";
        var_dump("stack: ", $stack);
    }
    return $stack;
}