<?php
/*
  www.oscGold.com (C) Kamelia-Net Jacek Krysiak
  modul oscGold wer 4.0
*/

function split_define_string($row){
	global $string_data;
	$string_array = array();

	$string_array['variable'] = '';
	$string_array['text'] = '';

	$comma_location = stripos($row,",");

	$string_array['variable'] = substr($row,0,$comma_location);
	$number_of_characters = strlen($row) - comma_location+1;
	$string_array['text'] = substr($row,$comma_location+1,$number_of_characters);

	$string_array['variable'] = process_data($string_array['variable']);
	$string_array['text'] = process_data($string_array['text']);

	return $string_array;
}

function get_ws_from_fs_directory($current_path,$fs_path){
	global $image_directory;
	$length_fs = strlen($fs_path);
	//echo "image dir:".$image_directory;
	$ws_path = substr($current_path,$length_fs);
	$ws_path = $image_directory.$ws_path;

	//echo $ws_path."<br><br>";

	return $ws_path;
}

/* The below function will list all folders and files within a directory
It is a recursive function that uses a global array.  The global array was the easiest
way for me to work with an array in a recursive function
*This function has no limit on the number of levels down you can search.
*The array structure was one that worked for me.
ARGUMENTS:
$startdir => specify the directory to start from; format: must end in a "/"
$searchSubdirs => True/false; True if you want to search subdirectories
$directoriesonly => True/false; True if you want to only return directories
$maxlevel => "all" or a number; specifes the number of directories down that you want to search
$level => integer; directory level that the function is currently searching
*/
function filelist ($filename='',$startdir="./", $searchSubdirs=1, $directoriesonly=0, $maxlevel="all", $level=1,$file_ext=array(),$language_folder='') {
	global $language_folder;
	//list the directory/file names that you want to ignore
    $ignoredDirectory[] = ".";
    $ignoredDirectory[] = "..";
    $ignoredDirectory[] = "CVS";
    $ignoredDirectory[] = "help";
    $ignoredDirectory[] = ".svn";
    global $directorylist;    //initialize global array
    if (is_dir($startdir)) {
        if ($dh = opendir($startdir)) {
            while (($file = readdir($dh)) !== false) {
                if (!(array_search($file,$ignoredDirectory) > -1)) {
                	if (filetype($startdir ."/". $file) == "dir") {
                       //build your directory array however you choose;
                       //add other file details that you want.
                	   if($level == 1){
                       		$language_folder = $file;
                       }
                       $directorylist[$startdir . $file]['level'] = $level;
                       $directorylist[$startdir . $file]['dir'] = 1;
                       $directorylist[$startdir . $file]['name'] = $file;
                       $directorylist[$startdir . $file]['path'] = $startdir;
                       $directorylist[$startdir . $file]['language'] = $language_folder;

                       if ($searchSubdirs) {
                           if ((($maxlevel) == "all") || ($maxlevel > $level)) {
                               filelist($filename,$startdir . $file . "/", $searchSubdirs, $directoriesonly, $maxlevel, $level + 1, $file_ext, $language_folder);
                           }
                       }
                   } else {
                       	$extension = findexts($file);
                       	$good_extension = (in_array($extension,$file_ext))? true : false;

                   		if ((!$directoriesonly) && (($good_extension) || (count($file_ext) == 0)) && (($filename=='') || ($filename == $file))) {
                           //if you want to include files; build your file array
                           //however you choose; add other file details that you want.

	                         $directorylist[$startdir . $file]['level'] = $level;
	                         $directorylist[$startdir . $file]['dir'] = 0;
	                         $directorylist[$startdir . $file]['name'] = $file;
	                         $directorylist[$startdir . $file]['path'] = $startdir;
	                         $directorylist[$startdir . $file]['type'] = $extension;
	                         $directorylist[$startdir . $file]['language'] = $language_folder;
	                         if ($extension == 'php') {
	                         	 $directorylist[$startdir . $file]['fields'] = fields_array($startdir.$file);
	                         }

      }}}}
           closedir($dh);
}}
return($directorylist);
}


function fields_array($file){
	$field_name_array = array();
	$trim_array = array("'",'"');

	$file_contents = file_get_contents($file);

	$rows = getStrsBetween($file_contents,'define(',");");
	//echo $list['language']."<br>";
	foreach ($rows as $field_names){
		$string_array = split_define_string($field_names);
		$field_name_array[$string_array['variable']] = $string_array['text'];
	}


	return $field_name_array;
}

