User:ClueBot II/ClueBot Script/Interpreter

You will need the following files for this:

  1. cbs_interpreter.php (below)
  2. cluebot2.cbsfunctions.php (below)
  3. wikibot.classes.php (found here)
  4. cluebot2.config.php (below)
  5. test.cbs (below)

Usage

edit

php cbs_interpreter.php file.cbs

For example: php cbs_interpreter.php test.cbs

CBS Functions

edit

(cluebot2.cbsfunctions.php)

<?PHP
        $debug = true;
        function getarguments ($data,&$return,&$session,$conditionals = true,$delimiter = ' ') {
                $pos = 0;
                $depthp = 0;
                $depthb = 0;
                $quotes1 = 0;
                $quotes2 = 0;
                $tmp = '';
                $chr = '';
                $data = trim($data);
                $array = array();

                while ($pos < strlen($data)) {
                        $chr = $data{$pos};
                        if (($quotes1 == 1) and ($chr == '"')) { $quotes1 = 0; }
                        elseif (($quotes2 == 1) and ($chr == "'")) { $quotes2 = 0; }
                        elseif (($quotes1 == 0) and ($quotes2 == 0)) {
                                if ($depthb == 0) {
                                        if ($chr == '(') $depthp++;
                                        if ($chr == ')') $depthp--;
                                }
                                if ($depthp == 0) {
                                        if ($chr == '{') $depthb++;
                                        if ($chr == '}') $depthb--;
                                }
                                if ($chr == '"') $quotes1 = 1;
                                if ($chr == "'") $quotes2 = 1;
                                if (($chr == $delimiter) and ($depthp == 0) and ($depthb == 0)) { $array[] = $tmp; $tmp = ''; $pos++; continue; }
                        }
                        $tmp .= $chr;
                        $pos++;
                }
                $array[] = $tmp;

                foreach ($array as $arg) {
                        if ($arg{0} == '%') {
                                $return[] = &$session['vars'][substr($arg,1)];
                        } elseif ($arg{0} == '{') {
                                $return[] = $arg;
                        } elseif (($conditionals == false) and ($arg{0} == '(')) {
                                $return[] = $arg;
                        } else {
                                $return[] = evalconditional($arg,&$session);
                        }
                }
        }

        function evalfunction ($function,&$session) {
                if (preg_match('/^\$([^(]+)\((.*)\)$/',trim($function),$m)) {
                        $func = strtolower($m[1]);
                        $args = array();
                        getarguments($m[2],&$args,&$session,true,',');
                        switch ($func) {
                                case '+':
                                case 'cat':
                                        $ret = '';
                                        foreach ($args as $arg) {
                                                $ret .= $arg;
                                        }
                                        return $ret;
                                        break;
                                case 'mid':
                                case 'substr':
                                        if (count($args) == 2) {
                                                return substr($args[0],$args[1]);
                                        } elseif (count($args) == 3) {
                                                return substr($args[0],$args[1],$args[2]);
                                        }
                                        break;
                                case 'gettok':
                                        if (count($args) >= 3) {
                                                if (count($args) == 4) {
                                                        $x = explode($args[1],$args[0],$args[3]);
                                                } elseif (count($args) == 3) {
                                                        $x = explode($args[1],$args[0]);
                                                }
                                                if ($args[2] == 0) {
                                                        return count($x);
                                                } else {
                                                        return $x[$args[2] - 1];
                                                }
                                        }
                                        break;
                                case 'settok':
                                        if (count($args) == 4) {
                                                $x = explode($args[1],$args[0]);
                                                $x[$args[2] - 1] = $args[3];
                                                return implode($args[1],$x);
                                        }
                                        break;
                                case 'addtok':
                                        if (count($args) == 3) {
                                                $x = explode($args[1],$args[0]);
                                                $x[] = $args[2];
                                                return implode($args[1],$x);
                                        }
                                        break;
                                case 'deltok':
                                        if (count($args) == 3) {
                                                $x = explode($args[1],$args[0]);
                                                unset($x[$args[2] - 1]);
                                                return implode($args[1],$x);
                                        }
                                        break;
                                case 'strpos':
                                        if (count($args) == 2) {
                                                return ((($x = strpos($args[0],$args[1])) === false)?-1:$x);
                                        } elseif (count($args) == 3) {
                                                return ((($x = strpos($args[0],$args[1],$args[2])) === false)?-1:$x);
                                        }
                                        break;
                                case 'stripos':
                                        if (count($args) == 2) {
                                                return ((($x = stripos($args[0],$args[1])) === false)?-1:$x);
                                        } elseif (count($args) == 3) {
                                                return ((($x = stripos($args[0],$args[1],$args[2])) === false)?-1:$x);
                                        }
                                        break;
                                case 'replace':
                                        if ((count($args) % 2) == 1) {
                                                $search = array();
                                                $replace = array();
                                                $data = $args[0];
                                                for ($i=1;$i<count($args);$i+=2) {
                                                        $search[] = $args[$i];
                                                        $replace[] = $args[$i + 1];
                                                }
                                                return str_replace($search,$replace,$data);
                                        }
                                        break;
                                case 'pregreplace':
                                        if (count($args) == 3) {
                                                return preg_replace($args[1],$args[2],$args[0]);
                                        }
                                        break;
                                case 'time':
                                        return time();
                                        break;
                        }
                }
        }

        function evalconditional ($conditional,&$session) {
                global $debug;
                if ($debug) echo 'evalconditional("'.$conditional.'",'.serialize($session).');'."\n";
                $pos = 0;
                $depth = 0;
                $part = 1;
                $quotes1 = 0;
                $quotes2 = 0;
                $c1 = '';
                $op = '';
                $c2 = '';

                while ($pos < strlen($conditional)) {
                        $chr = $conditional{$pos};
                        $chr2 = $conditional{$pos+1};
                        $chr3 = $conditional{$pos+2};
                        if (($quotes1 == 1) and ($chr == '"')) { $quotes1 = 0; }
                        elseif (($quotes2 == 1) and ($chr == "'")) { $quotes2 = 0; }
                        elseif (($quotes1 == 0) and ($quotes2 == 0)) {
                                if ($chr == '(') $depth++;
                                if ($chr == ')') $depth--;
                                if ($chr == '"') $quotes1 = 1;
                                if ($chr == "'") $quotes2 = 1;
                        }
                        if (($depth == 0) and (preg_match('/^(\<=|\>=|\<|\>|==|or|\|\||and|&&|!=|\+|\-| \% |\^|\=|\||\&)/i',$chr.$chr2.$chr3,$m)) and ($quotes1 == 0) and ($quotes2 == 0)) {
                                $op = $m[1];
                                $part = 2;
                                $pos += (strlen($op) - 1);
                        } elseif ($part == 1) {
                                $c1 .= $chr;
                        } elseif ($part == 2) {
                                $c2 .= $chr;
                        }
                        $pos++;
                }
                $c1 = trim($c1);
                $op = trim($op);
                $c2 = trim($c2);

                if (substr($c1,0,1) == '%') {
                        $d1 = '$e1';
                        $e1 = &$session['vars'][substr($c1,1)];
                } elseif (substr($c1,0,1) == '$') {
                        $d1 = 'evalfunction($c1,&$session)';
                } elseif ((substr($c1,0,1) == '(') and (substr($c1,-1,1) == ')')) {
                        $d1 = 'evalconditional($e1,&$session)';
                        $e1 = substr($c1,1,-1);
                } elseif (((substr($c1,0,1) == '"') and (substr($c1,-1,1) == '"')) or ((substr($c1,0,1) == "'") and (substr($c1,-1,1) == "'"))) {
                        $d1 = '$e1';
                        if (substr($c1,0,1) == '"') { $c1 = str_replace(array('\n', '\r'),array("\n", "\r"),$c1); }
                        $e1 = substr($c1,1,-1);
                } elseif (preg_match('/^[0-9+-]*$/',$c1)) {
                        $d1 = $c1;
                } else {
                        $d1 = 'false';
                }


                if (($op) and ($c2)) {
                        if (substr($c2,0,1) == '%') {
                                $d2 = '$e2';
                                $e2 = &$session['vars'][substr($c2,1)];
                        } elseif (substr($c2,0,1) == '$') {
                                $d2 = 'evalfunction($c2,&$session)';
                        } elseif ((substr($c2,0,1) == '(') and (substr($c2,-1,1) == ')')) {
                                $d2 = 'evalconditional($e2,&$session)';
                                $e2 = substr($c2,1,-1);
                        } elseif (((substr($c2,0,1) == '"') and (substr($c2,-1,1) == '"')) or ((substr($c2,0,1) == "'") and (substr($c2,-1,1) == "'"))) {
                                $d2 = '$e2';
                                if (substr($c2,0,1) == '"') { $c2 = str_replace(array('\n', '\r'),array("\n", "\r"),$c2); }
                                $e2 = substr($c2,1,-1);
                        } elseif (preg_match('/^[0-9+-]*$/',$c2)) {
                                $d2 = $c2;
                        } else {
                                $d2 = 'false';
                        }

                        if ($debug) echo 'eval(\'$ret = ('.$d1.' '.$op.' '.$d2.');\');'."\n";
                        eval('$ret = ('.$d1.' '.$op.' '.$d2.');');
                } else {
                        if ($debug) echo 'eval(\'$ret = '.$d1.';\');'."\n";
                        eval('$ret = '.$d1.';');
                }
                return $ret;
        }

        function evalstatement ($statement,&$session) {
                global $wpq;
                global $wpapi;
                global $wpi;
                global $debug;

                if ($debug) echo 'evalstatement("'.$statement.'",'.serialize($session).');'."\n";
                $statements = array (
                        'if',                   'set',
                        'unset',                'while',
                        'foreach',              'pagereplace',
                        'pageappend',           'pagepregreplace',
                        'pageget',              'pageset',
                        'pageprepend',          'varappend',
                        'varprepend',           'getrecentchanges',
                        'getcategorymembers',   'eval',
                        'getmodifiedtime',      'getbacklinks',
                        'getembeddedin'
                        );

                foreach ($statements as $s) {
                        if (strtolower(substr($statement,0,strlen($s))) == $s) {
                                $rest = substr($statement,strlen($s));
                                switch ($s) {
                                        case 'while':
                                        case 'if':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session,false);
//                                              print_r($tmp);
                                                if ($s == 'if') {
                                                        if (evalconditional($tmp[0],&$session)) {
                                                                evalscript($tmp[1],&$session);
                                                        }
                                                } elseif ($s == 'while') {
                                                        while (evalconditional($tmp[0],&$session)) {
                                                                evalscript($tmp[1],&$session);
                                                        }
                                                }
                                                break;
                                        case 'set':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                $tmp[0] = $tmp[1];
                                                break;
                                        case 'unset':
                                                $rest = trim($rest);
                                                if ($rest{0} == '%') {
                                                        unset($session['vars'][substr($rest,1)]);
                                                }
                                                break;
                                        case 'pagereplace':
                                        case 'pagepregreplace':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                $page = $tmp[0];
                                                $search = $tmp[1];
                                                $replace = $tmp[2];
                                                if (isset($tmp[3])) {
                                                        $editsummary = $tmp[3];
                                                } else {
                                                        $editsummary = 'Replacing "'.$search.'" with "'.$replace.'". (bot)';
                                                }
                                                if ($s == 'pagereplace') {
                                                        $wpi->post($page,str_replace($search,$replace,$wpq->getpage($page)),$editsummary);
                                                } elseif ($s == 'pagepregreplace') {
                                                        $wpi->post($page,preg_replace($search,$replace,$wpq->getpage($page)),$editsummary);
                                                }
                                                break;
                                        case 'pageappend':
                                        case 'pageprepend':
                                        case 'pageset':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                $page = $tmp[0];
                                                $data = $tmp[1];
                                                if (isset($tmp[2])) {
                                                        $editsummary = $tmp[2];
                                                } else {
                                                        if ($s == 'pageappend') {
                                                                $editsummary = 'Appending "'.((strlen($data) > 150)?substr($data,0,150).'...':$data).'". (bot)';
                                                        } elseif ($s == 'pageset') {
                                                                $editsummary = 'Setting page to "'.((strlen($data) > 100)?substr($data,0,100).'...':$data).'". (bot)';
                                                        }
                                                }
                                                if ($s == 'pageappend') {
                                                        $data = $wpq->getpage($page).$data;
                                                } elseif ($s == 'pageprepend') {
                                                        $data = $data.$wpq->getpage($page);
                                                }
                                                $wpi->post($page,$data,$editsummary);
                                                break;
                                        case 'pageget':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                $page = $tmp[0];
                                                $tmp[1] = $wpq->getpage($page);
                                                break;
                                        case 'varappend':
                                        case 'varprepend':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                if ($s == 'varprepend') {
                                                        $tmp[0] = $tmp[1].$tmp[0];
                                                } elseif ($s == 'varappend') {
                                                        $tmp[0] .= $tmp[1];
                                                }
                                                break;
                                        case 'foreach':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                foreach (explode($tmp[1],$tmp[0]) as $tmp[2]) {
                                                        evalscript(trim($tmp[3]),&$session);
                                                }
                                                break;
                                        case 'getrecentchanges':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                if (count($tmp) == 2) {
                                                        $x = $wpapi->recentchanges();
                                                } elseif (count($tmp) == 3) {
                                                        $x = $wpapi->recentchanges($tmp[2]);
                                                }
                                                $z = array();
                                                foreach ($x as $y) {
                                                        $z[] = $y['title'];
                                                }
                                                $tmp[0] = implode($tmp[1],$z);
                                                break;
                                        case 'getcategorymembers':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                if (count($tmp) == 3) {
                                                        $x = $wpapi->categorymembers($tmp[2]);
                                                } elseif (count($tmp) == 4) {
                                                        $x = $wpapi->categorymembers($tmp[2],$tmp[3]);
                                                } elseif (count($tmp) == 5) {
                                                        $x = $wpapi->categorymembers($tmp[2],$tmp[3],$tmp[4]);
                                                }
                                                $z = array();
                                                foreach ($x as $y) { $z[] = $y['title']; }
                                                $tmp[0] = implode($tmp[1],$z);
                                                break;
                                        case 'getbacklinks':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                if (count($tmp) == 3) {
                                                        $x = $wpapi->backlinks($tmp[2]);
                                                } elseif (count($tmp) == 4) {
                                                        $x = $wpapi->backlinks($tmp[2],$tmp[3]);
                                                } elseif (count($tmp) == 5) {
                                                        $x = $wpapi->backlinks($tmp[2],$tmp[3],$tmp[4]);
                                                }
                                                $z = array();
                                                foreach ($x as $y) { $z[] = $y['title']; }
                                                $tmp[0] = implode($tmp[1],$z);
                                                break;
                                        case 'getembeddedin':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                if (count($tmp) == 3) {
                                                        $x = $wpapi->embeddedin($tmp[2]);
                                                } elseif (count($tmp) == 4) {
                                                        $x = $wpapi->embeddedin($tmp[2],$tmp[3]);
                                                } elseif (count($tmp) == 5) {
                                                        $x = $wpapi->embeddedin($tmp[2],$tmp[3],$tmp[4]);
                                                }
                                                $z = array();
                                                foreach ($x as $y) { $z[] = $y['title']; }
                                                $tmp[0] = implode($tmp[1],$z);
                                                break;
                                        case 'getmodifiedtime':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                if (count($tmp) == 2) {
                                                        $x = $wpapi->revisions($tmp[1]);
                                                        if (preg_match('/(\d+)\-(\d+)\-(\d+)T(\d+):(\d+):(\d+)/',$x[0]['timestamp'],$m)) {
                                                                $tmp[0] = gmmktime($m[4],$m[5],$m[6],$m[2],$m[3],$m[1]);
                                                        }
                                                }
                                                break;
                                        case 'eval':
                                                $tmp = array();
                                                getarguments($rest,&$tmp,&$session);
                                                evalscript($tmp[0],&$session);
                                                break;
                                }
                                break;
                        }
                }
        }

        function evalscript ($script,&$session = array()) {
                /* Ok, we need to evaluate a ClueBot Script. */
                global $debug;
                if ($debug) echo 'evalscript("'.$script.'",'.serialize($session).');'."\n";

                $pos = 0;
                $quotes1 = 0;
                $quotes2 = 0;
                $depth = 0;
                $script = trim($script);
                $tmp = '';

                if ((substr($script,0,1) == '{') and (substr($script,-1,1) == '}')) {
                        $script = trim(substr($script,1,-1));
                }

                while ($pos < strlen($script)) {
                        if (($quotes1 == 1) and ($script{$pos} == '"')) $quotes1 = 0;
                        elseif (($quotes2 == 1) and ($script{$pos} == "'")) $quotes2 = 0;
                        elseif (($quotes1 == 0) and ($quotes2 == 0)) {
                                if ($script{$pos} == '"') $quotes1 = 1;
                                if ($script{$pos} == "'") $quotes2 = 1;
                                if ($script{$pos} == '{') $depth++;
                                if ($script{$pos} == '}') $depth--;
                                if ((($script{$pos} == ';') or ($script{$pos} == '}')) and ($depth == 0)) {
                                        if ($script{$pos} == '}') $tmp .= $script{$pos};
                                        evalstatement(trim($tmp),&$session);
                                        $tmp = '';
                                        $pos++;
                                        continue;
                                }
                        }
                        $tmp .= $script{$pos};
                        $pos++;
                }
        }
