Code

Split removal - first flush
authorcajus <cajus@594d385d-05f5-0310-b6e9-bd551577e9d8>
Tue, 26 Jan 2010 08:27:39 +0000 (08:27 +0000)
committercajus <cajus@594d385d-05f5-0310-b6e9-bd551577e9d8>
Tue, 26 Jan 2010 08:27:39 +0000 (08:27 +0000)
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@15296 594d385d-05f5-0310-b6e9-bd551577e9d8

21 files changed:
gosa-core/html/getFAIstatus.php
gosa-core/html/helpviewer.php
gosa-core/include/class_acl.inc
gosa-core/include/class_config.inc
gosa-core/include/class_filterLDAP.inc
gosa-core/include/class_ldap.inc
gosa-core/include/class_listing.inc
gosa-core/include/class_listingSortIterator.inc
gosa-core/include/class_plugin.inc
gosa-core/include/class_pluglist.inc
gosa-core/include/class_userinfo.inc
gosa-core/include/functions.inc
gosa-core/include/functions_helpviewer.inc
gosa-core/include/utils/class_tests.inc
gosa-core/include/utils/excel/class.writeexcel_formula.inc.php
gosa-core/include/utils/excel/class.writeexcel_worksheet.inc.php
gosa-core/plugins/admin/acl/class_aclRole.inc
gosa-core/plugins/admin/acl/class_filterACL.inc
gosa-core/plugins/personal/generic/class_user.inc
gosa-core/plugins/personal/posix/class_posixAccount.inc
gosa-core/setup/class_setupStep_Migrate.inc