function findexts ($filename){
	$filename = strtolower($filename) ;
	$exts = split("[/\\.]", $filename) ;
	$n = count($exts)-1;
	$exts = $exts[$n];
	return $exts;
}

function find_language_folders ($foldername){
	$foldername = strtolower($foldername) ;
	$exts = split("[/\\.]", $filename) ;
	$n = count($exts)-1;
	$exts = $exts[$n];
	return $exts;
}

function fieldlist($files){
	$field_name_array = array();
	$trim_array = array("'",'"');
	foreach ($files as $list) {
		if (($list['dir'] == 0) && ($list['type']=='php')) {
			//echo "Directory: " . $list['dir'] . " => Level: " . $list['level'] . " => Language: " . $list['language'] . " => Name: " . $list['name'] . " => Path: " . $list['path'] ." => Type: " . $list['type'] ."<br>";
			$file_contents = file_get_contents($list['path'].$list['name']);

			$rows = getStrsBetween($file_contents,'define(',");");

			foreach ($rows as $field_names){

				$string_array = split_define_string($field_names);

				$field_name_array[$string_array['variable']][$list['language']]['text'] = $string_array['text'];
				$field_name_array[$string_array['variable']][$list['language']]['path'] = $list['path'];

			}
		}
	}
	return $field_name_array;
}

function getStrsBetween($s,$s1,$s2=false,$offset=0) {
    /*====================================================================
    Function to scan a string for items encapsulated within a pair of tags

    getStrsBetween(string, tag1, <tag2>, <offset>

    If no second tag is specified, then match between identical tags

    Returns an array indexed with the encapsulated text, which is in turn
    a sub-array, containing the position of each item.

    Notes:
    strpos($needle,$haystack,$offset)
    substr($string,$start,$length)

    ====================================================================*/

    if( $s2 === false ) { $s2 = $s1; }
    $result = array();
    $users = array();
    $L1 = strlen($s1);
    $L2 = strlen($s2);

    if( $L1==0 || $L2==0 ) {
        return false;
    }

    do {
        $pos1 = strpos($s,$s1,$offset);

        if( $pos1 !== false ) {
            $pos1 += $L1;

            $pos2 = strpos($s,$s2,$pos1);

            if( $pos2 !== false ) {
                $key_len = $pos2 - $pos1;

                $this_key = substr($s,$pos1,$key_len);

				array_push($users, $this_key);

                if( !array_key_exists($this_key,$result) ) {
                    $result[$this_key] = array();
                }

                $result[$this_key][] = $pos1;

                $offset = $pos2 + $L2;
            } else {
                $pos1 = false;
            }
        }
    } while($pos1 !== false );

	$result = array_unique($users);

    return $result;
}
function full_copy($source,$target){
        if (is_dir($source)){
        	@mkdir($target);

            $d = dir($source);

            while (FALSE !== ($entry = $d->read())){
                if ( $entry == '.' || $entry == '..' ){
                    continue;
                }

                $Entry = $source . '/' . $entry;
                if ( is_dir( $Entry ) ){
                    full_copy( $Entry, $target . '/' . $entry );
                    continue;
                }
                copy( $Entry, $target . '/' . $entry );
            }
            $d->close();
        }else {
            copy($source, $target);
        }
}



/*
This file moves the function from the edit_textdata.php to one central location
for use by a series of edit files.
*/

function phppage2readeable($t){

 return str_replace(" ", "&nbsp;",preg_replace("/\.php$/", "", str_replace("_", "&nbsp;", $t)));
}
// ---- end


function getFromQuery ($var)
{
    $query = $_SERVER['QUERY_STRING'];

    $string = $var . "=";

    $idx = strpos ($query, $string);
    if ($idx === false)
    {
        return ("");
    }

    $string = substr ($query, $idx);
    $idx = strpos ($string, "=");
    $string = substr ($string, $idx + 1);
    $idx = strpos ($string, "&");
    if ($idx === false)
    {
    }
    else
    {
        $string = substr ($string, 0, $idx);
    }

    $string = urldecode ($string);

    return ($string);
}

// all this crap about seperating GET from POST variables is stupid
// this function will return first from put if available otherwise
// from get