?>

Interpreter

edit

(cbs_interpreter.php)

<?PHP
        include 'cluebot2.cbsfunctions.php';
        include 'wikibot.classes.php';
        include 'cluebot2.config.php';

        $wpq = new wikipediaquery;
        $wpi = new wikipediaindex;
        $wpapi = new wikipediaapi;

        $wpapi->login($user,$pass);

        $debug = false;
        $session = array();
        evalscript(file_get_contents($_SERVER['argv'][1]),&$session);
        /* Comment the following lines out if you don't want debugging */
        if (is_array($session['vars'])) {
                foreach ($session['vars'] as $var => $value) {
                        echo '%'.$var.' = '.$value."\n";
                }
        }
?>

Config

edit

(cluebot2.config.php)

<?PHP
        $owner = '';/* Put your username between the two single quotes. */
        $user = ''; /* Put your bot's username between the two single quotes. */
        $pass = ''; /* Put your bot's password between the two single quotes. */
        $status = 'rw';
        $maxlag = 2; /* Max lag */
        $maxlagkeepgoing = true; /* If we get a maxlag error, keep going */
?>

Example

edit

(test.cbs)

pageappend "Wikipedia:Sandbox" "\n\nThis is a test.\n";

Documentation

edit

See ClueBot Script documentation.