index c0b6ec2f013bb212057be2ebf84f9ecf67b21c4f..53eadd09a4be0de1210364915380ec93556e5ef3 100644 (file)
@@ -41,7 +41,7 @@ if(!isset($_GET['mac'])){
 
 $config = session::global_get("config");
 $o =  new gosaSupportDaemon();
-$res = $o->get_entries_by_mac(split(",",$_GET['mac']));
+$res = $o->get_entries_by_mac(explode(",", $_GET['mac']));
 foreach($res as $entry){
        echo $entry['MACADDRESS']."|".$entry['PROGRESS']."\n";
 }
index 99710fad4ce7b2a145ec65fcb625160c95976323..4a4f39982a20872ccbd4f2bddd5585388e72939b 100644 (file)
@@ -151,7 +151,7 @@ if(session::global_is_set('current_class_for_help')){
 if(isset($_GET['pg'])){
  
   if(preg_match("/\//",$_GET['pg'])){
-    $arr = split("\/",$_GET['pg']);
+    $arr = explode("/", $_GET['pg']);
     $helpobject['currentplug'] = "../doc/core/".$helpobject['lang']."/html/".$arr[0];
     $helpdir = $helpobject['currentplug'];
     $helpobject['file']= $arr[1];
index 01165904c669b232eaf1b168b54a55c6dc7b5cb2..b74463f09c95b18cf4d461b81f67d2fab3d6b4a2 100644 (file)
@@ -330,7 +330,7 @@ class acl extends plugin
 
       /* ACL saving... */
       if (preg_match('/^acl_.*_[^xy]$/', $name)){
-        list($dummy, $object, $attribute, $value)= split('_', $name);
+        list($dummy, $object, $attribute, $value)= explode('_', $name);
 
         /* Skip for detection entry */
         if ($object == 'dummy') {
@@ -920,7 +920,7 @@ class acl extends plugin
   static function explodeACL($acl)
   {
 
-    $list= split(':', $acl);
+    $list= explode(':', $acl);
     if(count($list) == 5){
       list($index, $type,$member,$permission,$filter)= $list;
       $filter = base64_decode($filter);
@@ -972,7 +972,7 @@ class acl extends plugin
     if ($ms == $acl){
       return $a;
     }
-    $ma= split(',', $ms);
+    $ma= explode(',', $ms);
 
     /* Decode dn's, fill with informations from LDAP */
     $ldap= $config->get_ldap_link();
@@ -1006,14 +1006,14 @@ class acl extends plugin
   {
     /* Rip acl off the string, seperate by ',' and place it in an array */
     $as= preg_replace('/^[^:]+:[^:]+:[^:]*:([^:]*).*$/', '\1', $acl);
-    $aa= split(',', $as);
+    $aa= explode(',', $as);
     $a= array();
 
     /* Dis-assemble single ACLs */
     foreach($aa as $sacl){
       
       /* Dis-assemble field ACLs */
-      $ao= split('#', $sacl);
+      $ao= explode('#', $sacl);
       $gobject= "";
       foreach($ao as $idx => $ssacl){
 
@@ -1032,7 +1032,7 @@ class acl extends plugin
         } else {
 
           /* All other entries get appended... */
-          list($field, $facl)= split(';', $ssacl);
+          list($field, $facl)= explode(';', $ssacl);
           $a[$gobject][$field]= $facl;
         }
 
@@ -1291,8 +1291,8 @@ class acl extends plugin
 
       // Remove entry directly
       foreach($attrs['gosaAclEntry'] as $id => $entry){
-        $parts= split(':',$entry);                     
-        $members= split(',',$parts[2]);                
+        $parts= explode(':',$entry);                     
+        $members= explode(',',$parts[2]);                
         $new_members= array();                         
         foreach($members as $member) {                 
           if (base64_decode($member) != $dn) {         
index daad80f35cdb78633093374f283f65346964460e..106e4995a53766703f923e1711e06c1d52c303d8 100644 (file)
@@ -805,7 +805,7 @@ class config  {
       }
 
       /* Split dn into single department pieces */
-      $elements = array_reverse(split(',',preg_replace("/$qbase$/",'',$val)));                 
+      $elements = array_reverse(explode(',',preg_replace("/$qbase$/",'',$val)));               
 
       /* Add last ou element of current dn to our array */
       $last = &$arr;
@@ -903,7 +903,7 @@ class config  {
       }
       if(isset($entry['goExportEntry'])){
         foreach($entry['goExportEntry'] as $export){
-          $shareAttrs = split("\|",$export);
+          $shareAttrs = explode("|",$export);
           if($listboxEntry) {
             $return[$shareAttrs[0]."|".$entry['cn'][0]] = $shareAttrs[0]." - ".$entry['cn'][0];
           }else{
@@ -944,7 +944,7 @@ class config  {
           unset($entry['goExportEntry']['count']);
         }
         foreach($entry['goExportEntry'] as $share){
-          $a_share = split("\|",$share);
+          $a_share = explode("|",$share);
           $sharename = $a_share[0];
           $data= array();
           $data['NAME']   = $sharename;
index 7697462049580281c7976e3314516cdeafd5e74f..8375a3832a536fc37cc6b05d193c97fe944526d7 100644 (file)
@@ -35,7 +35,7 @@ class filterLDAP {
     } else {
       foreach ($objectStorage as $oc) {
         $oc= preg_replace('/,$/', '', $oc);
-        $tmp= split(',', $oc);
+        $tmp= explode(',', $oc);
         if (count($tmp) == 1) {
           preg_match('/([^=]+)=(.*)$/', $oc, $m);
           if ($flags & GL_SUBSEARCH) {
index 5322abebac63402d8f54001d1f9a75c598fc9277..17acd751de48a23cee5c39ccfc25359b2f49db2b 100644 (file)
@@ -969,9 +969,9 @@ class LDAP{
   {
     if($this->reconnect) $this->connect();
 
-    /* First we have to splitt the string ito detect empty lines
+    /* First we have to split the string into empty lines.
        An empty line indicates an new Entry */
-    $entries = split("\n",$str_attr);
+    $entries = preg_split("/\n/",$str_attr);
 
     $data = "";
     $cnt = 0; 
@@ -1014,7 +1014,7 @@ class LDAP{
           /* check if we need base64_decode for this line */
           if(ereg("::",$tmp2))
           {
-            $encoded = split("::",$entry);
+            $encoded = explode("::",$entry);
             $attr  = trim($encoded[0]);
             $value = base64_decode(trim($encoded[1]));
             /* Add linenumber */
@@ -1037,11 +1037,11 @@ class LDAP{
        
        Now we check every insertblock and try to insert */
     foreach ( $all as $single) {
-      $lineone = split("\n",$single);  
-      $ndn = split("#", $lineone[0]);
+      $lineone = preg_split("/\n/",$single);  
+      $ndn = explode("#", $lineone[0]);
       $line = base64_decode($ndn[1]);
 
-      $dnn = split (":",$line,2);
+      $dnn = explode (":",$line,2);
       $current_line = $ndn[0];
       $dn    = $dnn[0];
       $value = $dnn[1];
@@ -1103,7 +1103,7 @@ class LDAP{
     if($this->reconnect) $this->connect();
 
     $ret = false;
-    $rows= split("\n",$str_attr);
+    $rows= preg_split("/\n/",$str_attr);
     $data= false;
 
     foreach($rows as $row) {
@@ -1115,13 +1115,13 @@ class LDAP{
 
           /* We are using line numbers 
              Because there is a # before a : */
-          $tmp1= split("#",$row);
+          $tmp1= explode("#",$row);
           $current_line= $tmp1[0];
           $row= base64_decode($tmp1[1]);
         }
 
         /* Split the line into  attribute  and value */
-        $attr   = split(":", $row,2);
+        $attr   = explode(":", $row,2);
         $attr[0]= trim($attr[0]);  /* attribute */
         $attr[1]= $attr[1];  /* value */
 
@@ -1224,7 +1224,7 @@ class LDAP{
   
   function importcsv($str)
   {
-    $lines = split("\n",$str);
+    $lines = preg_split("/\n/",$str);
     foreach($lines as $line)
     {
       /* continue if theres a comment */
@@ -1236,9 +1236,9 @@ class LDAP{
       $line= str_replace ("\t"  ,"," ,$line);
       echo $line;
 
-      $cells = split(",",$line )  ;
+      $cells = explode(",",$line )  ;
       $linet= str_replace ("\t\t",",",$line);
-      $cells = split("\t",$line);
+      $cells = preg_split("/\t/",$line);
       $count = count($cells);  
     }
 
@@ -1282,7 +1282,7 @@ class LDAP{
         continue;
       }
       $name= "OID";
-      $pattern= split(' ', $val);
+      $pattern= explode(' ', $val);
       $ocname= preg_replace("/^.* NAME\s+\(*\s*'([^']+)'\s*\)*.*$/", '\\1', $val);
       $objectclasses[$ocname]= array();
 
@@ -1362,10 +1362,10 @@ class LDAP{
 
   /* added by Guido Serra aka Zeph <zeph@purotesto.it> */
   function getCn($dn){
-    $simple= split(",", $dn);
+    $simple= explode(",", $dn);
 
     foreach($simple as $piece) {
-      $partial= split("=", $piece);
+      $partial= explode("=", $piece);
 
       if($partial[0] == "cn"){
         return $partial[1];
index 9d09f550b34a611f3fb38156424bdf93356929d1..00a9e1090d7d3d1dc99d0477fa44bb59e48e7c98 100644 (file)
@@ -596,12 +596,12 @@ class listing {
     $result= array();
     $layout= preg_replace("/^\|/", "", $layout);
     $layout= preg_replace("/\|$/", "", $layout);
-    $cols= split("\|", $layout);
+    $cols= explode("|", $layout);
 
     foreach ($cols as $index => $config) {
       if ($config != "") {
         $res= "";
-        $components= split(';', $config);
+        $components= explode(';', $config);
         foreach ($components as $part) {
           if (preg_match("/^r$/", $part)) {
             $res.= "text-align:right;";
@@ -854,7 +854,7 @@ class listing {
 
       // Skip entry if the pseudo filter does not fit
       if (isset($action['filter']) && preg_match('/^[a-z0-9_]+!?=[a-z0-9_]+$/i', $action['filter'])) {
-        list($fa, $fv)= split('=', $action['filter']);
+        list($fa, $fv)= explode('=', $action['filter']);
         if (preg_match('/^(.*)!$/', $fa, $m)){
           $fa= $m[1];
           if (isset($this->entries[$row][$fa]) && $this->entries[$row][$fa][0] == $fv) {
@@ -1250,7 +1250,7 @@ class listing {
         // match "users/user[userPassword:rw(,...)*]" style entries
         if (preg_match('/^([a-zA-Z0-9]+\/[a-zA-Z0-9]+)\[([a-zA-Z0-9]+:[rwcdm]+(,[a-zA-Z0-9]+:[rwcdm]+)*)\]$/', $acl, $match)){
           $module= $match[1];
-          $aclList= split(',', $match[2]);
+          $aclList= explode(',', $match[2]);
         }
 
         // Walk thru prepared ACL by using $module
index af18544aa898fe213b04fee7442e292b6c1fdaaa..ed956b68d0e894bd52d1e6a7695003f7204dd1ad 100644 (file)
@@ -64,9 +64,9 @@ class listingSortIterator implements Iterator {
           if ($b == "") {
             $b= "31.12.0000";
           }
-          list($d, $m, $y)= split('\.', $a);
+          list($d, $m, $y)= explode('.', $a);
           $a= (int)sprintf("%04d%02d%02d", $y, $m, $d);
-          list($d, $m, $y)= split('\.', $b);
+          list($d, $m, $y)= explode('.', $b);
           $b= (int)sprintf("%04d%02d%02d", $y, $m, $d);
           return $b-$a;
 
index 0691c206073d220480c29269e45c8d395ee68038..952e8ec3870953e1bb50296ee5d21ac1d299400c 100644 (file)
@@ -1762,7 +1762,7 @@ class plugin
         $acls = array();
         $found = false;
         for($i = 0 ; $i <  $attrs['gosaAclEntry']['count'] ; $i ++ ){
-          $acl_parts = split(":",$attrs['gosaAclEntry'][$i]);
+          $acl_parts = explode(":",$attrs['gosaAclEntry'][$i]);
 
           /* Roles uses antoher data storage order, members are stored int the third part, 
              while the members in direct ACL assignments are stored in the second part.
index 528052a875c054e5d28e3f98bd51f356a48c0b1e..a4440087e4d2ca0987c6471442cb2e461f569f1f 100644 (file)
@@ -98,7 +98,7 @@ class pluglist {
          */
                $acls_to_check = array();
                if(preg_match("/,/",$aclname)){
-                       $acls_to_check = split(",",$aclname);
+                       $acls_to_check = explode(",",$aclname);
                }else{
                        $acls_to_check = array($aclname);
                }
@@ -271,7 +271,7 @@ class pluglist {
                        $cfg= $this->config->data['MENU'];
 
                        if (isset($this->config->current['ICONSIZE'])){
-                               list($x, $y)= split("x", $this->config->get_cfg_value("iconsize"));
+                               list($x, $y)= explode("x", $this->config->get_cfg_value("iconsize"));
                                $isize= "width=\"$x\" height=\"$y\"";
                        } else {
                                $isize= "";
index 06a9648d1782d875d72483966014d5fc683af4be..1d5cefee532f4bdd4f55b1cffee8623d8cd8442d 100644 (file)
@@ -392,7 +392,7 @@ class userinfo
     $acl= array("r" => "", "w" => "", "c" => "", "d" => "", "m" => "", "a" => "");
 
     /* Build dn array */
-    $path= split(',', $dn);
+    $path= explode(',', $dn);
     $path= array_reverse($path);
 
     /* Walk along the path to evaluate the acl */
index 621f74bc6b053c1b7b2cd74f67ab9707dc8cde50..a543c7cf6360bc2d166976ac08af65ef08776504 100644 (file)
@@ -569,7 +569,7 @@ function ldap_login_user ($username, $password)
   $allowed_attributes = array("uid","mail");
   $verify_attr = array();
   if($config->get_cfg_value("loginAttribute") != ""){
-    $tmp = split(",", $config->get_cfg_value("loginAttribute")); 
+    $tmp = explode(",", $config->get_cfg_value("loginAttribute")); 
     foreach($tmp as $attr){
       if(in_array($attr,$allowed_attributes)){
         $verify_attr[] = $attr;
@@ -1357,7 +1357,7 @@ function convert_department_dn($dn, $base = NULL)
 
 
   $dep= "";
-  foreach (split(',', $dn) as $rdn){
+  foreach (explode(',', $dn) as $rdn){
     $dep = preg_replace("/^[^=]+=/","",$rdn)."/".$dep;
   }
 
@@ -1978,7 +1978,7 @@ function normalize_netmask($netmask)
  */
 function netmask_to_bits($netmask)
 {
-  list($nm0, $nm1, $nm2, $nm3)= split('\.', $netmask);
+  list($nm0, $nm1, $nm2, $nm3)= explode('.', $netmask);
   $res= 0;
 
   for ($n= 0; $n<4; $n++){
@@ -3069,7 +3069,7 @@ function generate_smb_nt_hash($password)
     }
   }
 
-  list($lm,$nt)= split (":", trim($hash));
+  list($lm,$nt)= explode(":", trim($hash));
 
   $attrs['sambaLMPassword']= $lm;
   $attrs['sambaNTPassword']= $nt;
@@ -3470,9 +3470,9 @@ function get_next_id_traditional($attrib, $dn)
   /* get the ranges */
   $tmp = array('0'=> 1000);
   if (preg_match('/posixAccount/', $oc) && $config->get_cfg_value("uidNumberBase") != ""){
-    $tmp= split('-',$config->get_cfg_value("uidNumberBase"));
+    $tmp= explode('-',$config->get_cfg_value("uidNumberBase"));
   } elseif($config->get_cfg_value("gidNumberBase") != ""){
-    $tmp= split('-',$config->get_cfg_value("gidNumberBase"));
+    $tmp= explode('-',$config->get_cfg_value("gidNumberBase"));
   }
 
   /* Set hwm to max if not set - for backward compatibility */
index 13a528d7d7e7df9ef51f8f2ce2e201a49c1d7a48..8bb1dcdd6c4bf3cd4f9e2dee39090a98a3ceca6c 100644 (file)
@@ -284,7 +284,7 @@ function search($arr,$word)
 
   /* Filter all unusable chars */
   $word   = preg_replace($allowed_chars_in_searchword,"",$word);
-  $words  = split(" ",str_replace("+"," ",$word));
+  $words  = explode(" ",str_replace("+"," ",$word));
 
   /* Check all wordlengths */
   foreach($words as $tryword){
@@ -376,7 +376,7 @@ function searchlist($arr,$res,$maxresults)
   /* Foreach */  
   foreach($topten as $key => $hits)  {
 
-    $ks = split("\/",$key);
+    $ks = explode("/",$key);
     $k1 = $ks[0];
     $k2 = $ks[1];
     
@@ -494,7 +494,7 @@ function getheader_from_content($str)
 {
   $str = strip_tags($str);
   $pos = 0;
-  $arr = split("\n",$str);
+  $arr = preg_split("/\n/",$str);
   foreach($arr as $possibleheadline){
     if(strlen($possibleheadline)>=3){
       return $possibleheadline; 
index 68f94e6c4b975aad08510725cc0b8997b29e9087..b7f1c1f0fa8db297f1a46d31b24de3b0ba4c77e9 100644 (file)
@@ -217,10 +217,10 @@ class tests {
     if(!tests::is_ip($ip1) || !tests::is_ip($ip2)){
       return(FALSE);
     }else{
-      $ar1 = split("\.",$ip1);
+      $ar1 = explode(".",$ip1);
       $var1 = $ar1[0] * (16777216) + $ar1[1] * (65536) + $ar1[2] * (256) + $ar1[3];
 
-      $ar2 = split("\.",$ip2);
+      $ar2 = explode(".",$ip2);
       $var2 = $ar2[0] * (16777216) + $ar2[1] * (65536) + $ar2[2] * (256) + $ar2[3];
       return($var1 < $var2);
     }
@@ -230,9 +230,9 @@ class tests {
   /* Check if the specified IP address $address is inside the given network */
   public static function is_in_network($network, $netmask, $address)
   {
-    $nw= split('\.', $network);
-    $nm= split('\.', $netmask);
-    $ad= split('\.', $address);
+    $nw= explode('.', $network);
+    $nm= explode('.', $netmask);
+    $ad= explode('.', $address);
 
     /* Generate inverted netmask */
     for ($i= 0; $i<4; $i++){
@@ -268,9 +268,9 @@ class tests {
   /* Check if the specified IP address $address is inside the given network */
   public static function is_in_ip_range($from, $to, $address)
   {
-    $from = split('\.', $from);
-    $to   = split('\.', $to);
-    $ad   = split('\.', $address);
+    $from = explode('.', $from);
+    $to   = explode('.', $to);
+    $ad   = explode('.', $address);
 
     /* Transform to integer */
     $from= $from[0] * (16777216) + $from[1] * (65536) + $from[2] * (256) + $from[3];
index a0e37ffbe77ddec69550e6674659473c46f2d581..79a1129acf6b77cea97912a4f7d5943c3207c1c2 100644 (file)
  * Spreadsheet::WriteExcel was written by John McNamara, jmcnamara@cpan.org
  */
 
-define('SPREADSHEET_EXCEL_WRITER_ADD',"+");\r    // @const SPREADSHEET_EXCEL_WRITER_ADD token identifier for character "+"\r
-define('SPREADSHEET_EXCEL_WRITER_SUB',"-");\r    // @const SPREADSHEET_EXCEL_WRITER_SUB token identifier for character "-"\r
-define('SPREADSHEET_EXCEL_WRITER_MUL',"*");\r    // @const SPREADSHEET_EXCEL_WRITER_MUL token identifier for character "*"\r
-define('SPREADSHEET_EXCEL_WRITER_DIV',"/");\r    // @const SPREADSHEET_EXCEL_WRITER_DIV token identifier for character "/"\r
-define('SPREADSHEET_EXCEL_WRITER_OPEN',"(");\r   // @const SPREADSHEET_EXCEL_WRITER_OPEN token identifier for character "("\r
-define('SPREADSHEET_EXCEL_WRITER_CLOSE',")"); \r // @const SPREADSHEET_EXCEL_WRITER_CLOSE token identifier for character ")"\r
-define('SPREADSHEET_EXCEL_WRITER_COMA',",");\r   // @const SPREADSHEET_EXCEL_WRITER_COMA token identifier for character ","\r
-define('SPREADSHEET_EXCEL_WRITER_SCOLON',";"); \r// @const SPREADSHEET_EXCEL_WRITER_SCOLON token identifier for character ";"\r
-define('SPREADSHEET_EXCEL_WRITER_GT',">");\r     // @const SPREADSHEET_EXCEL_WRITER_GT token identifier for character ">"\r
-define('SPREADSHEET_EXCEL_WRITER_LT',"<");\r     // @const SPREADSHEET_EXCEL_WRITER_LT token identifier for character "<"\r
-define('SPREADSHEET_EXCEL_WRITER_LE',"<=");\r    // @const SPREADSHEET_EXCEL_WRITER_LE token identifier for character "<="\r
-define('SPREADSHEET_EXCEL_WRITER_GE',">=");\r    // @const SPREADSHEET_EXCEL_WRITER_GE token identifier for character ">="\r
-define('SPREADSHEET_EXCEL_WRITER_EQ',"=");\r     // @const SPREADSHEET_EXCEL_WRITER_EQ token identifier for character "="\r
-define('SPREADSHEET_EXCEL_WRITER_NE',"<>");\r    // @const SPREADSHEET_EXCEL_WRITER_NE token identifier for character "<>"\r
-\r
+define('SPREADSHEET_EXCEL_WRITER_ADD',"+");\r    // @const SPREADSHEET_EXCEL_WRITER_ADD token identifier for character "+"
+define('SPREADSHEET_EXCEL_WRITER_SUB',"-");\r    // @const SPREADSHEET_EXCEL_WRITER_SUB token identifier for character "-"
+define('SPREADSHEET_EXCEL_WRITER_MUL',"*");\r    // @const SPREADSHEET_EXCEL_WRITER_MUL token identifier for character "*"
+define('SPREADSHEET_EXCEL_WRITER_DIV',"/");\r    // @const SPREADSHEET_EXCEL_WRITER_DIV token identifier for character "/"
+define('SPREADSHEET_EXCEL_WRITER_OPEN',"(");\r   // @const SPREADSHEET_EXCEL_WRITER_OPEN token identifier for character "("
+define('SPREADSHEET_EXCEL_WRITER_CLOSE',")"); \r // @const SPREADSHEET_EXCEL_WRITER_CLOSE token identifier for character ")"
+define('SPREADSHEET_EXCEL_WRITER_COMA',",");\r   // @const SPREADSHEET_EXCEL_WRITER_COMA token identifier for character ","
+define('SPREADSHEET_EXCEL_WRITER_SCOLON',";"); \r// @const SPREADSHEET_EXCEL_WRITER_SCOLON token identifier for character ";"
+define('SPREADSHEET_EXCEL_WRITER_GT',">");\r     // @const SPREADSHEET_EXCEL_WRITER_GT token identifier for character ">"
+define('SPREADSHEET_EXCEL_WRITER_LT',"<");\r     // @const SPREADSHEET_EXCEL_WRITER_LT token identifier for character "<"
+define('SPREADSHEET_EXCEL_WRITER_LE',"<=");\r    // @const SPREADSHEET_EXCEL_WRITER_LE token identifier for character "<="
+define('SPREADSHEET_EXCEL_WRITER_GE',">=");\r    // @const SPREADSHEET_EXCEL_WRITER_GE token identifier for character ">="
+define('SPREADSHEET_EXCEL_WRITER_EQ',"=");\r     // @const SPREADSHEET_EXCEL_WRITER_EQ token identifier for character "="
+define('SPREADSHEET_EXCEL_WRITER_NE',"<>");\r    // @const SPREADSHEET_EXCEL_WRITER_NE token identifier for character "<>"
+
 
 class writeexcel_formula {
 
@@ -158,1256 +158,1256 @@ function isError($data) {
                   (get_class($data) == 'pear_error' ||
                   is_subclass_of($data, 'pear_error')));
 }
-\r
-/**\r
-* Class for parsing Excel formulas\r
-*\r
-* @author   Xavier Noguer <xnoguer@rezebra.com>\r
-* @category FileFormats\r
-* @package  Spreadsheet_Excel_Writer\r
-*/\r
-\r
-    \r
-/**\r
-* Initialize the ptg and function hashes. \r
-*\r
-* @access private\r
-*/\r
-function _initializeHashes()\r {\r
-    // The Excel ptg indices\r
-    $this->ptg = array(\r
-        'ptgExp'       => 0x01,\r        'ptgTbl'       => 0x02,\r        'ptgAdd'       => 0x03,\r        'ptgSub'       => 0x04,\r
-        'ptgMul'       => 0x05,\r        'ptgDiv'       => 0x06,\r        'ptgPower'     => 0x07,        'ptgConcat'    => 0x08,\r
-        'ptgLT'        => 0x09,\r        'ptgLE'        => 0x0A,\r        'ptgEQ'        => 0x0B,\r        'ptgGE'        => 0x0C,\r
-        'ptgGT'        => 0x0D,\r        'ptgNE'        => 0x0E,\r        'ptgIsect'     => 0x0F,\r        'ptgUnion'     => 0x10,\r
-        'ptgRange'     => 0x11,\r        'ptgUplus'     => 0x12,\r        'ptgUminus'    => 0x13,\r        'ptgPercent'   => 0x14,\r
-        'ptgParen'     => 0x15,\r        'ptgMissArg'   => 0x16,\r        'ptgStr'       => 0x17,\r        'ptgAttr'      => 0x19,\r
-        'ptgSheet'     => 0x1A,\r        'ptgEndSheet'  => 0x1B,\r        'ptgErr'       => 0x1C,\r        'ptgBool'      => 0x1D,\r
-        'ptgInt'       => 0x1E,\r        'ptgNum'       => 0x1F,\r        'ptgArray'     => 0x20,\r        'ptgFunc'      => 0x21,\r
-        'ptgFuncVar'   => 0x22,\r        'ptgName'      => 0x23,\r        'ptgRef'       => 0x24,\r        'ptgArea'      => 0x25,\r
-        'ptgMemArea'   => 0x26,\r        'ptgMemErr'    => 0x27,\r        'ptgMemNoMem'  => 0x28,\r        'ptgMemFunc'   => 0x29,\r
-       'ptgRefErr'    => 0x2A,\r        'ptgAreaErr'   => 0x2B,\r        'ptgRefN'      => 0x2C,\r        'ptgAreaN'     => 0x2D,\r
+
+/**
+* Class for parsing Excel formulas
+*
+* @author   Xavier Noguer <xnoguer@rezebra.com>
+* @category FileFormats
+* @package  Spreadsheet_Excel_Writer
+*/
+
+    
+/**
+* Initialize the ptg and function hashes. 
+*
+* @access private
+*/
+function _initializeHashes()\r {
+    // The Excel ptg indices
+    $this->ptg = array(
+        'ptgExp'       => 0x01,\r        'ptgTbl'       => 0x02,\r        'ptgAdd'       => 0x03,\r        'ptgSub'       => 0x04,
+        'ptgMul'       => 0x05,\r        'ptgDiv'       => 0x06,\r        'ptgPower'     => 0x07,        'ptgConcat'    => 0x08,
+        'ptgLT'        => 0x09,\r        'ptgLE'        => 0x0A,\r        'ptgEQ'        => 0x0B,\r        'ptgGE'        => 0x0C,
+        'ptgGT'        => 0x0D,\r        'ptgNE'        => 0x0E,\r        'ptgIsect'     => 0x0F,\r        'ptgUnion'     => 0x10,
+        'ptgRange'     => 0x11,\r        'ptgUplus'     => 0x12,\r        'ptgUminus'    => 0x13,\r        'ptgPercent'   => 0x14,
+        'ptgParen'     => 0x15,\r        'ptgMissArg'   => 0x16,\r        'ptgStr'       => 0x17,\r        'ptgAttr'      => 0x19,
+        'ptgSheet'     => 0x1A,\r        'ptgEndSheet'  => 0x1B,\r        'ptgErr'       => 0x1C,\r        'ptgBool'      => 0x1D,
+        'ptgInt'       => 0x1E,\r        'ptgNum'       => 0x1F,\r        'ptgArray'     => 0x20,\r        'ptgFunc'      => 0x21,
+        'ptgFuncVar'   => 0x22,\r        'ptgName'      => 0x23,\r        'ptgRef'       => 0x24,\r        'ptgArea'      => 0x25,
+        'ptgMemArea'   => 0x26,\r        'ptgMemErr'    => 0x27,\r        'ptgMemNoMem'  => 0x28,\r        'ptgMemFunc'   => 0x29,
+       'ptgRefErr'    => 0x2A,\r        'ptgAreaErr'   => 0x2B,\r        'ptgRefN'      => 0x2C,\r        'ptgAreaN'     => 0x2D,
         'ptgMemAreaN'  => 0x2E,\r        'ptgMemNoMemN' => 0x2F,\r        'ptgNameX'     => 0x39,\r        'ptgRef3d'     => 0x3A,
-\r        'ptgArea3d'    => 0x3B,\r        'ptgRefErr3d'  => 0x3C,\r        'ptgAreaErr3d' => 0x3D,\r        'ptgArrayV'    => 0x40,\r
-        'ptgFuncV'     => 0x41,\r        'ptgFuncVarV'  => 0x42,\r        'ptgNameV'     => 0x43,\r        'ptgRefV'      => 0x44,\r
-        'ptgAreaV'     => 0x45,\r        'ptgMemAreaV'  => 0x46,\r        'ptgMemErrV'   => 0x47,\r        'ptgMemNoMemV' => 0x48,\r
-        'ptgMemFuncV'  => 0x49,\r        'ptgRefErrV'   => 0x4A,\r        'ptgAreaErrV'  => 0x4B,\r        'ptgRefNV'     => 0x4C,\r
-        'ptgAreaNV'    => 0x4D,\r        'ptgMemAreaNV' => 0x4E,\r        'ptgMemNoMemN' => 0x4F,\r        'ptgFuncCEV'   => 0x58,\r
-        'ptgNameXV'    => 0x59,\r        'ptgRef3dV'    => 0x5A,\r        'ptgArea3dV'   => 0x5B,        'ptgRefErr3dV' => 0x5C,\r
-        'ptgAreaErr3d' => 0x5D,\r        'ptgArrayA'    => 0x60,\r        'ptgFuncA'     => 0x61,\r        'ptgFuncVarA'  => 0x62,\r
-        'ptgNameA'     => 0x63,        'ptgRefA'      => 0x64,\r              'ptgAreaA'     => 0x65,\r        'ptgMemAreaA'  => 0x66,\r
-        'ptgMemErrA'   => 0x67,\r        'ptgMemNoMemA' => 0x68,\r        'ptgMemFuncA'  => 0x69,\r        'ptgRefErrA'   => 0x6A,\r
-        'ptgAreaErrA'  => 0x6B,\r        'ptgRefNA'     => 0x6C,\r        'ptgAreaNA'    => 0x6D,\r        'ptgMemAreaNA' => 0x6E,\r
-        'ptgMemNoMemN' => 0x6F,\r        'ptgFuncCEA'   => 0x78,\r        'ptgNameXA'    => 0x79,\r        'ptgRef3dA'    => 0x7A,\r
-        'ptgArea3dA'   => 0x7B,\r        'ptgRefErr3dA' => 0x7C,\r        'ptgAreaErr3d' => 0x7D\r
-        );\r
-    \r
-    // Thanks to Michael Meeks and Gnumeric for the initial arg values.\r
-    //\r
-    // The following hash was generated by "function_locale.pl" in the distro.\r
-    // Refer to function_locale.pl for non-English function names.\r
-    //\r
-    // The array elements are as follow:\r
-    // ptg:   The Excel function ptg code.\r
-    // args:  The number of arguments that the function takes:\r
-    //           >=0 is a fixed number of arguments.\r
-    //           -1  is a variable  number of arguments.\r
-    // class: The reference, value or array class of the function args.\r
-    // vol:   The function is volatile.\r
-    //\r
-    $this->_functions = array(\r
-       // function                  ptg  args  class  vol\r
-       'COUNT'           => array(   0,   -1,    0,    0 ),\r
-        'IF'              => array(   1,   -1,    1,    0 ),\r
-        'ISNA'            => array(   2,    1,    1,    0 ),\r
-        'ISERROR'         => array(   3,    1,    1,    0 ),\r
-        'SUM'             => array(   4,   -1,    0,    0 ),\r
-        'AVERAGE'         => array(   5,   -1,    0,    0 ),\r
-        'MIN'             => array(   6,   -1,    0,    0 ),\r
-        'MAX'             => array(   7,   -1,    0,    0 ),\r
-        'ROW'             => array(   8,   -1,    0,    0 ),\r
-        'COLUMN'          => array(   9,   -1,    0,    0 ),\r
-        'NA'              => array(  10,    0,    0,    0 ),\r
-        'NPV'             => array(  11,   -1,    1,    0 ),\r
-        'STDEV'           => array(  12,   -1,    0,    0 ),\r
-        'DOLLAR'          => array(  13,   -1,    1,    0 ),\r
-        'FIXED'           => array(  14,   -1,    1,    0 ),\r
-        'SIN'             => array(  15,    1,    1,    0 ),\r
-        'COS'             => array(  16,    1,    1,    0 ),\r
-        'TAN'             => array(  17,    1,    1,    0 ),\r
-        'ATAN'            => array(  18,    1,    1,    0 ),\r
-        'PI'              => array(  19,    0,    1,    0 ),\r
-        'SQRT'            => array(  20,    1,    1,    0 ),\r
-        'EXP'             => array(  21,    1,    1,    0 ),\r
-        'LN'              => array(  22,    1,    1,    0 ),\r
-        'LOG10'           => array(  23,    1,    1,    0 ),\r
-        'ABS'             => array(  24,    1,    1,    0 ),\r
-        'INT'             => array(  25,    1,    1,    0 ),\r
-        'SIGN'            => array(  26,    1,    1,    0 ),\r
-        'ROUND'           => array(  27,    2,    1,    0 ),\r
-        'LOOKUP'          => array(  28,   -1,    0,    0 ),\r
-        'INDEX'           => array(  29,   -1,    0,    1 ),\r
-        'REPT'            => array(  30,    2,    1,    0 ),\r
-        'MID'             => array(  31,    3,    1,    0 ),\r
-        'LEN'             => array(  32,    1,    1,    0 ),\r
-        'VALUE'           => array(  33,    1,    1,    0 ),\r
-        'TRUE'            => array(  34,    0,    1,    0 ),\r
-        'FALSE'           => array(  35,    0,    1,    0 ),\r
-        'AND'             => array(  36,   -1,    0,    0 ),\r
-        'OR'              => array(  37,   -1,    0,    0 ),\r
-        'NOT'             => array(  38,    1,    1,    0 ),\r
-        'MOD'             => array(  39,    2,    1,    0 ),\r
-        'DCOUNT'          => array(  40,    3,    0,    0 ),\r
-        'DSUM'            => array(  41,    3,    0,    0 ),\r
-        'DAVERAGE'        => array(  42,    3,    0,    0 ),\r
-        'DMIN'            => array(  43,    3,    0,    0 ),\r
-        'DMAX'            => array(  44,    3,    0,    0 ),\r
-        'DSTDEV'          => array(  45,    3,    0,    0 ),\r
-        'VAR'             => array(  46,   -1,    0,    0 ),\r
-        'DVAR'            => array(  47,    3,    0,    0 ),\r
-        'TEXT'            => array(  48,    2,    1,    0 ),\r
-        'LINEST'          => array(  49,   -1,    0,    0 ),\r
-        'TREND'           => array(  50,   -1,    0,    0 ),\r
-        'LOGEST'          => array(  51,   -1,    0,    0 ),\r
-        'GROWTH'          => array(  52,   -1,    0,    0 ),\r
-        'PV'              => array(  56,   -1,    1,    0 ),\r
-        'FV'              => array(  57,   -1,    1,    0 ),\r
-        'NPER'            => array(  58,   -1,    1,    0 ),\r
-        'PMT'             => array(  59,   -1,    1,    0 ),\r
-        'RATE'            => array(  60,   -1,    1,    0 ),\r
-        'MIRR'            => array(  61,    3,    0,    0 ),\r
-        'IRR'             => array(  62,   -1,    0,    0 ),\r
-        'RAND'            => array(  63,    0,    1,    1 ),\r
-        'MATCH'           => array(  64,   -1,    0,    0 ),\r
-        'DATE'            => array(  65,    3,    1,    0 ),\r
-        'TIME'            => array(  66,    3,    1,    0 ),\r
-        'DAY'             => array(  67,    1,    1,    0 ),\r
-        'MONTH'           => array(  68,    1,    1,    0 ),\r
-        'YEAR'            => array(  69,    1,    1,    0 ),\r
-        'WEEKDAY'         => array(  70,   -1,    1,    0 ),\r
-        'HOUR'            => array(  71,    1,    1,    0 ),\r
-        'MINUTE'          => array(  72,    1,    1,    0 ),\r
-        'SECOND'          => array(  73,    1,    1,    0 ),\r
-        'NOW'             => array(  74,    0,    1,    1 ),\r
-        'AREAS'           => array(  75,    1,    0,    1 ),\r
-        'ROWS'            => array(  76,    1,    0,    1 ),\r
-        'COLUMNS'         => array(  77,    1,    0,    1 ),\r
-        'OFFSET'          => array(  78,   -1,    0,    1 ),\r
-        'SEARCH'          => array(  82,   -1,    1,    0 ),\r
-        'TRANSPOSE'       => array(  83,    1,    1,    0 ),\r
-        'TYPE'            => array(  86,    1,    1,    0 ),\r
-        'ATAN2'           => array(  97,    2,    1,    0 ),\r
-        'ASIN'            => array(  98,    1,    1,    0 ),\r
-        'ACOS'            => array(  99,    1,    1,    0 ),\r
-        'CHOOSE'          => array( 100,   -1,    1,    0 ),\r
-        'HLOOKUP'         => array( 101,   -1,    0,    0 ),\r
-        'VLOOKUP'         => array( 102,   -1,    0,    0 ),\r
-        'ISREF'           => array( 105,    1,    0,    0 ),\r
-        'LOG'             => array( 109,   -1,    1,    0 ),\r
-        'CHAR'            => array( 111,    1,    1,    0 ),\r
-        'LOWER'           => array( 112,    1,    1,    0 ),\r
-        'UPPER'           => array( 113,    1,    1,    0 ),\r
-        'PROPER'          => array( 114,    1,    1,    0 ),\r
-        'LEFT'            => array( 115,   -1,    1,    0 ),\r
-        'RIGHT'           => array( 116,   -1,    1,    0 ),\r
-        'EXACT'           => array( 117,    2,    1,    0 ),\r
-        'TRIM'            => array( 118,    1,    1,    0 ),\r
-        'REPLACE'         => array( 119,    4,    1,    0 ),\r
-        'SUBSTITUTE'      => array( 120,   -1,    1,    0 ),\r
-        'CODE'            => array( 121,    1,    1,    0 ),\r
-        'FIND'            => array( 124,   -1,    1,    0 ),\r
-        'CELL'            => array( 125,   -1,    0,    1 ),\r
-        'ISERR'           => array( 126,    1,    1,    0 ),\r
-        'ISTEXT'          => array( 127,    1,    1,    0 ),\r
-        'ISNUMBER'        => array( 128,    1,    1,    0 ),\r
-        'ISBLANK'         => array( 129,    1,    1,    0 ),\r
-        'T'               => array( 130,    1,    0,    0 ),\r
-        'N'               => array( 131,    1,    0,    0 ),\r
-        'DATEVALUE'       => array( 140,    1,    1,    0 ),\r
-        'TIMEVALUE'       => array( 141,    1,    1,    0 ),\r
-        'SLN'             => array( 142,    3,    1,    0 ),\r
-        'SYD'             => array( 143,    4,    1,    0 ),\r
-        'DDB'             => array( 144,   -1,    1,    0 ),\r
-        'INDIRECT'        => array( 148,   -1,    1,    1 ),\r
-        'CALL'            => array( 150,   -1,    1,    0 ),\r
-        'CLEAN'           => array( 162,    1,    1,    0 ),\r
-        'MDETERM'         => array( 163,    1,    2,    0 ),\r
-        'MINVERSE'        => array( 164,    1,    2,    0 ),\r
-        'MMULT'           => array( 165,    2,    2,    0 ),\r
-        'IPMT'            => array( 167,   -1,    1,    0 ),\r
-        'PPMT'            => array( 168,   -1,    1,    0 ),\r
-        'COUNTA'          => array( 169,   -1,    0,    0 ),\r
-        'PRODUCT'         => array( 183,   -1,    0,    0 ),\r
-        'FACT'            => array( 184,    1,    1,    0 ),\r
-        'DPRODUCT'        => array( 189,    3,    0,    0 ),\r
-        'ISNONTEXT'       => array( 190,    1,    1,    0 ),\r
-        'STDEVP'          => array( 193,   -1,    0,    0 ),\r
-        'VARP'            => array( 194,   -1,    0,    0 ),\r
-        'DSTDEVP'         => array( 195,    3,    0,    0 ),\r
-        'DVARP'           => array( 196,    3,    0,    0 ),\r
-        'TRUNC'           => array( 197,   -1,    1,    0 ),\r
-        'ISLOGICAL'       => array( 198,    1,    1,    0 ),\r
-        'DCOUNTA'         => array( 199,    3,    0,    0 ),\r
-        'ROUNDUP'         => array( 212,    2,    1,    0 ),\r
-        'ROUNDDOWN'       => array( 213,    2,    1,    0 ),\r
-        'RANK'            => array( 216,   -1,    0,    0 ),\r
-        'ADDRESS'         => array( 219,   -1,    1,    0 ),\r
-        'DAYS360'         => array( 220,   -1,    1,    0 ),\r
-        'TODAY'           => array( 221,    0,    1,    1 ),\r
-        'VDB'             => array( 222,   -1,    1,    0 ),\r
-        'MEDIAN'          => array( 227,   -1,    0,    0 ),\r
-        'SUMPRODUCT'      => array( 228,   -1,    2,    0 ),\r
-        'SINH'            => array( 229,    1,    1,    0 ),\r
-        'COSH'            => array( 230,    1,    1,    0 ),\r
-        'TANH'            => array( 231,    1,    1,    0 ),\r
-        'ASINH'           => array( 232,    1,    1,    0 ),\r
-        'ACOSH'           => array( 233,    1,    1,    0 ),\r
-        'ATANH'           => array( 234,    1,    1,    0 ),\r
-        'DGET'            => array( 235,    3,    0,    0 ),\r
-        'INFO'            => array( 244,    1,    1,    1 ),\r
-        'DB'              => array( 247,   -1,    1,    0 ),\r
-        'FREQUENCY'       => array( 252,    2,    0,    0 ),\r
-        'ERROR.TYPE'      => array( 261,    1,    1,    0 ),\r
-        'REGISTER.ID'     => array( 267,   -1,    1,    0 ),\r
-        'AVEDEV'          => array( 269,   -1,    0,    0 ),\r
-        'BETADIST'        => array( 270,   -1,    1,    0 ),\r
-        'GAMMALN'         => array( 271,    1,    1,    0 ),\r
-        'BETAINV'         => array( 272,   -1,    1,    0 ),\r
-        'BINOMDIST'       => array( 273,    4,    1,    0 ),\r
-        'CHIDIST'         => array( 274,    2,    1,    0 ),\r
-        'CHIINV'          => array( 275,    2,    1,    0 ),\r
-        'COMBIN'          => array( 276,    2,    1,    0 ),\r
-        'CONFIDENCE'      => array( 277,    3,    1,    0 ),\r
-        'CRITBINOM'       => array( 278,    3,    1,    0 ),\r
-        'EVEN'            => array( 279,    1,    1,    0 ),\r
-        'EXPONDIST'       => array( 280,    3,    1,    0 ),\r
-        'FDIST'           => array( 281,    3,    1,    0 ),\r
-        'FINV'            => array( 282,    3,    1,    0 ),\r
-        'FISHER'          => array( 283,    1,    1,    0 ),\r
-        'FISHERINV'       => array( 284,    1,    1,    0 ),\r
-        'FLOOR'           => array( 285,    2,    1,    0 ),\r
-        'GAMMADIST'       => array( 286,    4,    1,    0 ),\r
-        'GAMMAINV'        => array( 287,    3,    1,    0 ),\r
-        'CEILING'         => array( 288,    2,    1,    0 ),\r
-        'HYPGEOMDIST'     => array( 289,    4,    1,    0 ),\r
-        'LOGNORMDIST'     => array( 290,    3,    1,    0 ),\r
-        'LOGINV'          => array( 291,    3,    1,    0 ),\r
-        'NEGBINOMDIST'    => array( 292,    3,    1,    0 ),\r
-        'NORMDIST'        => array( 293,    4,    1,    0 ),\r
-        'NORMSDIST'       => array( 294,    1,    1,    0 ),\r
-        'NORMINV'         => array( 295,    3,    1,    0 ),\r
-        'NORMSINV'        => array( 296,    1,    1,    0 ),\r
-        'STANDARDIZE'     => array( 297,    3,    1,    0 ),\r
-        'ODD'             => array( 298,    1,    1,    0 ),\r
-        'PERMUT'          => array( 299,    2,    1,    0 ),\r
-        'POISSON'         => array( 300,    3,    1,    0 ),\r
-        'TDIST'           => array( 301,    3,    1,    0 ),\r
-        'WEIBULL'         => array( 302,    4,    1,    0 ),\r
-        'SUMXMY2'         => array( 303,    2,    2,    0 ),\r
-        'SUMX2MY2'        => array( 304,    2,    2,    0 ),\r
-        'SUMX2PY2'        => array( 305,    2,    2,    0 ),\r
-        'CHITEST'         => array( 306,    2,    2,    0 ),\r
-        'CORREL'          => array( 307,    2,    2,    0 ),\r
-        'COVAR'           => array( 308,    2,    2,    0 ),\r
-        'FORECAST'        => array( 309,    3,    2,    0 ),\r
-        'FTEST'           => array( 310,    2,    2,    0 ),\r
-        'INTERCEPT'       => array( 311,    2,    2,    0 ),\r
-        'PEARSON'         => array( 312,    2,    2,    0 ),\r
-        'RSQ'             => array( 313,    2,    2,    0 ),\r
-        'STEYX'           => array( 314,    2,    2,    0 ),\r
-        'SLOPE'           => array( 315,    2,    2,    0 ),\r
-        'TTEST'           => array( 316,    4,    2,    0 ),\r
-        'PROB'            => array( 317,   -1,    2,    0 ),\r
-        'DEVSQ'           => array( 318,   -1,    0,    0 ),\r
-        'GEOMEAN'         => array( 319,   -1,    0,    0 ),\r
-        'HARMEAN'         => array( 320,   -1,    0,    0 ),\r
-        'SUMSQ'           => array( 321,   -1,    0,    0 ),\r
-        'KURT'            => array( 322,   -1,    0,    0 ),\r
-        'SKEW'            => array( 323,   -1,    0,    0 ),\r
-        'ZTEST'           => array( 324,   -1,    0,    0 ),\r
-        'LARGE'           => array( 325,    2,    0,    0 ),\r
-        'SMALL'           => array( 326,    2,    0,    0 ),\r
-        'QUARTILE'        => array( 327,    2,    0,    0 ),\r
-        'PERCENTILE'      => array( 328,    2,    0,    0 ),\r
-        'PERCENTRANK'     => array( 329,   -1,    0,    0 ),\r
-        'MODE'            => array( 330,   -1,    2,    0 ),\r
-        'TRIMMEAN'        => array( 331,    2,    0,    0 ),\r
-        'TINV'            => array( 332,    2,    1,    0 ),\r
-        'CONCATENATE'     => array( 336,   -1,    1,    0 ),\r
-        'POWER'           => array( 337,    2,    1,    0 ),\r
-        'RADIANS'         => array( 342,    1,    1,    0 ),\r
-        'DEGREES'         => array( 343,    1,    1,    0 ),\r
-        'SUBTOTAL'        => array( 344,   -1,    0,    0 ),\r
-        'SUMIF'           => array( 345,   -1,    0,    0 ),\r
-        'COUNTIF'         => array( 346,    2,    0,    0 ),\r
-        'COUNTBLANK'      => array( 347,    1,    0,    0 ),\r
-        'ROMAN'           => array( 354,   -1,    1,    0 )\r
-        );\r
-}\r
-    \r
-/**\r
-* Convert a token to the proper ptg value.\r
-*\r
-* @access private\r
-* @param mixed $token The token to convert.\r
-* @return mixed the converted token on success. PEAR_Error if the token\r
-*               is not recognized\r
-*/\r
-function _convert($token)\r {\r
-    if (preg_match("/^\"[^\"]{0,255}\"$/", $token))\r {\r
-        return $this->_convertString($token);\r
-    }\r elseif (is_numeric($token))\r {\r
-        return $this->_convertNumber($token);\r
-    }\r
+\r        'ptgArea3d'    => 0x3B,\r        'ptgRefErr3d'  => 0x3C,\r        'ptgAreaErr3d' => 0x3D,\r        'ptgArrayV'    => 0x40,
+        'ptgFuncV'     => 0x41,\r        'ptgFuncVarV'  => 0x42,\r        'ptgNameV'     => 0x43,\r        'ptgRefV'      => 0x44,
+        'ptgAreaV'     => 0x45,\r        'ptgMemAreaV'  => 0x46,\r        'ptgMemErrV'   => 0x47,\r        'ptgMemNoMemV' => 0x48,
+        'ptgMemFuncV'  => 0x49,\r        'ptgRefErrV'   => 0x4A,\r        'ptgAreaErrV'  => 0x4B,\r        'ptgRefNV'     => 0x4C,
+        'ptgAreaNV'    => 0x4D,\r        'ptgMemAreaNV' => 0x4E,\r        'ptgMemNoMemN' => 0x4F,\r        'ptgFuncCEV'   => 0x58,
+        'ptgNameXV'    => 0x59,\r        'ptgRef3dV'    => 0x5A,\r        'ptgArea3dV'   => 0x5B,        'ptgRefErr3dV' => 0x5C,
+        'ptgAreaErr3d' => 0x5D,\r        'ptgArrayA'    => 0x60,\r        'ptgFuncA'     => 0x61,\r        'ptgFuncVarA'  => 0x62,
+        'ptgNameA'     => 0x63,        'ptgRefA'      => 0x64,\r              'ptgAreaA'     => 0x65,\r        'ptgMemAreaA'  => 0x66,
+        'ptgMemErrA'   => 0x67,\r        'ptgMemNoMemA' => 0x68,\r        'ptgMemFuncA'  => 0x69,\r        'ptgRefErrA'   => 0x6A,
+        'ptgAreaErrA'  => 0x6B,\r        'ptgRefNA'     => 0x6C,\r        'ptgAreaNA'    => 0x6D,\r        'ptgMemAreaNA' => 0x6E,
+        'ptgMemNoMemN' => 0x6F,\r        'ptgFuncCEA'   => 0x78,\r        'ptgNameXA'    => 0x79,\r        'ptgRef3dA'    => 0x7A,
+        'ptgArea3dA'   => 0x7B,\r        'ptgRefErr3dA' => 0x7C,\r        'ptgAreaErr3d' => 0x7D
+        );
+    
+    // Thanks to Michael Meeks and Gnumeric for the initial arg values.
+    //
+    // The following hash was generated by "function_locale.pl" in the distro.
+    // Refer to function_locale.pl for non-English function names.
+    //
+    // The array elements are as follow:
+    // ptg:   The Excel function ptg code.
+    // args:  The number of arguments that the function takes:
+    //           >=0 is a fixed number of arguments.
+    //           -1  is a variable  number of arguments.
+    // class: The reference, value or array class of the function args.
+    // vol:   The function is volatile.
+    //
+    $this->_functions = array(
+       // function                  ptg  args  class  vol
+       'COUNT'           => array(   0,   -1,    0,    0 ),
+        'IF'              => array(   1,   -1,    1,    0 ),
+        'ISNA'            => array(   2,    1,    1,    0 ),
+        'ISERROR'         => array(   3,    1,    1,    0 ),
+        'SUM'             => array(   4,   -1,    0,    0 ),
+        'AVERAGE'         => array(   5,   -1,    0,    0 ),
+        'MIN'             => array(   6,   -1,    0,    0 ),
+        'MAX'             => array(   7,   -1,    0,    0 ),
+        'ROW'             => array(   8,   -1,    0,    0 ),
+        'COLUMN'          => array(   9,   -1,    0,    0 ),
+        'NA'              => array(  10,    0,    0,    0 ),
+        'NPV'             => array(  11,   -1,    1,    0 ),
+        'STDEV'           => array(  12,   -1,    0,    0 ),
+        'DOLLAR'          => array(  13,   -1,    1,    0 ),
+        'FIXED'           => array(  14,   -1,    1,    0 ),
+        'SIN'             => array(  15,    1,    1,    0 ),
+        'COS'             => array(  16,    1,    1,    0 ),
+        'TAN'             => array(  17,    1,    1,    0 ),
+        'ATAN'            => array(  18,    1,    1,    0 ),
+        'PI'              => array(  19,    0,    1,    0 ),
+        'SQRT'            => array(  20,    1,    1,    0 ),
+        'EXP'             => array(  21,    1,    1,    0 ),
+        'LN'              => array(  22,    1,    1,    0 ),
+        'LOG10'           => array(  23,    1,    1,    0 ),
+        'ABS'             => array(  24,    1,    1,    0 ),
+        'INT'             => array(  25,    1,    1,    0 ),
+        'SIGN'            => array(  26,    1,    1,    0 ),
+        'ROUND'           => array(  27,    2,    1,    0 ),
+        'LOOKUP'          => array(  28,   -1,    0,    0 ),
+        'INDEX'           => array(  29,   -1,    0,    1 ),
+        'REPT'            => array(  30,    2,    1,    0 ),
+        'MID'             => array(  31,    3,    1,    0 ),
+        'LEN'             => array(  32,    1,    1,    0 ),
+        'VALUE'           => array(  33,    1,    1,    0 ),
+        'TRUE'            => array(  34,    0,    1,    0 ),
+        'FALSE'           => array(  35,    0,    1,    0 ),
+        'AND'             => array(  36,   -1,    0,    0 ),
+        'OR'              => array(  37,   -1,    0,    0 ),
+        'NOT'             => array(  38,    1,    1,    0 ),
+        'MOD'             => array(  39,    2,    1,    0 ),
+        'DCOUNT'          => array(  40,    3,    0,    0 ),
+        'DSUM'            => array(  41,    3,    0,    0 ),
+        'DAVERAGE'        => array(  42,    3,    0,    0 ),
+        'DMIN'            => array(  43,    3,    0,    0 ),
+        'DMAX'            => array(  44,    3,    0,    0 ),
+        'DSTDEV'          => array(  45,    3,    0,    0 ),
+        'VAR'             => array(  46,   -1,    0,    0 ),
+        'DVAR'            => array(  47,    3,    0,    0 ),
+        'TEXT'            => array(  48,    2,    1,    0 ),
+        'LINEST'          => array(  49,   -1,    0,    0 ),
+        'TREND'           => array(  50,   -1,    0,    0 ),
+        'LOGEST'          => array(  51,   -1,    0,    0 ),
+        'GROWTH'          => array(  52,   -1,    0,    0 ),
+        'PV'              => array(  56,   -1,    1,    0 ),
+        'FV'              => array(  57,   -1,    1,    0 ),
+        'NPER'            => array(  58,   -1,    1,    0 ),
+        'PMT'             => array(  59,   -1,    1,    0 ),
+        'RATE'            => array(  60,   -1,    1,    0 ),
+        'MIRR'            => array(  61,    3,    0,    0 ),
+        'IRR'             => array(  62,   -1,    0,    0 ),
+        'RAND'            => array(  63,    0,    1,    1 ),
+        'MATCH'           => array(  64,   -1,    0,    0 ),
+        'DATE'            => array(  65,    3,    1,    0 ),
+        'TIME'            => array(  66,    3,    1,    0 ),
+        'DAY'             => array(  67,    1,    1,    0 ),
+        'MONTH'           => array(  68,    1,    1,    0 ),
+        'YEAR'            => array(  69,    1,    1,    0 ),
+        'WEEKDAY'         => array(  70,   -1,    1,    0 ),
+        'HOUR'            => array(  71,    1,    1,    0 ),
+        'MINUTE'          => array(  72,    1,    1,    0 ),
+        'SECOND'          => array(  73,    1,    1,    0 ),
+        'NOW'             => array(  74,    0,    1,    1 ),
+        'AREAS'           => array(  75,    1,    0,    1 ),
+        'ROWS'            => array(  76,    1,    0,    1 ),
+        'COLUMNS'         => array(  77,    1,    0,    1 ),
+        'OFFSET'          => array(  78,   -1,    0,    1 ),
+        'SEARCH'          => array(  82,   -1,    1,    0 ),
+        'TRANSPOSE'       => array(  83,    1,    1,    0 ),
+        'TYPE'            => array(  86,    1,    1,    0 ),
+        'ATAN2'           => array(  97,    2,    1,    0 ),
+        'ASIN'            => array(  98,    1,    1,    0 ),
+        'ACOS'            => array(  99,    1,    1,    0 ),
+        'CHOOSE'          => array( 100,   -1,    1,    0 ),
+        'HLOOKUP'         => array( 101,   -1,    0,    0 ),
+        'VLOOKUP'         => array( 102,   -1,    0,    0 ),
+        'ISREF'           => array( 105,    1,    0,    0 ),
+        'LOG'             => array( 109,   -1,    1,    0 ),
+        'CHAR'            => array( 111,    1,    1,    0 ),
+        'LOWER'           => array( 112,    1,    1,    0 ),
+        'UPPER'           => array( 113,    1,    1,    0 ),
+        'PROPER'          => array( 114,    1,    1,    0 ),
+        'LEFT'            => array( 115,   -1,    1,    0 ),
+        'RIGHT'           => array( 116,   -1,    1,    0 ),
+        'EXACT'           => array( 117,    2,    1,    0 ),
+        'TRIM'            => array( 118,    1,    1,    0 ),
+        'REPLACE'         => array( 119,    4,    1,    0 ),
+        'SUBSTITUTE'      => array( 120,   -1,    1,    0 ),
+        'CODE'            => array( 121,    1,    1,    0 ),
+        'FIND'            => array( 124,   -1,    1,    0 ),
+        'CELL'            => array( 125,   -1,    0,    1 ),
+        'ISERR'           => array( 126,    1,    1,    0 ),
+        'ISTEXT'          => array( 127,    1,    1,    0 ),
+        'ISNUMBER'        => array( 128,    1,    1,    0 ),
+        'ISBLANK'         => array( 129,    1,    1,    0 ),
+        'T'               => array( 130,    1,    0,    0 ),
+        'N'               => array( 131,    1,    0,    0 ),
+        'DATEVALUE'       => array( 140,    1,    1,    0 ),
+        'TIMEVALUE'       => array( 141,    1,    1,    0 ),
+        'SLN'             => array( 142,    3,    1,    0 ),
+        'SYD'             => array( 143,    4,    1,    0 ),
+        'DDB'             => array( 144,   -1,    1,    0 ),
+        'INDIRECT'        => array( 148,   -1,    1,    1 ),
+        'CALL'            => array( 150,   -1,    1,    0 ),
+        'CLEAN'           => array( 162,    1,    1,    0 ),
+        'MDETERM'         => array( 163,    1,    2,    0 ),
+        'MINVERSE'        => array( 164,    1,    2,    0 ),
+        'MMULT'           => array( 165,    2,    2,    0 ),
+        'IPMT'            => array( 167,   -1,    1,    0 ),
+        'PPMT'            => array( 168,   -1,    1,    0 ),
+        'COUNTA'          => array( 169,   -1,    0,    0 ),
+        'PRODUCT'         => array( 183,   -1,    0,    0 ),
+        'FACT'            => array( 184,    1,    1,    0 ),
+        'DPRODUCT'        => array( 189,    3,    0,    0 ),
+        'ISNONTEXT'       => array( 190,    1,    1,    0 ),
+        'STDEVP'          => array( 193,   -1,    0,    0 ),
+        'VARP'            => array( 194,   -1,    0,    0 ),
+        'DSTDEVP'         => array( 195,    3,    0,    0 ),
+        'DVARP'           => array( 196,    3,    0,    0 ),
+        'TRUNC'           => array( 197,   -1,    1,    0 ),
+        'ISLOGICAL'       => array( 198,    1,    1,    0 ),
+        'DCOUNTA'         => array( 199,    3,    0,    0 ),
+        'ROUNDUP'         => array( 212,    2,    1,    0 ),
+        'ROUNDDOWN'       => array( 213,    2,    1,    0 ),
+        'RANK'            => array( 216,   -1,    0,    0 ),
+        'ADDRESS'         => array( 219,   -1,    1,    0 ),
+        'DAYS360'         => array( 220,   -1,    1,    0 ),
+        'TODAY'           => array( 221,    0,    1,    1 ),
+        'VDB'             => array( 222,   -1,    1,    0 ),
+        'MEDIAN'          => array( 227,   -1,    0,    0 ),
+        'SUMPRODUCT'      => array( 228,   -1,    2,    0 ),
+        'SINH'            => array( 229,    1,    1,    0 ),
+        'COSH'            => array( 230,    1,    1,    0 ),
+        'TANH'            => array( 231,    1,    1,    0 ),
+        'ASINH'           => array( 232,    1,    1,    0 ),
+        'ACOSH'           => array( 233,    1,    1,    0 ),
+        'ATANH'           => array( 234,    1,    1,    0 ),
+        'DGET'            => array( 235,    3,    0,    0 ),
+        'INFO'            => array( 244,    1,    1,    1 ),
+        'DB'              => array( 247,   -1,    1,    0 ),
+        'FREQUENCY'       => array( 252,    2,    0,    0 ),
+        'ERROR.TYPE'      => array( 261,    1,    1,    0 ),
+        'REGISTER.ID'     => array( 267,   -1,    1,    0 ),
+        'AVEDEV'          => array( 269,   -1,    0,    0 ),
+        'BETADIST'        => array( 270,   -1,    1,    0 ),
+        'GAMMALN'         => array( 271,    1,    1,    0 ),
+        'BETAINV'         => array( 272,   -1,    1,    0 ),
+        'BINOMDIST'       => array( 273,    4,    1,    0 ),
+        'CHIDIST'         => array( 274,    2,    1,    0 ),
+        'CHIINV'          => array( 275,    2,    1,    0 ),
+        'COMBIN'          => array( 276,    2,    1,    0 ),
+        'CONFIDENCE'      => array( 277,    3,    1,    0 ),
+        'CRITBINOM'       => array( 278,    3,    1,    0 ),
+        'EVEN'            => array( 279,    1,    1,    0 ),
+        'EXPONDIST'       => array( 280,    3,    1,    0 ),
+        'FDIST'           => array( 281,    3,    1,    0 ),
+        'FINV'            => array( 282,    3,    1,    0 ),
+        'FISHER'          => array( 283,    1,    1,    0 ),
+        'FISHERINV'       => array( 284,    1,    1,    0 ),
+        'FLOOR'           => array( 285,    2,    1,    0 ),
+        'GAMMADIST'       => array( 286,    4,    1,    0 ),
+        'GAMMAINV'        => array( 287,    3,    1,    0 ),
+        'CEILING'         => array( 288,    2,    1,    0 ),
+        'HYPGEOMDIST'     => array( 289,    4,    1,    0 ),
+        'LOGNORMDIST'     => array( 290,    3,    1,    0 ),
+        'LOGINV'          => array( 291,    3,    1,    0 ),
+        'NEGBINOMDIST'    => array( 292,    3,    1,    0 ),
+        'NORMDIST'        => array( 293,    4,    1,    0 ),
+        'NORMSDIST'       => array( 294,    1,    1,    0 ),
+        'NORMINV'         => array( 295,    3,    1,    0 ),
+        'NORMSINV'        => array( 296,    1,    1,    0 ),
+        'STANDARDIZE'     => array( 297,    3,    1,    0 ),
+        'ODD'             => array( 298,    1,    1,    0 ),
+        'PERMUT'          => array( 299,    2,    1,    0 ),
+        'POISSON'         => array( 300,    3,    1,    0 ),
+        'TDIST'           => array( 301,    3,    1,    0 ),
+        'WEIBULL'         => array( 302,    4,    1,    0 ),
+        'SUMXMY2'         => array( 303,    2,    2,    0 ),
+        'SUMX2MY2'        => array( 304,    2,    2,    0 ),
+        'SUMX2PY2'        => array( 305,    2,    2,    0 ),
+        'CHITEST'         => array( 306,    2,    2,    0 ),
+        'CORREL'          => array( 307,    2,    2,    0 ),
+        'COVAR'           => array( 308,    2,    2,    0 ),
+        'FORECAST'        => array( 309,    3,    2,    0 ),
+        'FTEST'           => array( 310,    2,    2,    0 ),
+        'INTERCEPT'       => array( 311,    2,    2,    0 ),
+        'PEARSON'         => array( 312,    2,    2,    0 ),
+        'RSQ'             => array( 313,    2,    2,    0 ),
+        'STEYX'           => array( 314,    2,    2,    0 ),
+        'SLOPE'           => array( 315,    2,    2,    0 ),
+        'TTEST'           => array( 316,    4,    2,    0 ),
+        'PROB'            => array( 317,   -1,    2,    0 ),
+        'DEVSQ'           => array( 318,   -1,    0,    0 ),
+        'GEOMEAN'         => array( 319,   -1,    0,    0 ),
+        'HARMEAN'         => array( 320,   -1,    0,    0 ),
+        'SUMSQ'           => array( 321,   -1,    0,    0 ),
+        'KURT'            => array( 322,   -1,    0,    0 ),
+        'SKEW'            => array( 323,   -1,    0,    0 ),
+        'ZTEST'           => array( 324,   -1,    0,    0 ),
+        'LARGE'           => array( 325,    2,    0,    0 ),
+        'SMALL'           => array( 326,    2,    0,    0 ),
+        'QUARTILE'        => array( 327,    2,    0,    0 ),
+        'PERCENTILE'      => array( 328,    2,    0,    0 ),
+        'PERCENTRANK'     => array( 329,   -1,    0,    0 ),
+        'MODE'            => array( 330,   -1,    2,    0 ),
+        'TRIMMEAN'        => array( 331,    2,    0,    0 ),
+        'TINV'            => array( 332,    2,    1,    0 ),
+        'CONCATENATE'     => array( 336,   -1,    1,    0 ),
+        'POWER'           => array( 337,    2,    1,    0 ),
+        'RADIANS'         => array( 342,    1,    1,    0 ),
+        'DEGREES'         => array( 343,    1,    1,    0 ),
+        'SUBTOTAL'        => array( 344,   -1,    0,    0 ),
+        'SUMIF'           => array( 345,   -1,    0,    0 ),
+        'COUNTIF'         => array( 346,    2,    0,    0 ),
+        'COUNTBLANK'      => array( 347,    1,    0,    0 ),
+        'ROMAN'           => array( 354,   -1,    1,    0 )
+        );
+}
+    
+/**
+* Convert a token to the proper ptg value.
+*
+* @access private
+* @param mixed $token The token to convert.
+* @return mixed the converted token on success. PEAR_Error if the token
+*               is not recognized
+*/
+function _convert($token)\r {
+    if (preg_match("/^\"[^\"]{0,255}\"$/", $token))\r {
+        return $this->_convertString($token);
+    }\r elseif (is_numeric($token))\r {
+        return $this->_convertNumber($token);
+    }
     // match references like A1 or $A$1
     \relseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/',$token))\r { 
-        return $this->_convertRef2d($token);\r
-    }\r
-    // match external references like Sheet1:Sheet2!A1\r
+        return $this->_convertRef2d($token);
+    }
+    // match external references like Sheet1:Sheet2!A1
     elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\![A-Ia-i]?[A-Za-z](\d+)$/",$token))\r {\r 
-        return $this->_convertRef3d($token);\r
-    }\r
-    // match ranges like A1:B2\r
-    elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\:(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/",$token))\r {\r
-        return $this->_convertRange2d($token);\r
-    }\r
-    // match ranges like A1..B2\r
-    elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/",$token))\r {\r
-        return $this->_convertRange2d($token);\r
-    }\r
-    // match external ranges like Sheet1:Sheet2!A1:B2\r
-    elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\!([A-Ia-i]?[A-Za-z])?(\d+)\:([A-Ia-i]?[A-Za-z])?(\d+)$/",$token))\r {\r
-        return $this->_convertRange3d($token);\r
-    }\r
-    // match external ranges like 'Sheet1:Sheet2'!A1:B2\r
-    elseif (preg_match("/^'[A-Za-z0-9_ ]+(\:[A-Za-z0-9_ ]+)?'\!([A-Ia-i]?[A-Za-z])?(\d+)\:([A-Ia-i]?[A-Za-z])?(\d+)$/",$token))\r {\r
-        return $this->_convertRange3d($token);\r
-    }\r
-    elseif (isset($this->ptg[$token])) // operators (including parentheses)\r {\r
-        return pack("C", $this->ptg[$token]);\r
-    }\r
-    // commented so argument number can be processed correctly. See toReversePolish().\r
-    /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/",$token))\r
-    {\r
-        return($this->_convertFunction($token,$this->_func_args));\r
-    }*/\r
-    // if it's an argument, ignore the token (the argument remains)\r
-    elseif ($token == 'arg')\r {\r
-        return '';\r
-    }\r
-    // TODO: use real error codes\r
-    trigger_error("Unknown token $token", E_USER_ERROR);\r
-}\r
-    \r
-/**\r
-* Convert a number token to ptgInt or ptgNum\r
-*\r
-* @access private\r
-* @param mixed $num an integer or double for conversion to its ptg value\r
-*/\r
-function _convertNumber($num)\r {\r
+        return $this->_convertRef3d($token);
+    }
+    // match ranges like A1:B2
+    elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\:(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/",$token))\r {
+        return $this->_convertRange2d($token);
+    }
+    // match ranges like A1..B2
+    elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/",$token))\r {
+        return $this->_convertRange2d($token);
+    }
+    // match external ranges like Sheet1:Sheet2!A1:B2
+    elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\!([A-Ia-i]?[A-Za-z])?(\d+)\:([A-Ia-i]?[A-Za-z])?(\d+)$/",$token))\r {
+        return $this->_convertRange3d($token);
+    }
+    // match external ranges like 'Sheet1:Sheet2'!A1:B2
+    elseif (preg_match("/^'[A-Za-z0-9_ ]+(\:[A-Za-z0-9_ ]+)?'\!([A-Ia-i]?[A-Za-z])?(\d+)\:([A-Ia-i]?[A-Za-z])?(\d+)$/",$token))\r {
+        return $this->_convertRange3d($token);
+    }
+    elseif (isset($this->ptg[$token])) // operators (including parentheses)\r {
+        return pack("C", $this->ptg[$token]);
+    }
+    // commented so argument number can be processed correctly. See toReversePolish().
+    /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/",$token))
+    {
+        return($this->_convertFunction($token,$this->_func_args));
+    }*/
+    // if it's an argument, ignore the token (the argument remains)
+    elseif ($token == 'arg')\r {
+        return '';
+    }
+    // TODO: use real error codes
+    trigger_error("Unknown token $token", E_USER_ERROR);
+}
+    
+/**
+* Convert a number token to ptgInt or ptgNum
+*
+* @access private
+* @param mixed $num an integer or double for conversion to its ptg value
+*/
+function _convertNumber($num)\r {
+
+    // Integer in the range 0..2**16-1
+
+    if ((preg_match("/^\d+$/",$num)) and ($num <= 65535)) {
+        return(pack("Cv", $this->ptg['ptgInt'], $num));
+    }\r else { // A float
+        if ($this->_byte_order) { // if it's Big Endian
+            $num = strrev($num);
+        }
+        return pack("Cd", $this->ptg['ptgNum'], $num);
+    }
+}
+    
+/**
+* Convert a string token to ptgStr
+*
+* @access private
+* @param string $string A string for conversion to its ptg value
+*/
+function _convertString($string)\r {
+    // chop away beggining and ending quotes
+    $string = substr($string, 1, strlen($string) - 2);
+    return pack("CC", $this->ptg['ptgStr'], strlen($string)).$string;
+}
+
+/**
+* Convert a function to a ptgFunc or ptgFuncVarV depending on the number of
+* args that it takes.
+*
+* @access private
+* @param string  $token    The name of the function for convertion to ptg value.
+* @param integer $num_args The number of arguments the function receives.
+* @return string The packed ptg for the function
+*/
+function _convertFunction($token, $num_args)\r {
+    $args     = $this->_functions[$token][1];
+    $volatile = $this->_functions[$token][3];
+    
+    // Fixed number of args eg. TIME($i,$j,$k).
+    if ($args >= 0) {
+        return pack("Cv", $this->ptg['ptgFuncV'], $this->_functions[$token][0]);
+    }
+    // Variable number of args eg. SUM($i,$j,$k, ..).
+    if ($args == -1) {
+        return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0]);
+    }
+}
+    
+/**
+* Convert an Excel range such as A1:D4 to a ptgRefV.
+*
+* @access private
+* @param string $range An Excel range in the A1:A2 or A1..A2 format.
+*/
+function _convertRange2d($range)\r {
+    $class = 2; // as far as I know, this is magick.
+    
+    // Split the range into 2 cell refs
+    if (preg_match("/^([A-Ia-i]?[A-Za-z])(\d+)\:([A-Ia-i]?[A-Za-z])(\d+)$/",$range)) {
+        list($cell1, $cell2) = explode(':', $range);
+    }\r elseif (preg_match("/^([A-Ia-i]?[A-Za-z])(\d+)\.\.([A-Ia-i]?[A-Za-z])(\d+)$/",$range)) {
+        list($cell1, $cell2) = explode('..', $range);
+    }\r else {
+        // TODO: use real error codes
+        trigger_error("Unknown range separator", E_USER_ERROR);
+    }
+    
+    // Convert the cell references
+    $cell_array1 = $this->_cellToPackedRowcol($cell1);
+    if ($this->isError($cell_array1)) {
+        return $cell_array1;
+    }
+    list($row1, $col1) = $cell_array1;
+    $cell_array2 = $this->_cellToPackedRowcol($cell2);
+    if ($this->isError($cell_array2)) {
+        return $cell_array2;
+    }
+    list($row2, $col2) = $cell_array2;
+    
+    // The ptg value depends on the class of the ptg.
+    if ($class == 0) {
+        $ptgArea = pack("C", $this->ptg['ptgArea']);
+    }\r elseif ($class == 1) {
+        $ptgArea = pack("C", $this->ptg['ptgAreaV']);
+    }\r elseif ($class == 2) {
+        $ptgArea = pack("C", $this->ptg['ptgAreaA']);
+    }\r else {
+        // TODO: use real error codes
+        trigger_error("Unknown class $class", E_USER_ERROR);
+    }
+    return $ptgArea . $row1 . $row2 . $col1. $col2;
+}
+/**
+* Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to
+* a ptgArea3dV.
+*
+* @access private
+* @param string $token An Excel range in the Sheet1!A1:A2 format.
+*/
+function _convertRange3d($token)\r {
+    $class = 2; // as far as I know, this is magick.
+
+    // Split the ref at the ! symbol
+    list($ext_ref, $range) = explode('!', $token);
+
+    // Convert the external reference part
+    $ext_ref = $this->_packExtRef($ext_ref);
+    if ($this->isError($ext_ref)) {
+        return $ext_ref;
+    }
+
+    // Split the range into 2 cell refs
+    list($cell1, $cell2) = explode(':', $range);
+
+    // Convert the cell references
+    if (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/", $cell1))\r {
+        $cell_array1 = $this->_cellToPackedRowcol($cell1);
+        if ($this->isError($cell_array1)) {
+            return $cell_array1;
+        }
+       list($row1, $col1) = $cell_array1;
+        $cell_array2 = $this->_cellToPackedRowcol($cell2);
+        if ($this->isError($cell_array2)) {
+           return $cell_array2;
+        }
+        list($row2, $col2) = $cell_array2;
+    }\r else { // It's a columns range (like 26:27)
+       $cells_array = $this->_rangeToPackedRange($cell1.':'.$cell2);
+       if ($this->isError($cells_array)) {
+           return $cells_array;
+        }
+       list($row1, $col1, $row2, $col2) = $cells_array;
+    }
+    // The ptg value depends on the class of the ptg.
+    if ($class == 0) {
+        $ptgArea = pack("C", $this->ptg['ptgArea3d']);
+    }\r elseif ($class == 1) {
+        $ptgArea = pack("C", $this->ptg['ptgArea3dV']);
+    }\r elseif ($class == 2) {
+        $ptgArea = pack("C", $this->ptg['ptgArea3dA']);
+    }\r else {
+        trigger_error("Unknown class $class", E_USER_ERROR);
+    }
+    return $ptgArea . $ext_ref . $row1 . $row2 . $col1. $col2;
+}
+
+/**
+* Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV.
+*
+* @access private
+* @param string $cell An Excel cell reference
+* @return string The cell in packed() format with the corresponding ptg
+*/
+function _convertRef2d($cell)\r {
+    $class = 2; // as far as I know, this is magick.
+    
+    // Convert the cell reference
+    $cell_array = $this->_cellToPackedRowcol($cell);
+    if ($this->isError($cell_array)) {
+        return $cell_array;
+    }
+    list($row, $col) = $cell_array;
+
+    // The ptg value depends on the class of the ptg.
+    if ($class == 0) {
+        $ptgRef = pack("C", $this->ptg['ptgRef']);
+    }\r elseif ($class == 1) {
+        $ptgRef = pack("C", $this->ptg['ptgRefV']);
+    }\r elseif ($class == 2) {
+        $ptgRef = pack("C", $this->ptg['ptgRefA']);
+    }\r else {
+        // TODO: use real error codes
+        trigger_error("Unknown class $class",E_USER_ERROR);
+    }
+    return $ptgRef.$row.$col;
+}
+    
+/**
+* Convert an Excel 3d reference such as "Sheet1!A1" or "Sheet1:Sheet2!A1" to a
+* ptgRef3dV.
+*
+* @access private
+* @param string $cell An Excel cell reference
+* @return string The cell in packed() format with the corresponding ptg
+*/
+function _convertRef3d($cell)\r {
+    $class = 2; // as far as I know, this is magick.
+    // Split the ref at the ! symbol
+    list($ext_ref, $cell) = explode('!', $cell);
+    // Convert the external reference part
+    $ext_ref = $this->_packExtRef($ext_ref);
+    if ($this->isError($ext_ref)) {
+        return $ext_ref;
+    }
+    // Convert the cell reference part
+    list($row, $col) = $this->_cellToPackedRowcol($cell);
+    // The ptg value depends on the class of the ptg.
+    if ($class == 0) {
+        $ptgRef = pack("C", $this->ptg['ptgRef3d']);
+    } elseif ($class == 1) {
+        $ptgRef = pack("C", $this->ptg['ptgRef3dV']);
+    } elseif ($class == 2) {
+        $ptgRef = pack("C", $this->ptg['ptgRef3dA']);
+    }\r else {
+        trigger_error("Unknown class $class", E_USER_ERROR);
+    }
+
+    return $ptgRef . $ext_ref. $row . $col;
+}
+
+/**
+* Convert the sheet name part of an external reference, for example "Sheet1" or
+* "Sheet1:Sheet2", to a packed structure.
+*
+* @access private
+* @param string $ext_ref The name of the external reference
+* @return string The reference index in packed() format
+*/
+function _packExtRef($ext_ref) {
+    $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading  ' if any.
+    $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any.
 
-    // Integer in the range 0..2**16-1\r
+    // Check if there is a sheet range eg., Sheet1:Sheet2.
+    if (preg_match("/:/", $ext_ref))\r {
+        list($sheet_name1, $sheet_name2) = explode(':', $ext_ref);
 
-    if ((preg_match("/^\d+$/",$num)) and ($num <= 65535)) {\r
-        return(pack("Cv", $this->ptg['ptgInt'], $num));\r
-    }\r else { // A float\r
-        if ($this->_byte_order) { // if it's Big Endian\r
-            $num = strrev($num);\r
-        }\r
-        return pack("Cd", $this->ptg['ptgNum'], $num);\r
-    }\r
-}\r
-    \r
-/**\r
-* Convert a string token to ptgStr\r
-*\r
-* @access private\r
-* @param string $string A string for conversion to its ptg value\r
-*/\r
-function _convertString($string)\r {\r
-    // chop away beggining and ending quotes\r
-    $string = substr($string, 1, strlen($string) - 2);\r
-    return pack("CC", $this->ptg['ptgStr'], strlen($string)).$string;\r
-}\r
-\r
-/**\r
-* Convert a function to a ptgFunc or ptgFuncVarV depending on the number of\r
-* args that it takes.\r
-*\r
-* @access private\r
-* @param string  $token    The name of the function for convertion to ptg value.\r
-* @param integer $num_args The number of arguments the function receives.\r
-* @return string The packed ptg for the function\r
-*/\r
-function _convertFunction($token, $num_args)\r {\r
-    $args     = $this->_functions[$token][1];\r
-    $volatile = $this->_functions[$token][3];\r
-    \r
-    // Fixed number of args eg. TIME($i,$j,$k).\r
-    if ($args >= 0) {\r
-        return pack("Cv", $this->ptg['ptgFuncV'], $this->_functions[$token][0]);\r
-    }\r
-    // Variable number of args eg. SUM($i,$j,$k, ..).\r
-    if ($args == -1) {\r
-        return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0]);\r
-    }\r
-}\r
-    \r
-/**\r
-* Convert an Excel range such as A1:D4 to a ptgRefV.\r
-*\r
-* @access private\r
-* @param string $range An Excel range in the A1:A2 or A1..A2 format.\r
-*/\r
-function _convertRange2d($range)\r {\r
-    $class = 2; // as far as I know, this is magick.\r
-    \r
-    // Split the range into 2 cell refs\r
-    if (preg_match("/^([A-Ia-i]?[A-Za-z])(\d+)\:([A-Ia-i]?[A-Za-z])(\d+)$/",$range)) {\r
-        list($cell1, $cell2) = split(':', $range);\r
-    }\r elseif (preg_match("/^([A-Ia-i]?[A-Za-z])(\d+)\.\.([A-Ia-i]?[A-Za-z])(\d+)$/",$range)) {\r
-        list($cell1, $cell2) = split('\.\.', $range);\r
-    }\r else {\r
-        // TODO: use real error codes\r
-        trigger_error("Unknown range separator", E_USER_ERROR);\r
-    }\r
-    \r
-    // Convert the cell references\r
-    $cell_array1 = $this->_cellToPackedRowcol($cell1);\r
-    if ($this->isError($cell_array1)) {\r
-        return $cell_array1;\r
-    }\r
-    list($row1, $col1) = $cell_array1;\r
-    $cell_array2 = $this->_cellToPackedRowcol($cell2);\r
-    if ($this->isError($cell_array2)) {\r
-        return $cell_array2;\r
-    }\r
-    list($row2, $col2) = $cell_array2;\r
-    \r
-    // The ptg value depends on the class of the ptg.\r
-    if ($class == 0) {\r
-        $ptgArea = pack("C", $this->ptg['ptgArea']);\r
-    }\r elseif ($class == 1) {\r
-        $ptgArea = pack("C", $this->ptg['ptgAreaV']);\r
-    }\r elseif ($class == 2) {\r
-        $ptgArea = pack("C", $this->ptg['ptgAreaA']);\r
-    }\r else {\r
-        // TODO: use real error codes\r
-        trigger_error("Unknown class $class", E_USER_ERROR);\r
-    }\r
-    return $ptgArea . $row1 . $row2 . $col1. $col2;\r
-}\r
\r
-/**\r
-* Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to\r
-* a ptgArea3dV.\r
-*\r
-* @access private\r
-* @param string $token An Excel range in the Sheet1!A1:A2 format.\r
-*/\r
-function _convertRange3d($token)\r {\r
-    $class = 2; // as far as I know, this is magick.\r
-\r
-    // Split the ref at the ! symbol\r
-    list($ext_ref, $range) = split('!', $token);\r
-\r
-    // Convert the external reference part\r
-    $ext_ref = $this->_packExtRef($ext_ref);\r
-    if ($this->isError($ext_ref)) {\r
-        return $ext_ref;\r
-    }\r
-\r
-    // Split the range into 2 cell refs\r
-    list($cell1, $cell2) = split(':', $range);\r
-\r
-    // Convert the cell references\r
-    if (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/", $cell1))\r {\r
-        $cell_array1 = $this->_cellToPackedRowcol($cell1);\r
-        if ($this->isError($cell_array1)) {\r
-            return $cell_array1;\r
-        }\r
-       list($row1, $col1) = $cell_array1;\r
-        $cell_array2 = $this->_cellToPackedRowcol($cell2);\r
-        if ($this->isError($cell_array2)) {\r
-           return $cell_array2;\r
-        }\r
-        list($row2, $col2) = $cell_array2;\r
-    }\r else { // It's a columns range (like 26:27)\r
-       $cells_array = $this->_rangeToPackedRange($cell1.':'.$cell2);\r
-       if ($this->isError($cells_array)) {\r
-           return $cells_array;\r
-        }\r
-       list($row1, $col1, $row2, $col2) = $cells_array;\r
-    }\r
\r
-    // The ptg value depends on the class of the ptg.\r
-    if ($class == 0) {\r
-        $ptgArea = pack("C", $this->ptg['ptgArea3d']);\r
-    }\r elseif ($class == 1) {\r
-        $ptgArea = pack("C", $this->ptg['ptgArea3dV']);\r
-    }\r elseif ($class == 2) {\r
-        $ptgArea = pack("C", $this->ptg['ptgArea3dA']);\r
-    }\r else {\r
-        trigger_error("Unknown class $class", E_USER_ERROR);\r
-    }\r
\r
-    return $ptgArea . $ext_ref . $row1 . $row2 . $col1. $col2;\r
-}\r
-\r
-/**\r
-* Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV.\r
-*\r
-* @access private\r
-* @param string $cell An Excel cell reference\r
-* @return string The cell in packed() format with the corresponding ptg\r
-*/\r
-function _convertRef2d($cell)\r {\r
-    $class = 2; // as far as I know, this is magick.\r
-    \r
-    // Convert the cell reference\r
-    $cell_array = $this->_cellToPackedRowcol($cell);\r
-    if ($this->isError($cell_array)) {\r
-        return $cell_array;\r
-    }\r
-    list($row, $col) = $cell_array;\r
-\r
-    // The ptg value depends on the class of the ptg.\r
-    if ($class == 0) {\r
-        $ptgRef = pack("C", $this->ptg['ptgRef']);\r
-    }\r elseif ($class == 1) {\r
-        $ptgRef = pack("C", $this->ptg['ptgRefV']);\r
-    }\r elseif ($class == 2) {\r
-        $ptgRef = pack("C", $this->ptg['ptgRefA']);\r
-    }\r else {\r
-        // TODO: use real error codes\r
-        trigger_error("Unknown class $class",E_USER_ERROR);\r
-    }\r
-    return $ptgRef.$row.$col;\r
-}\r
-    \r
-/**\r
-* Convert an Excel 3d reference such as "Sheet1!A1" or "Sheet1:Sheet2!A1" to a\r
-* ptgRef3dV.\r
-*\r
-* @access private\r
-* @param string $cell An Excel cell reference\r
-* @return string The cell in packed() format with the corresponding ptg\r
-*/\r
-function _convertRef3d($cell)\r {\r
-    $class = 2; // as far as I know, this is magick.\r
\r
-    // Split the ref at the ! symbol\r
-    list($ext_ref, $cell) = split('!', $cell);\r
\r
-    // Convert the external reference part\r
-    $ext_ref = $this->_packExtRef($ext_ref);\r
-    if ($this->isError($ext_ref)) {\r
-        return $ext_ref;\r
-    }\r
\r
-    // Convert the cell reference part\r
-    list($row, $col) = $this->_cellToPackedRowcol($cell);\r
\r
-    // The ptg value depends on the class of the ptg.\r
-    if ($class == 0) {\r
-        $ptgRef = pack("C", $this->ptg['ptgRef3d']);\r
-    } elseif ($class == 1) {\r
-        $ptgRef = pack("C", $this->ptg['ptgRef3dV']);\r
-    } elseif ($class == 2) {\r
-        $ptgRef = pack("C", $this->ptg['ptgRef3dA']);\r
-    }\r else {\r
-        trigger_error("Unknown class $class", E_USER_ERROR);\r
-    }\r
-\r
-    return $ptgRef . $ext_ref. $row . $col;\r
-}\r
-\r
-/**\r
-* Convert the sheet name part of an external reference, for example "Sheet1" or\r
-* "Sheet1:Sheet2", to a packed structure.\r
-*\r
-* @access private\r
-* @param string $ext_ref The name of the external reference\r
-* @return string The reference index in packed() format\r
-*/\r
-function _packExtRef($ext_ref) {\r
-    $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading  ' if any.\r
-    $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any.\r
-\r
-    // Check if there is a sheet range eg., Sheet1:Sheet2.\r
-    if (preg_match("/:/", $ext_ref))\r {\r
-        list($sheet_name1, $sheet_name2) = split(':', $ext_ref);\r
-\r
-        $sheet1 = $this->_getSheetIndex($sheet_name1);\r
-        if ($sheet1 == -1) {\r
-            trigger_error("Unknown sheet name $sheet_name1 in formula",E_USER_ERROR);\r
-        }\r
-        $sheet2 = $this->_getSheetIndex($sheet_name2);\r
-        if ($sheet2 == -1) {\r
-            trigger_error("Unknown sheet name $sheet_name2 in formula",E_USER_ERROR);\r
-        }\r
-\r
-        // Reverse max and min sheet numbers if necessary\r
-        if ($sheet1 > $sheet2) {\r
-            list($sheet1, $sheet2) = array($sheet2, $sheet1);\r
-        }\r
-    }\r else { // Single sheet name only.\r
-        $sheet1 = $this->_getSheetIndex($ext_ref);\r
-        if ($sheet1 == -1) {\r
-            trigger_error("Unknown sheet name $ext_ref in formula",E_USER_ERROR);\r
-        }\r
-        $sheet2 = $sheet1;\r
-    }\r
\r
-    // References are stored relative to 0xFFFF.\r
-    $offset = -1 - $sheet1;\r
+        $sheet1 = $this->_getSheetIndex($sheet_name1);
+        if ($sheet1 == -1) {
+            trigger_error("Unknown sheet name $sheet_name1 in formula",E_USER_ERROR);
+        }
+        $sheet2 = $this->_getSheetIndex($sheet_name2);
+        if ($sheet2 == -1) {
+            trigger_error("Unknown sheet name $sheet_name2 in formula",E_USER_ERROR);
+        }
+
+        // Reverse max and min sheet numbers if necessary
+        if ($sheet1 > $sheet2) {
+            list($sheet1, $sheet2) = array($sheet2, $sheet1);
+        }
+    }\r else { // Single sheet name only.
+        $sheet1 = $this->_getSheetIndex($ext_ref);
+        if ($sheet1 == -1) {
+            trigger_error("Unknown sheet name $ext_ref in formula",E_USER_ERROR);
+        }
+        $sheet2 = $sheet1;
+    }
+    // References are stored relative to 0xFFFF.
+    $offset = -1 - $sheet1;
 
-    return pack('vdvv', $offset, 0x00, $sheet1, $sheet2);\r
-}\r
-\r
-/**\r
-* Look up the index that corresponds to an external sheet name. The hash of\r
-* sheet names is updated by the addworksheet() method of the \r
-* Spreadsheet_Excel_Writer_Workbook class.\r
-*\r
-* @access private\r
-* @return integer\r
-*/\r
-function _getSheetIndex($sheet_name)\r {\r
-    if (!isset($this->_ext_sheets[$sheet_name])) {\r
-        return -1;\r
-    }\r else {\r
-        return $this->_ext_sheets[$sheet_name];\r
-    }\r
-}\r
-\r
-/**\r
-* This method is used to update the array of sheet names. It is\r
-* called by the addWorksheet() method of the Spreadsheet_Excel_Writer_Workbook class.\r
-*\r
-* @access private\r
-* @param string  $name  The name of the worksheet being added\r
-* @param integer $index The index of the worksheet being added\r
-*/\r
-function setExtSheet($name, $index)\r {\r
-    $this->_ext_sheets[$name] = $index;\r
-}\r
-\r
-/**\r
-* pack() row and column into the required 3 byte format.\r
-*\r
-* @access private\r
-* @param string $cell The Excel cell reference to be packed\r
-* @return array Array containing the row and column in packed() format\r
-*/\r
-function _cellToPackedRowcol($cell)\r {\r
-    $cell = strtoupper($cell);\r
-    list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell);\r
-    if ($col >= 256) {\r
-        trigger_error("Column in: $cell greater than 255", E_USER_ERROR);\r
-    }\r
-    if ($row >= 16384) {\r
-        trigger_error("Row in: $cell greater than 16384 ", E_USER_ERROR);\r
-    }\r
-\r
-    // Set the high bits to indicate if row or col are relative.\r
-    $row    |= $col_rel << 14;\r
-    $row    |= $row_rel << 15;\r
-\r
-    $row     = pack('v', $row);\r
-    $col     = pack('C', $col);\r
-\r
-    return array($row, $col);\r
-}\r
-    \r
-/**\r
-* pack() row range into the required 3 byte format.\r
-* Just using maximun col/rows, which is probably not the correct solution\r
-*\r
-* @access private\r
-* @param string $range The Excel range to be packed\r
-* @return array Array containing (row1,col1,row2,col2) in packed() format\r
-*/\r
-function _rangeToPackedRange($range)\r {\r
-    preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match);\r
-    // return absolute rows if there is a $ in the ref\r
-    $row1_rel = empty($match[1]) ? 1 : 0;\r
-    $row1     = $match[2];\r
-    $row2_rel = empty($match[3]) ? 1 : 0;\r
-    $row2     = $match[4];\r
-    // Convert 1-index to zero-index\r
-    $row1--;\r
-    $row2--;\r
-    // Trick poor inocent Excel\r
-    $col1 = 0;\r
-    $col2 = 16383; // maximum possible value for Excel 5 (change this!!!)\r
+    return pack('vdvv', $offset, 0x00, $sheet1, $sheet2);
+}
 
-    //list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell);\r
-    if (($row1 >= 16384) or ($row2 >= 16384)) {\r
-        trigger_error("Row in: $range greater than 16384 ",E_USER_ERROR);\r
-    }\r
-\r
-    // Set the high bits to indicate if rows are relative.\r
-    $row1    |= $row1_rel << 14;\r
-    $row2    |= $row2_rel << 15;\r
-\r
-    $row1     = pack('v', $row1);\r
-    $row2     = pack('v', $row2);\r
-    $col1     = pack('C', $col1);\r
-    $col2     = pack('C', $col2);\r
-\r
-    return array($row1, $col1, $row2, $col2);\r
-}\r
-\r
-/**\r
-* Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero\r
-* indexed row and column number. Also returns two (0,1) values to indicate\r
-* whether the row or column are relative references.\r
-*\r
-* @access private\r
-* @param string $cell The Excel cell reference in A1 format.\r
-* @return array\r
-*/\r
-function _cellToRowcol($cell)\r {\r
-    preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/',$cell,$match);\r
-    // return absolute column if there is a $ in the ref\r
-    $col_rel = empty($match[1]) ? 1 : 0;\r
-    $col_ref = $match[2];\r
-    $row_rel = empty($match[3]) ? 1 : 0;\r
-    $row     = $match[4];\r
-    \r
-    // Convert base26 column string to a number.\r
-    $expn   = strlen($col_ref) - 1;\r
-    $col    = 0;\r
-    for ($i=0; $i < strlen($col_ref); $i++)\r {\r
-        $col += (ord($col_ref{$i}) - ord('A') + 1) * pow(26, $expn);\r
-        $expn--;\r
-    }\r
-    \r
-    // Convert 1-index to zero-index\r
-    $row--;\r
-    $col--;\r
-    \r
-    return array($row, $col, $row_rel, $col_rel);\r
-}\r
-    \r
-/**\r
-* Advance to the next valid token.\r
-*\r
-* @access private\r
-*/\r
-function _advance()\r {\r
-    $i = $this->_current_char;\r
-    // eat up white spaces\r
-    if ($i < strlen($this->_formula))\r {\r
-        while ($this->_formula{$i} == " ") {\r
-            $i++;\r
-        }\r
-        if ($i < strlen($this->_formula) - 1) {\r
-            $this->_lookahead = $this->_formula{$i+1};\r
-        }\r
-        $token = "";\r
-    }\r
-    while ($i < strlen($this->_formula))\r {\r
-        $token .= $this->_formula{$i};\r
-        if ($i < strlen($this->_formula) - 1) {\r
-            $this->_lookahead = $this->_formula{$i+1};\r
-        }\r else {\r
-            $this->_lookahead = '';\r
-        }\r
-        if ($this->_match($token) != '')\r {\r
-            //if ($i < strlen($this->_formula) - 1) {\r
-            //    $this->_lookahead = $this->_formula{$i+1};\r
-            //}\r
-            $this->_current_char = $i + 1;\r
-            $this->_current_token = $token;\r
-            return 1;\r
-        }\r
-        if ($i < strlen($this->_formula) - 2) {\r
-            $this->_lookahead = $this->_formula{$i+2};\r
-        }\r else {\r
-        // if we run out of characters _lookahead becomes empty\r
-            $this->_lookahead = '';\r
-        }\r
-        $i++;\r
-    }\r
-    //die("Lexical error ".$this->_current_char);\r
-}\r
-    \r
-/**\r
-* Checks if it's a valid token.\r
-*\r
-* @access private\r
-* @param mixed $token The token to check.\r
-* @return mixed       The checked token or false on failure\r
-*/\r
-function _match($token)\r {\r
-    switch($token)\r {\r
-        case SPREADSHEET_EXCEL_WRITER_ADD:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_SUB:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_MUL:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_DIV:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_OPEN:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_CLOSE:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_SCOLON:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_COMA:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_GT:\r
-            if ($this->_lookahead == '=') { // it's a GE token\r
-                break;\r
-            }\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_LT:\r
-            // it's a LE or a NE token\r
-            if (($this->_lookahead == '=') or ($this->_lookahead == '>')) {\r
-                break;\r
-            }\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_GE:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_LE:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_EQ:\r
-            return($token);\r
-            break;\r
-        case SPREADSHEET_EXCEL_WRITER_NE:\r
-            return($token);\r
-            break;\r
-        default:\r
-            // if it's a reference\r
-            if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$token) and\r
-               !ereg("[0-9]",$this->_lookahead) and \r
-               ($this->_lookahead != ':') and ($this->_lookahead != '.') and\r
-               ($this->_lookahead != '!'))\r {\r
-                return $token;\r
-            }\r
-            // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1)\r
-            elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\![A-Ia-i]?[A-Za-z][0-9]+$/",$token) and\r
-                   !ereg("[0-9]",$this->_lookahead) and\r
-                   ($this->_lookahead != ':') and ($this->_lookahead != '.'))\r {\r
-                return $token;\r
-            }\r
-            // if it's a range (A1:A2)\r
-            elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$token) and \r
-                   !ereg("[0-9]",$this->_lookahead))\r {\r
-                return $token;\r
-            }\r
-            // if it's a range (A1..A2)\r
-            elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$token) and \r
-                   !ereg("[0-9]",$this->_lookahead))\r {\r
-                return $token;\r
-            }\r
-            // If it's an external range like Sheet1:Sheet2!A1:B2\r
-            elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$token) and\r
-                   !ereg("[0-9]",$this->_lookahead))\r {\r
-                return $token;\r
-            }\r
-           // If it's an external range like 'Sheet1:Sheet2'!A1:B2\r
-            elseif (preg_match("/^'[A-Za-z0-9_ ]+(\:[A-Za-z0-9_ ]+)?'\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$token) and\r
-                   !ereg("[0-9]",$this->_lookahead))\r {\r
-                return $token;\r
-            }\r
-            // If it's a number (check that it's not a sheet name or range)\r
-            elseif (is_numeric($token) and \r
-                    (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and\r
-                    ($this->_lookahead != '!') and ($this->_lookahead != ':'))\r {\r
-                return $token;\r
-            }\r
-            // If it's a string (of maximum 255 characters)\r
-            elseif (ereg("^\"[^\"]{0,255}\"$",$token))\r {\r
-                return $token;\r
-            }\r
-            // if it's a function call\r
-            elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$token) and ($this->_lookahead == "(")) {\r
-                return $token;\r
-            }\r
-            return '';\r
-    }\r
-}\r
-    \r
-/**\r
-* The parsing method. It parses a formula.\r
-*\r
-* @access public\r
-* @param string $formula The formula to parse, without the initial equal sign (=).\r
-*/\r
-function parse($formula)\r {\r
-    $this->_current_char = 0;\r
-    $this->_formula      = $formula;\r
-    $this->_lookahead    = $formula{1};\r
-    $this->_advance();\r
-    $this->_parse_tree   = $this->_condition();\r
-    if ($this->isError($this->_parse_tree)) {\r
-        return $this->_parse_tree;\r
-    }\r
-}\r
-    \r
-/**\r
-* It parses a condition. It assumes the following rule:\r
-* Cond -> Expr [(">" | "<") Expr]\r
-*\r
-* @access private\r
-* @return mixed The parsed ptg'd tree\r
-*/\r
-function _condition()\r {\r
-    $result = $this->_expression();\r
-    if ($this->isError($result)) {\r
-        return $result;\r
-    }\r
-    if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_LT)\r {\r
-        $this->_advance();\r
-        $result2 = $this->_expression();\r
-        if ($this->isError($result2)) {\r
-            return $result2;\r
-        }\r
-        $result = $this->_createTree('ptgLT', $result, $result2);\r
-    }\r elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_GT) \r{\r
-        $this->_advance();\r
-        $result2 = $this->_expression();\r
-        if ($this->isError($result2)) {\r
-            return $result2;\r
-        }\r
-        $result = $this->_createTree('ptgGT', $result, $result2);\r
-    }\r elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_LE) \r{\r
-        $this->_advance();\r
-        $result2 = $this->_expression();\r
-        if ($this->isError($result2)) {\r
-            return $result2;\r
-        }\r
-        $result = $this->_createTree('ptgLE', $result, $result2);\r
-    }\r elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_GE) \r{\r
-        $this->_advance();\r
-        $result2 = $this->_expression();\r
-        if ($this->isError($result2)) {\r
-            return $result2;\r
-        }\r
-        $result = $this->_createTree('ptgGE', $result, $result2);\r
-    }\r elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_EQ) \r{\r
-        $this->_advance();\r
-        $result2 = $this->_expression();\r
-        if ($this->isError($result2)) {\r
-            return $result2;\r
-        }\r
-        $result = $this->_createTree('ptgEQ', $result, $result2);\r
-    }\r elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_NE) \r{\r
-        $this->_advance();\r
-        $result2 = $this->_expression();\r
-        if ($this->isError($result2)) {\r
-            return $result2;\r
-        }\r
-        $result = $this->_createTree('ptgNE', $result, $result2);\r
-    }\r
-    return $result;\r
-}\r
+/**
+* Look up the index that corresponds to an external sheet name. The hash of
+* sheet names is updated by the addworksheet() method of the 
+* Spreadsheet_Excel_Writer_Workbook class.
+*
+* @access private
+* @return integer
+*/
+function _getSheetIndex($sheet_name)\r {
+    if (!isset($this->_ext_sheets[$sheet_name])) {
+        return -1;
+    }\r else {
+        return $this->_ext_sheets[$sheet_name];
+    }
+}
 
-/**\r
-* It parses a expression. It assumes the following rule:\r
-* Expr -> Term [("+" | "-") Term]\r
-*\r
-* @access private\r
-* @return mixed The parsed ptg'd tree\r
-*/\r
-function _expression()\r {\r
-    // If it's a string return a string node\r
-    if (ereg("^\"[^\"]{0,255}\"$", $this->_current_token))\r {\r
-        $result = $this->_createTree($this->_current_token, '', '');\r
-        $this->_advance();\r
-        return $result;\r
-    }\r
-    $result = $this->_term();\r
-    if ($this->isError($result)) {\r
-        return $result;\r
-    }\r
-    while (($this->_current_token == SPREADSHEET_EXCEL_WRITER_ADD) or \r
-           ($this->_current_token == SPREADSHEET_EXCEL_WRITER_SUB))\r {\r
+/**
+* This method is used to update the array of sheet names. It is
+* called by the addWorksheet() method of the Spreadsheet_Excel_Writer_Workbook class.
+*
+* @access private
+* @param string  $name  The name of the worksheet being added
+* @param integer $index The index of the worksheet being added
+*/
+function setExtSheet($name, $index)\r {
+    $this->_ext_sheets[$name] = $index;
+}
+
+/**
+* pack() row and column into the required 3 byte format.
+*
+* @access private
+* @param string $cell The Excel cell reference to be packed
+* @return array Array containing the row and column in packed() format
+*/
+function _cellToPackedRowcol($cell)\r {
+    $cell = strtoupper($cell);
+    list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell);
+    if ($col >= 256) {
+        trigger_error("Column in: $cell greater than 255", E_USER_ERROR);
+    }
+    if ($row >= 16384) {
+        trigger_error("Row in: $cell greater than 16384 ", E_USER_ERROR);
+    }
+
+    // Set the high bits to indicate if row or col are relative.
+    $row    |= $col_rel << 14;
+    $row    |= $row_rel << 15;
+
+    $row     = pack('v', $row);
+    $col     = pack('C', $col);
+
+    return array($row, $col);
+}
+    
+/**
+* pack() row range into the required 3 byte format.
+* Just using maximun col/rows, which is probably not the correct solution
+*
+* @access private
+* @param string $range The Excel range to be packed
+* @return array Array containing (row1,col1,row2,col2) in packed() format
+*/
+function _rangeToPackedRange($range)\r {
+    preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match);
+    // return absolute rows if there is a $ in the ref
+    $row1_rel = empty($match[1]) ? 1 : 0;
+    $row1     = $match[2];
+    $row2_rel = empty($match[3]) ? 1 : 0;
+    $row2     = $match[4];
+    // Convert 1-index to zero-index
+    $row1--;
+    $row2--;
+    // Trick poor inocent Excel
+    $col1 = 0;
+    $col2 = 16383; // maximum possible value for Excel 5 (change this!!!)
+
+    //list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell);
+    if (($row1 >= 16384) or ($row2 >= 16384)) {
+        trigger_error("Row in: $range greater than 16384 ",E_USER_ERROR);
+    }
+
+    // Set the high bits to indicate if rows are relative.
+    $row1    |= $row1_rel << 14;
+    $row2    |= $row2_rel << 15;
+
+    $row1     = pack('v', $row1);
+    $row2     = pack('v', $row2);
+    $col1     = pack('C', $col1);
+    $col2     = pack('C', $col2);
+
+    return array($row1, $col1, $row2, $col2);
+}
+
+/**
+* Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero
+* indexed row and column number. Also returns two (0,1) values to indicate
+* whether the row or column are relative references.
+*
+* @access private
+* @param string $cell The Excel cell reference in A1 format.
+* @return array
+*/
+function _cellToRowcol($cell)\r {
+    preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/',$cell,$match);
+    // return absolute column if there is a $ in the ref
+    $col_rel = empty($match[1]) ? 1 : 0;
+    $col_ref = $match[2];
+    $row_rel = empty($match[3]) ? 1 : 0;
+    $row     = $match[4];
+    
+    // Convert base26 column string to a number.
+    $expn   = strlen($col_ref) - 1;
+    $col    = 0;
+    for ($i=0; $i < strlen($col_ref); $i++)\r {
+        $col += (ord($col_ref{$i}) - ord('A') + 1) * pow(26, $expn);
+        $expn--;
+    }
+    
+    // Convert 1-index to zero-index
+    $row--;
+    $col--;
+    
+    return array($row, $col, $row_rel, $col_rel);
+}
+    
+/**
+* Advance to the next valid token.
+*
+* @access private
+*/
+function _advance()\r {
+    $i = $this->_current_char;
+    // eat up white spaces
+    if ($i < strlen($this->_formula))\r {
+        while ($this->_formula{$i} == " ") {
+            $i++;
+        }
+        if ($i < strlen($this->_formula) - 1) {
+            $this->_lookahead = $this->_formula{$i+1};
+        }
+        $token = "";
+    }
+    while ($i < strlen($this->_formula))\r {
+        $token .= $this->_formula{$i};
+        if ($i < strlen($this->_formula) - 1) {
+            $this->_lookahead = $this->_formula{$i+1};
+        }\r else {
+            $this->_lookahead = '';
+        }
+        if ($this->_match($token) != '')\r {
+            //if ($i < strlen($this->_formula) - 1) {
+            //    $this->_lookahead = $this->_formula{$i+1};
+            //}
+            $this->_current_char = $i + 1;
+            $this->_current_token = $token;
+            return 1;
+        }
+        if ($i < strlen($this->_formula) - 2) {
+            $this->_lookahead = $this->_formula{$i+2};
+        }\r else {
+        // if we run out of characters _lookahead becomes empty
+            $this->_lookahead = '';
+        }
+        $i++;
+    }
+    //die("Lexical error ".$this->_current_char);
+}
+    
+/**
+* Checks if it's a valid token.
+*
+* @access private
+* @param mixed $token The token to check.
+* @return mixed       The checked token or false on failure
+*/
+function _match($token)\r {
+    switch($token)\r {
+        case SPREADSHEET_EXCEL_WRITER_ADD:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_SUB:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_MUL:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_DIV:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_OPEN:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_CLOSE:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_SCOLON:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_COMA:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_GT:
+            if ($this->_lookahead == '=') { // it's a GE token
+                break;
+            }
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_LT:
+            // it's a LE or a NE token
+            if (($this->_lookahead == '=') or ($this->_lookahead == '>')) {
+                break;
+            }
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_GE:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_LE:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_EQ:
+            return($token);
+            break;
+        case SPREADSHEET_EXCEL_WRITER_NE:
+            return($token);
+            break;
+        default:
+            // if it's a reference
+            if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$token) and
+               !ereg("[0-9]",$this->_lookahead) and 
+               ($this->_lookahead != ':') and ($this->_lookahead != '.') and
+               ($this->_lookahead != '!')) {
+                return $token;
+            }
+            // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1)
+            elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\![A-Ia-i]?[A-Za-z][0-9]+$/",$token) and
+                   !ereg("[0-9]",$this->_lookahead) and
+                   ($this->_lookahead != ':') and ($this->_lookahead != '.')) {
+                return $token;
+            }
+            // if it's a range (A1:A2)
+            elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$token) and 
+                   !ereg("[0-9]",$this->_lookahead)) {
+                return $token;
+            }
+            // if it's a range (A1..A2)
+            elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$token) and 
+                   !ereg("[0-9]",$this->_lookahead)) {
+                return $token;
+            }
+            // If it's an external range like Sheet1:Sheet2!A1:B2
+            elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$token) and
+                   !ereg("[0-9]",$this->_lookahead)) {
+                return $token;
+            }
+           // If it's an external range like 'Sheet1:Sheet2'!A1:B2
+            elseif (preg_match("/^'[A-Za-z0-9_ ]+(\:[A-Za-z0-9_ ]+)?'\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$token) and
+                   !ereg("[0-9]",$this->_lookahead)) {
+                return $token;
+            }
+            // If it's a number (check that it's not a sheet name or range)
+            elseif (is_numeric($token) and 
+                    (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and
+                    ($this->_lookahead != '!') and ($this->_lookahead != ':')) {
+                return $token;
+            }
+            // If it's a string (of maximum 255 characters)
+            elseif (ereg("^\"[^\"]{0,255}\"$",$token)) {
+                return $token;
+            }
+            // if it's a function call
+            elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$token) and ($this->_lookahead == "(")) {
+                return $token;
+            }
+            return '';
+    }
+}
+    
+/**
+* The parsing method. It parses a formula.
+*
+* @access public
+* @param string $formula The formula to parse, without the initial equal sign (=).
+*/
+function parse($formula) {
+    $this->_current_char = 0;
+    $this->_formula      = $formula;
+    $this->_lookahead    = $formula{1};
+    $this->_advance();
+    $this->_parse_tree   = $this->_condition();
+    if ($this->isError($this->_parse_tree)) {
+        return $this->_parse_tree;
+    }
+}
+    
+/**
+* It parses a condition. It assumes the following rule:
+* Cond -> Expr [(">" | "<") Expr]
+*
+* @access private
+* @return mixed The parsed ptg'd tree
+*/
+function _condition()\r {
+    $result = $this->_expression();
+    if ($this->isError($result)) {
+        return $result;
+    }
+    if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_LT)\r {
+        $this->_advance();
+        $result2 = $this->_expression();
+        if ($this->isError($result2)) {
+            return $result2;
+        }
+        $result = $this->_createTree('ptgLT', $result, $result2);
+    }\r elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_GT) \r{
+        $this->_advance();
+        $result2 = $this->_expression();
+        if ($this->isError($result2)) {
+            return $result2;
+        }
+        $result = $this->_createTree('ptgGT', $result, $result2);
+    }\r elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_LE) \r{
+        $this->_advance();
+        $result2 = $this->_expression();
+        if ($this->isError($result2)) {
+            return $result2;
+        }
+        $result = $this->_createTree('ptgLE', $result, $result2);
+    }\r elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_GE) \r{
+        $this->_advance();
+        $result2 = $this->_expression();
+        if ($this->isError($result2)) {
+            return $result2;
+        }
+        $result = $this->_createTree('ptgGE', $result, $result2);
+    }\r elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_EQ) \r{
+        $this->_advance();
+        $result2 = $this->_expression();
+        if ($this->isError($result2)) {
+            return $result2;
+        }
+        $result = $this->_createTree('ptgEQ', $result, $result2);
+    }\r elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_NE) \r{
+        $this->_advance();
+        $result2 = $this->_expression();
+        if ($this->isError($result2)) {
+            return $result2;
+        }
+        $result = $this->_createTree('ptgNE', $result, $result2);
+    }
+    return $result;
+}
+
+/**
+* It parses a expression. It assumes the following rule:
+* Expr -> Term [("+" | "-") Term]
+*
+* @access private
+* @return mixed The parsed ptg'd tree
+*/
+function _expression()\r {
+    // If it's a string return a string node
+    if (ereg("^\"[^\"]{0,255}\"$", $this->_current_token))\r {
+        $result = $this->_createTree($this->_current_token, '', '');
+        $this->_advance();
+        return $result;
+    }
+    $result = $this->_term();
+    if ($this->isError($result)) {
+        return $result;
+    }
+    while (($this->_current_token == SPREADSHEET_EXCEL_WRITER_ADD) or 
+           ($this->_current_token == SPREADSHEET_EXCEL_WRITER_SUB))\r {
         if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_ADD)\r \r{
-            $this->_advance();\r
-            $result2 = $this->_term();\r
-            if ($this->isError($result2)) {\r
-                return $result2;\r
-            }\r
-            $result = $this->_createTree('ptgAdd', $result, $result2);\r
-        }\r else \r{\r
-            $this->_advance();\r
-            $result2 = $this->_term();\r
-            if ($this->isError($result2)) {\r
-                return $result2;\r
-            }\r
-            $result = $this->_createTree('ptgSub', $result, $result2);\r
-        }\r
-    }\r
-    return $result;\r
-}\r
-    \r
-/**\r
-* This function just introduces a ptgParen element in the tree, so that Excel\r
-* doesn't get confused when working with a parenthesized formula afterwards.\r
-*\r
-* @access private\r
-* @see _fact()\r
-* @return mixed The parsed ptg'd tree\r
-*/\r
-function _parenthesizedExpression()\r {\r
-    $result = $this->_createTree('ptgParen', $this->_expression(), '');\r
-    return $result;\r
-}\r
-    \r
-/**\r
-* It parses a term. It assumes the following rule:\r
-* Term -> Fact [("*" | "/") Fact]\r
-*\r
-* @access private\r
-* @return mixed The parsed ptg'd tree\r
-*/\r
-function _term()\r {\r
-    $result = $this->_fact();\r
-    if ($this->isError($result)) {\r
-        return $result;\r
-    }\r
-    while (($this->_current_token == SPREADSHEET_EXCEL_WRITER_MUL) or \r
+            $this->_advance();
+            $result2 = $this->_term();
+            if ($this->isError($result2)) {
+                return $result2;
+            }
+            $result = $this->_createTree('ptgAdd', $result, $result2);
+        }\r else \r{
+            $this->_advance();
+            $result2 = $this->_term();
+            if ($this->isError($result2)) {
+                return $result2;
+            }
+            $result = $this->_createTree('ptgSub', $result, $result2);
+        }
+    }
+    return $result;
+}
+    
+/**
+* This function just introduces a ptgParen element in the tree, so that Excel
+* doesn't get confused when working with a parenthesized formula afterwards.
+*
+* @access private
+* @see _fact()
+* @return mixed The parsed ptg'd tree
+*/
+function _parenthesizedExpression()\r {
+    $result = $this->_createTree('ptgParen', $this->_expression(), '');
+    return $result;
+}
+    
+/**
+* It parses a term. It assumes the following rule:
+* Term -> Fact [("*" | "/") Fact]
+*
+* @access private
+* @return mixed The parsed ptg'd tree
+*/
+function _term()\r {
+    $result = $this->_fact();
+    if ($this->isError($result)) {
+        return $result;
+    }
+    while (($this->_current_token == SPREADSHEET_EXCEL_WRITER_MUL) or 
            ($this->_current_token == SPREADSHEET_EXCEL_WRITER_DIV)) {
         if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_MUL)\r \r{
-            $this->_advance();\r
-            $result2 = $this->_fact();\r
-            if ($this->isError($result2)) {\r
-                return $result2;\r
-            }\r
-            $result = $this->_createTree('ptgMul', $result, $result2);\r
-        }\r else \r{\r
-            $this->_advance();\r
-            $result2 = $this->_fact();\r
-            if ($this->isError($result2)) {\r
-                return $result2;\r
-            }\r
-            $result = $this->_createTree('ptgDiv', $result, $result2);\r
-        }\r
-    }\r
-    return $result;\r
-}\r
-    \r
-/**\r
-* It parses a factor. It assumes the following rule:\r
-* Fact -> ( Expr )\r
-*       | CellRef\r
-*       | CellRange\r
-*       | Number\r
-*       | Function\r
-*\r
-* @access private\r
-* @return mixed The parsed ptg'd tree\r
-*/\r
-function _fact()\r {\r
-    if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_OPEN)\r {\r
-        $this->_advance();         // eat the "("\r
-        $result = $this->_parenthesizedExpression();\r
-        if ($this->_current_token != SPREADSHEET_EXCEL_WRITER_CLOSE) {\r
-            trigger_error("')' token expected.",E_USER_ERROR);\r
-        }\r
-        $this->_advance();         // eat the ")"\r
-        return $result;\r
-    }\r if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$this->_current_token))\r {\r
-    // if it's a reference\r
-        $result = $this->_createTree($this->_current_token, '', '');\r
-        $this->_advance();\r
-        return $result;\r
-    }\r elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\![A-Ia-i]?[A-Za-z][0-9]+$/",$this->_current_token))\r {\r
-    // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1)\r
-        $result = $this->_createTree($this->_current_token, '', '');\r
-        $this->_advance();\r
-        return $result;\r
-    }\r elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$this->_current_token) or \r
-              preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$this->_current_token))\r {\r
-    // if it's a range\r
-        $result = $this->_current_token;\r
-        $this->_advance();\r
-        return $result;\r
-    }\r elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$this->_current_token))\r {\r
-    // If it's an external range (Sheet1!A1:B2)\r
-        $result = $this->_current_token;\r
-        $this->_advance();\r
-        return $result;\r
-    }\r elseif (preg_match("/^'[A-Za-z0-9_ ]+(\:[A-Za-z0-9_ ]+)?'\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$this->_current_token))\r {\r
-    // If it's an external range ('Sheet1'!A1:B2)\r
-        $result = $this->_current_token;\r
-        $this->_advance();\r
-        return $result;\r
-    }\r elseif (is_numeric($this->_current_token))\r {\r
-        $result = $this->_createTree($this->_current_token, '', '');\r
-        $this->_advance();\r
-        return $result;\r
-    }\r elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$this->_current_token))\r {\r
-    // if it's a function call\r
-        $result = $this->_func();\r
-        return $result;\r
-    }\r
-    trigger_error("Sintactic error: ".$this->_current_token.", lookahead: ".\r
-                          $this->_lookahead.", current char: ".$this->_current_char, E_USER_ERROR);\r
-}\r
-    \r
-/**\r
-* It parses a function call. It assumes the following rule:\r
-* Func -> ( Expr [,Expr]* )\r
-*\r
-* @access private\r
-*/\r
-function _func()\r {\r
-    $num_args = 0; // number of arguments received\r
-    $function = $this->_current_token;\r
-    $this->_advance();\r
-    $this->_advance();         // eat the "("\r
-    while ($this->_current_token != ')')\r {\r
-        if ($num_args > 0)\r {\r
+            $this->_advance();
+            $result2 = $this->_fact();
+            if ($this->isError($result2)) {
+                return $result2;
+            }
+            $result = $this->_createTree('ptgMul', $result, $result2);
+        }\r else \r{
+            $this->_advance();
+            $result2 = $this->_fact();
+            if ($this->isError($result2)) {
+                return $result2;
+            }
+            $result = $this->_createTree('ptgDiv', $result, $result2);
+        }
+    }
+    return $result;
+}
+    
+/**
+* It parses a factor. It assumes the following rule:
+* Fact -> ( Expr )
+*       | CellRef
+*       | CellRange
+*       | Number
+*       | Function
+*
+* @access private
+* @return mixed The parsed ptg'd tree
+*/
+function _fact()\r {
+    if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_OPEN)\r {
+        $this->_advance();         // eat the "("
+        $result = $this->_parenthesizedExpression();
+        if ($this->_current_token != SPREADSHEET_EXCEL_WRITER_CLOSE) {
+            trigger_error("')' token expected.",E_USER_ERROR);
+        }
+        $this->_advance();         // eat the ")"
+        return $result;
+    }\r if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$this->_current_token))\r {
+    // if it's a reference
+        $result = $this->_createTree($this->_current_token, '', '');
+        $this->_advance();
+        return $result;
+    }\r elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\![A-Ia-i]?[A-Za-z][0-9]+$/",$this->_current_token))\r {
+    // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1)
+        $result = $this->_createTree($this->_current_token, '', '');
+        $this->_advance();
+        return $result;
+    }\r elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$this->_current_token) or 
+              preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$this->_current_token))\r {
+    // if it's a range
+        $result = $this->_current_token;
+        $this->_advance();
+        return $result;
+    }\r elseif (preg_match("/^[A-Za-z0-9_]+(\:[A-Za-z0-9_]+)?\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$this->_current_token))\r {
+    // If it's an external range (Sheet1!A1:B2)
+        $result = $this->_current_token;
+        $this->_advance();
+        return $result;
+    }\r elseif (preg_match("/^'[A-Za-z0-9_ ]+(\:[A-Za-z0-9_ ]+)?'\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/",$this->_current_token))\r {
+    // If it's an external range ('Sheet1'!A1:B2)
+        $result = $this->_current_token;
+        $this->_advance();
+        return $result;
+    }\r elseif (is_numeric($this->_current_token))\r {
+        $result = $this->_createTree($this->_current_token, '', '');
+        $this->_advance();
+        return $result;
+    }\r elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$this->_current_token))\r {
+    // if it's a function call
+        $result = $this->_func();
+        return $result;
+    }
+    trigger_error("Sintactic error: ".$this->_current_token.", lookahead: ".
+                          $this->_lookahead.", current char: ".$this->_current_char, E_USER_ERROR);
+}
+    
+/**
+* It parses a function call. It assumes the following rule:
+* Func -> ( Expr [,Expr]* )
+*
+* @access private
+*/
+function _func()\r {
+    $num_args = 0; // number of arguments received
+    $function = $this->_current_token;
+    $this->_advance();
+    $this->_advance();         // eat the "("
+    while ($this->_current_token != ')')\r {
+        if ($num_args > 0)\r {
             if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_COMA ||
-               $this->_current_token == SPREADSHEET_EXCEL_WRITER_SCOLON) {\r
-                $this->_advance();  // eat the ","\r
-            }\r else {\r
-                trigger_error("Sintactic error: coma expected in ".\r
-                                  "function $function, {$num_args}º arg", E_USER_ERROR);\r
-            }\r
-            $result2 = $this->_condition();\r
-            if ($this->isError($result2)) {\r
-                return $result2;\r
-            }\r
-            $result = $this->_createTree('arg', $result, $result2);\r
-        }\r else { // first argument\r
-            $result2 = $this->_condition();\r
-            if ($this->isError($result2)) {\r
-                return $result2;\r
-            }\r
-            $result = $this->_createTree('arg', '', $result2);\r
-        }\r
-        $num_args++;\r
-    }\r
-    $args = $this->_functions[$function][1];\r
-    // If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid.\r
-    if (($args >= 0) and ($args != $num_args)) {\r
-        trigger_error("Incorrect number of arguments in function $function() ",E_USER_ERROR);\r
-    }\r
-\r
-    $result = $this->_createTree($function, $result, $num_args);\r
-    $this->_advance();         // eat the ")"\r
-    return $result;\r
-}\r
-    \r
-/**\r
-* Creates a tree. In fact an array which may have one or two arrays (sub-trees)\r
-* as elements.\r
-*\r
-* @access private\r
-* @param mixed $value The value of this node.\r
-* @param mixed $left  The left array (sub-tree) or a final node.\r
-* @param mixed $right The right array (sub-tree) or a final node.\r
-*/\r
-function _createTree($value, $left, $right)\r {\r
-    return(array('value' => $value, 'left' => $left, 'right' => $right));\r
-}\r
-    \r
-/**\r
-* Builds a string containing the tree in reverse polish notation (What you \r
-* would use in a HP calculator stack).\r
-* The following tree:\r
-* \r
-*    +\r
-*   / \\r
-*  2   3\r
-*\r
-* produces: "23+"\r
-*\r
-* The following tree:\r
-*\r
-*    +\r
-*   / \\r
-*  3   *\r
-*     / \\r
-*    6   A1\r
-*\r
-* produces: "36A1*+"\r
-*\r
-* In fact all operands, functions, references, etc... are written as ptg's\r
-*\r
-* @access public\r
-* @param array $tree The optional tree to convert.\r
-* @return string The tree in reverse polish notation\r
-*/\r
-function toReversePolish($tree = array())\r {\r
-    $polish = ""; // the string we are going to return\r
-    if (empty($tree)) { // If it's the first call use _parse_tree\r
-        $tree = $this->_parse_tree;\r
-    }\r
-    if (is_array($tree['left']))\r {\r
-        $converted_tree = $this->toReversePolish($tree['left']);\r
-        if ($this->isError($converted_tree)) {\r
-            return $converted_tree;\r
-        }\r
-        $polish .= $converted_tree;\r
-    }\r elseif ($tree['left'] != '') { // It's a final node\r
-        $converted_tree = $this->_convert($tree['left']);\r
-        if ($this->isError($converted_tree)) {\r
-            return $converted_tree;\r
-        }\r
-        $polish .= $converted_tree;\r
-    }\r
-    if (is_array($tree['right']))\r {\r
-        $converted_tree = $this->toReversePolish($tree['right']);\r
-        if ($this->isError($converted_tree)) {\r
-            return $converted_tree;\r
-        }\r
-        $polish .= $converted_tree;\r
-    }\r elseif ($tree['right'] != '') { // It's a final node\r
-        $converted_tree = $this->_convert($tree['right']);\r
-        if ($this->isError($converted_tree)) {\r
-            return $converted_tree;\r
-        }\r
-        $polish .= $converted_tree;\r
-    }\r
-    // if it's a function convert it here (so we can set it's arguments)\r
-    if (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/",$tree['value']) and\r
-        !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/',$tree['value']) and\r
-        !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/",$tree['value']) and\r
-        !is_numeric($tree['value']) and\r
-        !isset($this->ptg[$tree['value']]))\r {\r
-        // left subtree for a function is always an array.\r
-        if ($tree['left'] != '') {\r
-            $left_tree = $this->toReversePolish($tree['left']);\r
-        }\r else {\r
-            $left_tree = '';\r
-        }\r
-        if ($this->isError($left_tree)) {\r
-            return $left_tree;\r
-        }\r
-        // add it's left subtree and return.\r
-        return $left_tree.$this->_convertFunction($tree['value'], $tree['right']);\r
-    }\r else\r {\r
-        $converted_tree = $this->_convert($tree['value']);\r
-        if ($this->isError($converted_tree)) {\r
-            return $converted_tree;\r
-        }\r
-    }\r
-    $polish .= $converted_tree;\r
-    return $polish;\r
-}\r
+               $this->_current_token == SPREADSHEET_EXCEL_WRITER_SCOLON) {
+                $this->_advance();  // eat the ","
+            }\r else {
+                trigger_error("Sintactic error: coma expected in ".
+                                  "function $function, {$num_args}º arg", E_USER_ERROR);
+            }
+            $result2 = $this->_condition();
+            if ($this->isError($result2)) {
+                return $result2;
+            }
+            $result = $this->_createTree('arg', $result, $result2);
+        }\r else { // first argument
+            $result2 = $this->_condition();
+            if ($this->isError($result2)) {
+                return $result2;
+            }
+            $result = $this->_createTree('arg', '', $result2);
+        }
+        $num_args++;
+    }
+    $args = $this->_functions[$function][1];
+    // If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid.
+    if (($args >= 0) and ($args != $num_args)) {
+        trigger_error("Incorrect number of arguments in function $function() ",E_USER_ERROR);
+    }
 