function getVAR ($var)
{
    global $_GET;
    global $_POST;

    if (strlen ($_POST[$var]) > 0)
    {
        return ($_POST[$var]);
    }

    return ($_GET[$var]);
}

// ok now strip off any carriage returns and line feeds

function strip_crlf ($data)
{
    $len = strlen ($data);
    for ($i = 0; $i < $len; ++$i)
    {
        $cc = substr ($data, $i, 1);
        $cc1 = substr ($data, $i + 1, 1);

        if ((ord ($cc) == 10) ||  // a new line char
            (ord ($cc) == 13)     // a carriage return
           )
        {
            $data = substr ($data, 0, $i);
            break;
        }
    }

    return ($data);
}

function getFiles ($dir1)
{
    global $languages_array;
    global $PHP_SELF;

   $dir1 = dir($fs_dir);
    if ($dir1)
    {
        $file_extension = substr($PHP_SELF, strrpos($PHP_SELF, '.'));
        while ($file = $dir1->read())
        {
            if (substr($file, strrpos($file, '.')) == $file_extension)
            {
                $data [$idx++] = $file;
            }
        }
        $dir1->close();
    }

    return ($data);
}

// this looks for all the files that we may want to edit

function listFiles ($dir)
{
    global $filetype1, $PHP_SELF;
 if ($dir)
    {
        $file_extension = '.php';
        $d = dir($dir);
        while ($file = $d->read()){
         $file_array[$file]=$file;

//  asort($file_array, SORT_REGULAR );
  foreach ( $file_array as $file){
          while (false !== ($entry = $d->read())) {
          // echo $entry."<br> \n";
          // echo substr($entry, strrpos($entry, '.'));
       if (substr($entry, strrpos($entry, '.')) == $file_extension){

       echo '<tr><td class="smallText">' . ' <a href="' . tep_href_link(FILENAME_EDIT_TEXT, '&action=edit&filename=' . $entry) . '" title="' . $entry . '">' . ($entry) . '</a></td></tr>' . "\n";
                  }
              }
           }
        }
        $d->close();
    }
}

function listFiles1 ($dir)
{
    global $filetype1, $PHP_SELF;
 if ($dir)
    {
        $file_extension = '.php';
        $d = dir($dir);
        while ($file = $d->read()){
         $file_array[$file]=$file;

//  asort($file_array, SORT_REGULAR );
  foreach ( $file_array as $file){
          while (false !== ($entry = $d->read())) {
          // echo $entry."<br> \n";
          // echo substr($entry, strrpos($entry, '.'));
       if (substr($entry, strrpos($entry, '.')) == $file_extension){

       echo '<tr><td class="smallText">' . ' <a href="' . tep_href_link(FILENAME_EDIT_TEXT, '&action=edit&filename=' . $entry) . '" title="' . $entry . '">' . ($entry) . '</a></td></tr>' . "\n";
                  }
              }
           }
        }
        $d->close();
    }
}
// These functions perform character reads for the file parser
//
// The parser will depend on reading one character at a time, so the
// 2 routines getChar and readLine work together, getChar calls readLine
// noone else does.
//
// read the next line in, to feed the getChar routine

function readLine ()
{
    global $file_data;

    // if we have reached the end of file, mark it as so

    if (feof ($file_data ['handle']))
    {
        // We have reached the end of the file

        $file_data ['eof'] = 1;
        return;
    }

    // actually read in a line

    $data = fgets ($file_data ['handle']);

    // ok now strip off any carriage returns and line feeds and
    // double comment slashes

    $len = strlen ($data);
    for ($i = 0; $i < $len; ++$i)
    {
        $cc = substr ($data, $i, 1);
        $cc1 = substr ($data, $i + 1, 1);
    $cc0 = substr ($data, $i - 1, 1);

        if ((ord ($cc) == 10) ||  // a new line char
            (ord ($cc) == 13) ||  // a carriage return
            (
                ($cc  == '/' &&
                 $cc1 == '/' &&
         $cc0!=":" // not a link
         )
            )
           )
        {
            $data = substr ($data, 0, $i);
            break;
        }
    }

    // ok we have a clean line

    $file_data ['data'] = $data;
    $file_data ['len']  = strlen ($data);
    $file_data ['idx']  = 0;
    $file_data ['line'] ++;

    if ($file_data['len'] == 0)
    {
        // recursively skip blank lines
        return (readLine ());
    }

    return;
}