-}\r
+    $result = $this->_createTree($function, $result, $num_args);
+    $this->_advance();         // eat the ")"
+    return $result;
+}
+    
+/**
+* Creates a tree. In fact an array which may have one or two arrays (sub-trees)
+* as elements.
+*
+* @access private
+* @param mixed $value The value of this node.
+* @param mixed $left  The left array (sub-tree) or a final node.
+* @param mixed $right The right array (sub-tree) or a final node.
+*/
+function _createTree($value, $left, $right)\r {
+    return(array('value' => $value, 'left' => $left, 'right' => $right));
+}
+    
+/**
+* Builds a string containing the tree in reverse polish notation (What you 
+* would use in a HP calculator stack).
+* The following tree:
+* 
+*    +
+*   / \
+*  2   3
+*
+* produces: "23+"
+*
+* The following tree:
+*
+*    +
+*   / \
+*  3   *
+*     / \
+*    6   A1
+*
+* produces: "36A1*+"
+*
+* In fact all operands, functions, references, etc... are written as ptg's
+*
+* @access public
+* @param array $tree The optional tree to convert.
+* @return string The tree in reverse polish notation
+*/
+function toReversePolish($tree = array())\r {
+    $polish = ""; // the string we are going to return
+    if (empty($tree)) { // If it's the first call use _parse_tree
+        $tree = $this->_parse_tree;
+    }
+    if (is_array($tree['left']))\r {
+        $converted_tree = $this->toReversePolish($tree['left']);
+        if ($this->isError($converted_tree)) {
+            return $converted_tree;
+        }
+        $polish .= $converted_tree;
+    }\r elseif ($tree['left'] != '') { // It's a final node
+        $converted_tree = $this->_convert($tree['left']);
+        if ($this->isError($converted_tree)) {
+            return $converted_tree;
+        }
+        $polish .= $converted_tree;
+    }
+    if (is_array($tree['right']))\r {
+        $converted_tree = $this->toReversePolish($tree['right']);
+        if ($this->isError($converted_tree)) {
+            return $converted_tree;
+        }
+        $polish .= $converted_tree;
+    }\r elseif ($tree['right'] != '') { // It's a final node
+        $converted_tree = $this->_convert($tree['right']);
+        if ($this->isError($converted_tree)) {
+            return $converted_tree;
+        }
+        $polish .= $converted_tree;
+    }
+    // if it's a function convert it here (so we can set it's arguments)
+    if (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/",$tree['value']) and
+        !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/',$tree['value']) and
+        !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/",$tree['value']) and
+        !is_numeric($tree['value']) and
+        !isset($this->ptg[$tree['value']]))\r {
+        // left subtree for a function is always an array.
+        if ($tree['left'] != '') {
+            $left_tree = $this->toReversePolish($tree['left']);
+        }\r else {
+            $left_tree = '';
+        }
+        if ($this->isError($left_tree)) {
+            return $left_tree;
+        }
+        // add it's left subtree and return.
+        return $left_tree.$this->_convertFunction($tree['value'], $tree['right']);
+    }\r else\r {
+        $converted_tree = $this->_convert($tree['value']);
+        if ($this->isError($converted_tree)) {
+            return $converted_tree;
+        }
+    }
+    $polish .= $converted_tree;
+    return $polish;
+}
+
+}
 
 
 ?>
index 6db3f5dbeca26412ba80dbadb5395363bbcd4b78..c949acb06566a3935058a5130197df4f54714064 100644 (file)
@@ -1638,7 +1638,7 @@ function _write_url_external() {
     if (isset($sheet)) {
         $link_type |= 0x08;
         $sheet_len  = pack("V", length($sheet) + 0x01);
-        $sheet      = join("\0", split('', $sheet));
+        $sheet      = join("\0", str_split($sheet));
         $sheet     .= "\0\0\0";
     } else {
         $sheet_len   = '';
index 748d4b9c7538cc688838daaa569cb12f9225b289..5f96b0dea1bda890c2ce83412e2cc720995bafea 100644 (file)
@@ -266,7 +266,7 @@ class aclrole extends acl
 
       /* ACL saving... */
       if (preg_match('/^acl_.*_[^xy]$/', $name) && $this->acl_is_writeable("gosaAclEntry")){
-        list($dummy, $object, $attribute, $value)= split('_', $name);
+        list($dummy, $object, $attribute, $value)= explode('_', $name);
 
         /* Skip for detection entry */
         if ($object == 'dummy') {
index 135e5198f8862b4c388563f2a30dc324b0309fb5..563be9162555e7fd1ae04c37e0cf909f1cb50cb6 100644 (file)
@@ -53,7 +53,7 @@ class filterACL {
     } else {
       foreach ($objectStorage as $oc) {
         $oc= preg_replace('/,$/', '', $oc);
-        $tmp= split(',', $oc);
+        $tmp= explode(',', $oc);
         if (count($tmp) == 1) {
           preg_match('/([^=]+)=(.*)$/', $oc, $m);
           if ($flags & GL_SUBSEARCH) {
index 062bccb0441ee89130d6cd9d6df700237c9ddf5a..94f23a194be1ed74f4a782732e89dee53b915ec5 100644 (file)
@@ -223,7 +223,7 @@ class user extends plugin
     /* Generate dateOfBirth entry */
     if (isset ($this->attrs['dateOfBirth'])){
       /* This entry is ISO 8601 conform */
-      list($year, $month, $day)= split("-", $this->attrs['dateOfBirth'][0], 3);
+      list($year, $month, $day)= explode("-", $this->attrs['dateOfBirth'][0], 3);
     
       #TODO: use $lang to convert date
       $this->dateOfBirth= "$day.$month.$year";
@@ -863,7 +863,7 @@ class user extends plugin
     if ($this->dateOfBirth != ""){
       if(!is_array($this->attrs['dateOfBirth'])) {
         #TODO: use $lang to convert date
-        list($day, $month, $year)= split("\.", $this->dateOfBirth);
+        list($day, $month, $year)= explode(".", $this->dateOfBirth);
         $this->attrs['dateOfBirth'] = sprintf("%04d-%02d-%02d", $year, $month, $day);
       }
     }
index cdf74fe9eba78991549432d0bc538c7cb9611a81..6e319d08bc6a79e5d606c90edc2634a00367fe71 100644 (file)
@@ -825,7 +825,7 @@ class posixAccount extends plugin
       $this->shadowExpire= "0";
     } else {
       /* Transform date to days since the beginning */
-      list($day, $month, $year)= split('\.', $this->shadowExpire, 3);
+      list($day, $month, $year)= explode('.', $this->shadowExpire, 3);
       $this->shadowExpire= (int)(mktime(0, 0, 0, $month, $day, $year)/ (60 * 60 * 24)) ;
     }
     if (!$this->activate_shadowMax){
index 2b7630a11bd96b23f61edc70f8060ebccb5e28c3..eee96634b8a0a00639d281b519b2c7445f3e615b 100644 (file)
@@ -921,10 +921,10 @@ class Step_Migrate extends setup_step
         $acls = $attrs['gosaAclEntry'];
         for($i = 0 ; $i < $acls['count'] ; $i++){
           $acl = $acls[$i];
-          $tmp = split(":",$acl);
+          $tmp = explode(":",$acl);
 
           if($tmp[1] == "psub"){
-            $members = split(",",$tmp[2]);
+            $members = explode(",",$tmp[2]);
             foreach($members as $member){
               $member = base64_decode($member);
               if(isset($users[$member])){
@@ -965,7 +965,7 @@ class Step_Migrate extends setup_step
                 $a_str = $ret['gosaAclTemplate'][$e];
                 if(preg_match("/^[0-9]*:psub:/",$a_str) && preg_match("/:all;cmdrw$/",$a_str)){
 
-                  $members = split(",",$tmp[3]);
+                  $members = explode(",",$tmp[3]);
                   foreach($members as $member){
                     $member = base64_decode($member);
 
@@ -2902,7 +2902,7 @@ class Step_Migrate extends setup_step
        */ 
       $release = "";
       $r = $info['FAIrelease'][0];
-      $z = split("/",$r);
+      $z = explode("/",$r);
       foreach($z as $part){
 
         if(!empty($part)){