function getChar ()
{
    global $file_data;

    // if we have exhausted our characters then read a new line in

    if ($file_data ['idx'] >= $file_data ['len'])
    {
        readLine ();
        if ($file_data ['eof'] == 1)
            return;

        // mark that we have transitioned over an end of line
        $file_data ['eol'] = 1;
    }
    else
        $file_data ['eol'] = 0;

    // ok save the last character, to check for escaped chars and such

    $file_data ['last'] = $file_data ['current'];

    // EOL cancels a back slash escape
    if ($file_data ['eol'] == 1)
        $file_data ['last'] = 0;

    $file_data ['current'] = substr ($file_data ['data'],
        $file_data ['idx'], 1);
    $file_data ['idx'] ++;
}


// process_data, cleans up certain cases.  Typically the define
// is pretty straightforward: define ('ABC', 'DEF');
//
// in that case we just need to strip off the surrounding
// quotes, but here are some pathological cases
//
// define ('ABC', 'DEF' . 'GHI');
// define ('ABC', TEP_STUFF . 'DEF');
//
// This routine checks to see if we should remove the
// quotes or not, in the first case yes, in the other cases
// no.
//
// look for the special cases where the entire string is quoted
// also trim whitespace off of end

function process_data ($data)
{
	$data = trim ($data);

    $cc = substr ($data, 0, 1);
    $end = strlen ($data) - 1;
    $cc1 = substr ($data, $end, 1);

    // check to see if the first and last characters are quotes

    if (!strcmp ($cc, $cc1) &&
        (!strcmp ($cc, '"') ||
         !strcmp ($cc, "'")))
    {
        // ok check to see if we get dequoted somewhere in between

        $len = strlen ($data) - 1; // we dont want to check last char
        for ($i = 1; $i < $len; ++$i)
        {
            $cc1 = substr ($data, $i, 1);
            $cc2 = substr ($data, $i - 1, 1);
            if (!strcmp ($cc, $cc1) &&
                strcmp ($cc2, '\\'))
            {
                // ok we were dequoted
                // just return the data as is
                //
                // we do not remove the quotes in this case

                return ($data);
            }
        }

        // ok we were not dequoted, therefore strip the quotes

        $data = substr ($data, 1, $len - 1);
    }
    //echo "Data".$data."<br>";

    return ($data);
}

// We will create a state machine driven parser

function parseFile ($this_filename)
{
  // returns $num_defines
    global $file_data;
    global $defines;

    $fh = fopen ($this_filename, "rb");

    $file_data ['handle'] = $fh;
    $file_data ['filename'] = $this_filename;
    $file_data ['line'] = 0;
    $file_data ['eof'] = 0;
    $file_data ['len'] = 0;
    $file_data ['idx'] = 0;
    $file_data ['last'] = 0;

    // Create the state table

    // read the define portion
    $state [0] = array ( 'string' => "define('",
                         'eatall' => 0,
                         'data' => '',
                         'sidx' => 0);

    // save all data upto the apostrophe
    $state [1] = array ( 'string' => "'",
                         'eatall' => 1,
                         'data' => '',
                         'sidx' => 0);

    // read till the comma
    $state [2] = array ( 'string' => ",",
                         'eatall' => 0,
                         'data' => '',
                         'sidx' => 0);

    // State's 3 and 4 are too complex to anaylze in the normal way
    //
    // In state 3 we will read until we find the first non-whitespace
    //
    // In state 4 we will read and eat until we find an unquoted, unescaped
    // close paren.
    //
    // Then we will determine what to do about the quotes and such
    //

    // read till the first non-whitespace
    $state [3] = array ( 'string' => "",
                         'eatall' => 0,
                         'data' => '',
                         'sidx' => 0);

    // eat until we find a close paren
    $state [4] = array ( 'string' => "",
                         'eatall' => 1,
                         'data' => '',
                         'sidx' => 0);

    // After state's 3 and 4 we need to find the closing semi colon

    // read till the semicolon
    $state [5] = array ( 'string' => ";",
                         'eatall' => 0,
                         'data' => '',
                         'sidx' => 0);

    $the_state = 0;
    $num_defines = 0;

    // keep reading characters till we reach the end of file

    while ($file_data ['eof'] == 0)
    {
        // get the next character

        getChar ();

        $cc = $file_data ['current'];
        $cc1 = $file_data ['last'];

        //echo "cc ".$cc." cc1 ".$cc1."<br><br> The State:".$state [$the_state]['sidx']."<br><br>";
        // we ignore white space, unless we are in the eatall states

        if (!$eatall &&
            ($cc == ' ' || $cc == '\t'))
        {
            continue;
        }

        $idx = $state [$the_state]['sidx'];
        $schar = substr ($state [$the_state]['string'], $idx, 1);
        $eatall = $state [$the_state]['eatall'];

        // a special case when state is 3 and 4
        // in state 3 we read until we find a non-whitespace

        if ($the_state == 3)
        {
            if (strcmp ($cc, " ") &&
                strcmp ($cc, "\t"))
            {
                // ok when we get to a non-white space let's
                // transition to state 4

                $state [$the_state]['sidx'] = 0;
                $the_state ++;

                $in_quote = 0;
                $quote_type = "'";
                $dequoted = 0;

                if (!strcmp ($cc, "'") ||
                    !strcmp ($cc, '"'))
                {
                    $in_quote = 1;
                    $quote_type = $cc;
                }

                // put this character into the new state data

                $state[$the_state]['data'] = $cc;
            }

            continue;
        }

        // in state 4 we eat until we find an unquoted, unescaped
        // paren

        if ($the_state == 4)
        {
            if ($cc == ')' &&
                $cc1 != '\\' &&
                $in_quote == 0)
            {
                // we have completed state 4
                // call process_data to determine if we should
                // remove the starting and ending quotes if they
                // exist

                $state [$the_state]['data'] = process_data (
                    $state [$the_state]['data']);

                $state [$the_state]['sidx'] = 0;

                $the_state++;

                continue;
            }

            // ok we need to check our quote status

            if ($in_quote == 1 &&
                !strcmp ($cc, $quote_type) &&
                strcmp ($cc1, "\\")) // make sure not escaped
            {
                // ok we have been dequoted

                $dequote = 1;
                $in_quote = 0;

                // if we pass an eol, append a newline

                if ($file_data ['eol'] == 1)
                    $state [$the_state]['data'] .= "\n";

                // save the quote

                $state [$the_state]['data'] .= $cc;

                continue;
            }

            // ok are we being quoted

            if ($in_quote == 0 &&
                (!strcmp ($cc, '"') ||
                 !strcmp ($cc, "'") ||
                 !strcmp ($cc, '('))) // consider nonquoted, nonescaped
                                      // interior parens as quotes
            {
                // ok we are quoted again

                $in_quote = 1;
                $quote_type = $cc;

                // if we are quoted by parens, change the quote type
                // to be the close paren, to make the if statement
                // easier

                if (!strcmp ($cc, '('))
                    $quote_type = ')';
            }

            // if we pass an eol, append a newline

            if ($file_data ['eol'] == 1)
            {
                $state [$the_state]['data'] .= "\n";
            }

            // eat the character
            $state [$the_state]['data'] .= $cc;
            continue;
        }

        // normal states are here

        // eatall == 1, means we eat all characters till the one
        // in we are looking for, otherwise we skip characters till
        // we find the character

        if ($eatall == 0)
        {
            // ok we failed to finish the state machine,
            // we will restart the state machine

            if (strcmp ($cc, $schar))
            {
                // reset the states
                for ($i = 0; $i < 7; ++$i)
                {
                    $state [$i]['sidx'] = 0;
                    $state [$i]['data'] = '';
                }

                $the_state = 0;

                continue;
            }
        }
        else
        {
            if (strcmp ($cc, $schar) ||
                !strcmp ($cc1, '\\'))
            {
                // ok we eatall till we find our char

                if ($file_data ['eol'] == 1)
                    $state [$the_state]['data'] .= "\n";
                $state [$the_state]['data'] .= $cc;

                continue;
            }
        }

        // ok advance the state

        $len = strlen ($state [$the_state]['string']);
        $sidx = $state [$the_state]['sidx'];
        $sidx ++;
        $state [$the_state]['sidx'] = $sidx;

        // only use this code on a non eatall

        if ($eatall == 0)
        {
            if ($file_data ['eol'] == 1)
                $state [$the_state]['data'] .= "\n";
            $state [$the_state]['data'] .= $cc;
        }

        // special case when we find the d in define

        if ($the_state == 0 && $sidx == 1)
        {
            // we have found the first character
            //
            // I want to store the starting and ending line numbers
            // so that when we rebuild the file, it will make the
            // assembly much easier.
            //

            $start_line = $file_data ['line'];
        }

        // check to see if we can advance the state

        if ($sidx >= $len)
        {
            // advance the state

            $state [$the_state]['sidx'] = 0;
            $the_state ++;

            if ($the_state == 6)
            {
                // bingo we have found a complete define statement

                $end_line = $file_data ['line'];

                // before assembly, we need to see if we can handle this data

                if ( preg_match( "/'\s*.\s*\w+\s*.\s*'/", $state[4]['data'], $pattern_match) ) $data_disable = true;
                else $data_disable = false;

                // ok assemble an array

                $this_define =
                    array (
                        'name'       => $state [1]['data'],
                        'data'       => $state [4]['data'],
                        'start_line' => $start_line,
                        'end_line'   => $end_line,
                        'disable'    => $data_disable);

                // now save this

                $defines [$num_defines] = $this_define;
                $num_defines++;

                // reset the states
                for ($i = 0; $i < 7; ++$i)
                {
                    $state [$i]['sidx'] = 0;
                    $state [$i]['data'] = '';
                }

                $the_state = 0;
            }
        }
    }
    // ok we are done with the file

    fclose ($file_data ['handle']);
  return $num_defines;
}

function parseFileData($this_filename){

	// returns $num_defines
    global $file_data;
    global $defines;

    $fh = fopen ($this_filename, "rb");

    $file_data ['handle'] = $fh;
    $file_data ['filename'] = $this_filename;
    $file_data ['line'] = 0;
    $file_data ['eof'] = 0;
    $file_data ['len'] = 0;
    $file_data ['idx'] = 0;
    $file_data ['last'] = 0;

    // Create the state table

    // read the define portion
    $state [0] = array ( 'string' => "define('",
                         'eatall' => 0,
                         'data' => '',
                         'sidx' => 0);

    // save all data upto the apostrophe
    $state [1] = array ( 'string' => "'",
                         'eatall' => 1,
                         'data' => '',
                         'sidx' => 0);

    // read till the comma
    $state [2] = array ( 'string' => ",",
                         'eatall' => 0,
                         'data' => '',
                         'sidx' => 0);

    // State's 3 and 4 are too complex to anaylze in the normal way
    //
    // In state 3 we will read until we find the first non-whitespace
    //
    // In state 4 we will read and eat until we find an unquoted, unescaped
    // close paren.
    //
    // Then we will determine what to do about the quotes and such
    //

    // read till the first non-whitespace
    $state [3] = array ( 'string' => "",
                         'eatall' => 0,
                         'data' => '',
                         'sidx' => 0);

    // eat until we find a close paren
    $state [4] = array ( 'string' => "",
                         'eatall' => 1,
                         'data' => '',
                         'sidx' => 0);

    // After state's 3 and 4 we need to find the closing semi colon

    // read till the semicolon
    $state [5] = array ( 'string' => ";",
                         'eatall' => 0,
                         'data' => '',
                         'sidx' => 0);

    $the_state = 0;
    $num_defines = 0;

    // keep reading characters till we reach the end of file

    while ($file_data ['eof'] == 0)
    {
        // get the next character

        getChar ();

        $cc = $file_data ['current'];
        $cc1 = $file_data ['last'];

        // we ignore white space, unless we are in the eatall states

        if (!$eatall &&
            ($cc == ' ' || $cc == '\t'))
        {
            continue;
        }

        $idx = $state [$the_state]['sidx'];
        $schar = substr ($state [$the_state]['string'], $idx, 1);
        $eatall = $state [$the_state]['eatall'];

        // a special case when state is 3 and 4
        // in state 3 we read until we find a non-whitespace

        if ($the_state == 3)
        {
            if (strcmp ($cc, " ") &&
                strcmp ($cc, "\t"))
            {
                // ok when we get to a non-white space let's
                // transition to state 4

                $state [$the_state]['sidx'] = 0;
                $the_state ++;

                $in_quote = 0;
                $quote_type = "'";
                $dequoted = 0;

                if (!strcmp ($cc, "'") ||
                    !strcmp ($cc, '"'))
                {
                    $in_quote = 1;
                    $quote_type = $cc;
                }

                // put this character into the new state data

                $state[$the_state]['data'] = $cc;
            }

            continue;
        }

        // in state 4 we eat until we find an unquoted, unescaped
        // paren

        if ($the_state == 4)
        {
            if ($cc == ')' &&
                $cc1 != '\\' &&
                $in_quote == 0)
            {
                // we have completed state 4
                // call process_data to determine if we should
                // remove the starting and ending quotes if they
                // exist

                $state [$the_state]['data'] = process_data (
                    $state [$the_state]['data']);

                $state [$the_state]['sidx'] = 0;

                $the_state++;

                continue;
            }

            // ok we need to check our quote status

            if ($in_quote == 1 &&
                !strcmp ($cc, $quote_type) &&
                strcmp ($cc1, "\\")) // make sure not escaped
            {
                // ok we have been dequoted

                $dequote = 1;
                $in_quote = 0;

                // if we pass an eol, append a newline

                if ($file_data ['eol'] == 1)
                    $state [$the_state]['data'] .= "\n";

                // save the quote

                $state [$the_state]['data'] .= $cc;

                continue;
            }

            // ok are we being quoted

            if ($in_quote == 0 &&
                (!strcmp ($cc, '"') ||
                 !strcmp ($cc, "'") ||
                 !strcmp ($cc, '('))) // consider nonquoted, nonescaped
                                      // interior parens as quotes
            {
                // ok we are quoted again

                $in_quote = 1;
                $quote_type = $cc;

                // if we are quoted by parens, change the quote type
                // to be the close paren, to make the if statement
                // easier

                if (!strcmp ($cc, '('))
                    $quote_type = ')';
            }

            // if we pass an eol, append a newline

            if ($file_data ['eol'] == 1)
            {
                $state [$the_state]['data'] .= "\n";
            }

            // eat the character
            $state [$the_state]['data'] .= $cc;
            continue;
        }

        // normal states are here

        // eatall == 1, means we eat all characters till the one
        // in we are looking for, otherwise we skip characters till
        // we find the character

        if ($eatall == 0)
        {
            // ok we failed to finish the state machine,
            // we will restart the state machine

            if (strcmp ($cc, $schar))
            {
                // reset the states
                for ($i = 0; $i < 7; ++$i)
                {
                    $state [$i]['sidx'] = 0;
                    $state [$i]['data'] = '';
                }

                $the_state = 0;

                continue;
            }
        }
        else
        {
            if (strcmp ($cc, $schar) ||
                !strcmp ($cc1, '\\'))
            {
                // ok we eatall till we find our char

                if ($file_data ['eol'] == 1)
                    $state [$the_state]['data'] .= "\n";
                $state [$the_state]['data'] .= $cc;

                continue;
            }
        }

        // ok advance the state

        $len = strlen ($state [$the_state]['string']);
        $sidx = $state [$the_state]['sidx'];
        $sidx ++;
        $state [$the_state]['sidx'] = $sidx;

        // only use this code on a non eatall

        if ($eatall == 0)
        {
            if ($file_data ['eol'] == 1)
                $state [$the_state]['data'] .= "\n";
            $state [$the_state]['data'] .= $cc;
        }

        // special case when we find the d in define

        if ($the_state == 0 && $sidx == 1)
        {
            // we have found the first character
            //
            // I want to store the starting and ending line numbers
            // so that when we rebuild the file, it will make the
            // assembly much easier.
            //

            $start_line = $file_data ['line'];
        }

        // check to see if we can advance the state

        if ($sidx >= $len)
        {
            // advance the state

            $state [$the_state]['sidx'] = 0;
            $the_state ++;

            if ($the_state == 6)
            {
                // bingo we have found a complete define statement

                $end_line = $file_data ['line'];

                // ok assemble an array

                $this_define =
                    array (
                        'name'       => $state [1]['data'],
                        'data'       => $state [4]['data'],
                        'start_line' => $start_line,
                        'end_line'   => $end_line);

                // now save this

                $defines [$num_defines] = $this_define;
                $num_defines++;

                // reset the states
                for ($i = 0; $i < 7; ++$i)
                {
                    $state [$i]['sidx'] = 0;
                    $state [$i]['data'] = '';
                }

                $the_state = 0;
            }
        }
    }

    // ok we are done with the file

    fclose ($file_data ['handle']);
  //return $num_defines;
  print_r($state);
  return $this_define['data'] ;
}
?>