#!/usr/bin/env bash
#  ____         ____
# | __ )  __ _ / ___|___  _ __
# |  _ \ / _` | |   / _ \| '_ \
# | |_) | (_| | |__| (_) | | | |   --= A Shell BASIC-to-C converter =--
# |____/ \__,_|\____\___/|_| |_|
#
# Peter van Eerten - March 2009/December 2015. License: MIT License (Expat).
#
#---------------------------------------------------------------------------------------------------------------------
# CREDITS to all people of the BaCon forum. Without them BaCon would not be as it is now.
#---------------------------------------------------------------------------------------------------------------------
#
# This script should work with the following shells:
#
#   - Bourne Again Shell (BASH) 3.2 or higher
#   - AT&T Kornshell 93
#   - Public Doman Korn Shell (PDKSH)
#   - MirBSD Korn Shell (MKSH)
#   - ZShell (ZSH) 4.x or higher
#
#---------------------------------------------------------------------------------------------------------------------
# GLOBAL INITIALIZATIONS
#---------------------------------------------------------------------------------------------------------------------

# Are we using BASH?
if [[ -n $BASH ]]
then
    if [[ ${BASH_VERSINFO[0]}$((${BASH_VERSINFO[1]}+0)) -lt 32 ]]
    then
        echo "System error: this is BASH version ${BASH_VERSION}. BaCon needs BASH 3.2 or higher to run!"
        exit 1
    fi
    # Set the extended globbing option in BASH
    shopt -s extglob
fi
if [[ -z $BASH ]]
then
    # Check Kornshell version
    if [[ ${KSH_VERSION} = +(* 93*) ]]
    then
        alias echo="print -r"
        ulimit -s unlimited
    else
        alias echo="print -R"
    fi

    # If run with Zshell then emulate KSH
    if [[ -n $ZSH_NAME ]]
    then
        if [[ ${ZSH_VERSION%%.*} -lt 4 ]]
        then
	    echo "System error: this is ZShell version ${ZSH_VERSION}. BaCon needs ZShell 4.x or higher to run!"
	    exit 1
        else
	    emulate ksh
        fi
    fi
fi

# Unset grep options
unset GREP_OPTIONS

# Version of BACON
typeset -rx g_VERSION="3.2.2"

# Our numerical environment is POSIX
export LC_NUMERIC="POSIX"

# Find coretools
if [[ -z `which cat` || -z `which rm` || -z `which tr` || -z `which touch` || -z `which uname` || -z `which head` || -z `which pwd` ]]
then
    echo "System error: 'cat', 'rm', 'tr', 'touch', 'uname', 'head' or 'pwd' not found on this system!"
    exit 1
fi

# Link flags
g_LDFLAGS="-lbacon -lm"

# Solaris
if [[ `uname` = +(*SunOS*) ]]
then
    g_LDFLAGS="$g_LDFLAGS -lnsl -lsocket"
fi

# Global constant for miniparsing
typeset -rx g_PARSEVAR=`echo -e "\001"`

# Global to define '$', '%' and '#'-replacement
typeset -rx g_STRINGSIGN="__b2c__string_var"
typeset -rx g_LONGSIGN="__b2c__long_var"
typeset -rx g_FLOATSIGN="__b2c__float_var"

# Global to define '"'-symbol
typeset -rx g_DQUOTESIGN=`echo -e "\042"`

# Global to define '''-symbol
typeset -rx g_SQUOTESIGN=`echo -e "\047"`

# Global to define CRLF combination
typeset -rx g_CRLF=`echo -e "\015\012"`

# Global to define TAB
typeset -rx g_TAB=`echo -e "\011"`

# Remember the original field separator
typeset -rx g_ORGIFS="${IFS}"

#-------------------------------------------------------$1 = variable name, $2 = function name

function Get_Var
{
    typeset VAR RECORD

    # In case of array assignments: exit
    if [[ ${1} = +(*\{*) || $(echo ${1}) = +(* *) ]]
    then
        return
    fi

    # Get rid of assignment notation
    if [[ ${1} = +(*\=*) ]]
    then
        VAR=$(echo ${1%%=*})
    else
        VAR=$(echo ${1})
    fi

    # Get rid of '*' sign in variable name
    VAR=${VAR//\*/}

    # Get rid of '&' sign in variable name
    VAR=${VAR//&/}

    # Get rid of recordname 
    if [[ ${VAR} = +(*.*) ]]
    then
        RECORD=${VAR%%.*}
        VAR=${VAR##*.}
    else
        RECORD=${g_RECORDVAR}
    fi
    RECORD=${RECORD%%\[*}

    # Get rid of array notation
    if [[ ${VAR} = +(*\[*) ]]
    then
        VAR=${VAR%%\[*}
    fi

    # Get rid of brackets in case of function pointer or assoc var
    if [[ ${VAR} = +(*\(*) ]]
    then
        VAR=$(echo ${VAR%%\(*})
    fi

    # Get rid of $ sign
    if [[ $VAR = +(*\$*) ]]
    then
        VAR=${VAR//\$/$g_STRINGSIGN}
    elif [[ $VAR = +(*#*) ]]
    then
        VAR=${VAR//#/$g_FLOATSIGN}
    elif [[ $VAR = +(*%*) ]]
    then
        VAR=${VAR//%/$g_LONGSIGN}
    fi

    # If plain text, skip. Also skip '}' to avoid eval clash.
    if [[ "${VAR%%\(*}" != +(*${g_DQUOTESIGN}*) && "${VAR%%\(*}" != +(*\}*) ]]
    then
        # Always lookup type in MAIN
        eval echo '${hash_'"${RECORD}${VAR}"'}'

        # Lookup type in function if given
        if [[ -n ${2} && ${2} = +(*[a-zA-Z0-9_.]*) ]]
        then
            eval echo '${hash_'"${RECORD}${VAR}___${2}"'}'
        fi
    fi
}

function Save_Main_Var
{
    typeset STR TYPE NR

    # Make sure the asterisk is attached to type
    if [[ ${1} = +(\**) ]]
    then
        STR=$(echo ${1//\*/})
        let NR=${#1}-${#STR}
        TYPE="$2"
        until [[ ${NR} -eq 0 ]]
        do
            TYPE="${TYPE}*"
            ((NR-=1))
        done
    else
        STR="$1"
        TYPE="$2"
    fi

    # Get rid of assignment notation
    if [[ ${STR} = +(*=*) ]]
    then
        STR=$(echo ${STR%%=*})
    else
        STR=$(echo ${STR})
    fi

    # Get rid of array notation
    if [[ ${STR} = +(*\[*\]*) ]]
    then
        STR=${STR%%\[*}
    fi

    # Get rid of recordname '.'
    if [[ ${STR} = +(*.*) ]]
    then
        STR=${STR##*.}
    fi

    eval hash_"${g_RECORDVAR%%\[*}${STR}"='${TYPE}'

    if [[ ${g_DEBUG} -eq 1 ]]
    then
        if [[ ${g_ALL_MAIN_VARS} != +(*${g_RECORDVAR%%\[*}${STR}*) ]]
        then
            g_ALL_MAIN_VARS="$g_ALL_MAIN_VARS ${g_RECORDVAR%%\[*}${STR}"
        fi
    fi
}

function Save_Func_Var
{
    typeset STR TYPE NR

    # If there is a function pointer, skip this function
    if [[ ${1} = +(*\(*\)*) ]]
    then
        return
    fi

    # Make sure the asterisk is attached to type
    if [[ ${1} = +(\**) ]]
    then
        STR=$(echo ${1//\*/})
        let NR=${#1}-${#STR}
        TYPE="$3"
        until [[ ${NR} -eq 0 ]]
        do
            TYPE="${TYPE}*"
            ((NR-=1))
        done
    else
        STR="$1"
        TYPE="$3"
    fi

    # Get rid of assignment notation
    if [[ "${STR}" = +(*=*) ]]
    then
        STR=$(echo ${STR%%=*})
    else
        STR=$(echo ${STR})
    fi

    # Get rid of array notation
    if [[ ${STR} = +(*\[*\]*) ]]
    then
        STR=${STR%%\[*}
    fi

    # Get rid of recordname '.'
    if [[ ${STR} = +(*.*) ]]
    then
        STR=${STR##*.}
    fi

    eval hash_"${g_RECORDVAR%%\[*}${STR}___${2}"='${TYPE}'

    if [[ ${g_DEBUG} -eq 1 ]]
    then
        if [[ ${g_ALL_FUNC_VARS} != +(*${g_RECORDVAR%%\[*}${STR}___${2}*) ]]
        then
            g_ALL_FUNC_VARS="$g_ALL_FUNC_VARS ${g_RECORDVAR%%\[*}${STR}___${2}"
        fi
    fi
}

function Debug_Vars
{
    typeset i

    echo
    for i in $g_ALL_MAIN_VARS
    do
        i=${i//_____/.}
        echo -n $(Get_Var $i)":MAIN:${i} "
    done

    echo
    for i in $g_ALL_FUNC_VARS
    do
        i=${i//_____/.}
        echo -n $(Get_Var $i)":${i##*___}:${i%%___*} "
    done
    echo
}

# This function registers variables. $1 = var to be declared, if $2-$3-$4 etc is double then $1 should be double.
function Register_Numeric
{
    typeset TYPE

    if [[ ${1} = +(*${g_FLOATSIGN}) ]]
    then
	echo "double ${1};" >> $g_HFILE
        Save_Main_Var "${1}" "double"
        TYPE="double"
    else
        echo "${g_VARTYPE} ${1};" >> $g_HFILE
        Save_Main_Var "${1}" "${g_VARTYPE}"
        TYPE="${g_VARTYPE}"
    fi
}

# This function saves the dimension of arrays (SORT)
function Save_Dim
{
    typeset STR

    # Get rid of record '.'
    if [[ ${1} = +(*.*) ]]
    then
        STR=${1##*.}
    else
        STR=${1}
    fi

    eval dim_"${g_RECORDVAR%%\[*}${STR}_${g_FUNCNAME}"='${2}'
}

# This function gets the dimension of arrays (SORT)
function Get_Dim
{
    typeset STR RECORD RESULT

    # Get rid of record '.'
    if [[ ${1} = +(*.*) ]]
    then
        RECORD=${1%%.*}
        STR=${1##*.}
    else
        RECORD=${g_RECORDVAR%%\[*}
        STR=${1}
    fi

    RESULT=`eval echo '${dim_'"${RECORD}${STR}_"'}'`
    if [[ -z ${RESULT} ]]
    then
        RESULT=`eval echo '${dim_'"${RECORD}${STR}_${g_FUNCNAME}"'}'`
    fi

    echo ${RESULT}
}

#-----------------------------------------------------------

function Mini_Parser
{
    # Local variables
    typeset LINE TOKEN LEN CHAR
    typeset -i IN_STRING IN_FUNC ESCAPED

    let ESCAPED=0
    let IN_STRING=0
    let IN_FUNC=0

    LINE=$(echo ${1// /${g_PARSEVAR}})
    TOKEN=
    LEN=${#LINE}

    # Get the characters
    until [[ $LEN -eq 0 ]]
    do
	CHAR="${LINE:0:1}"
	case $CHAR in
	    ","|";")
		if [[ $IN_STRING -eq 0 && $IN_FUNC -eq 0 ]]
		then
                    if [[ ${#TOKEN} -gt 0 ]]
                    then
                        break
                    fi
		fi;;
	    "\\")
		ESCAPED=1;;
	    "\"")
		if [[ $ESCAPED -eq 0 ]]
		then
		    if [[ $IN_STRING -eq 0 ]]
		    then
			IN_STRING=1
		    else
			IN_STRING=0
		    fi
		fi
		ESCAPED=0;;
	    "(")
		if [[ $IN_STRING -eq 0 ]]
		then
		    ((IN_FUNC=$IN_FUNC+1))
		fi
		ESCAPED=0;;
	    ")")
		if [[ $IN_STRING -eq 0 ]]
		then
		    ((IN_FUNC=$IN_FUNC-1))
		fi
		ESCAPED=0;;
	    *)
		ESCAPED=0;;
	esac
	# Convert back to space
	if [[ "${CHAR}" = "${g_PARSEVAR}" ]]
	then
	    TOKEN="${TOKEN} "
	else
	    TOKEN="${TOKEN}${CHAR}"
	fi
	let LEN=${#LINE}-1
	LINE="${LINE: -$LEN}"
    done

    echo "${TOKEN}"
}

#----------------------------------------------------------- $2 = stdout or stderr

function Print_Element
{
    typeset CHECK VAR

    # If argument 1 does not contain an actual string
    if [[ ${1} = "stdout" || ${1} == "stderr" ]]
    then
        return
    fi

    # Check on string by reference variable
    VAR=$(echo ${1%%\(*})
    if [[ "${VAR}" != +(*${g_DQUOTESIGN}*) ]]
    then
        CHECK=$(Get_Var "${1}" ${g_FUNCNAME})
    fi

    # Check if var is string var
    if [[ "${VAR}" = +(*${g_STRINGSIGN}*) || "${VAR}" = +(*${g_DQUOTESIGN}*) || "${VAR}" = +(gettext*|ngettext*) || ${CHECK} = "char*" ]]
    then
	echo "__b2c__assign = ${1}; if(__b2c__assign != NULL) fprintf(${2}, \"%s\", __b2c__assign);" >> $g_CFILE
    else
	echo "fprintf(${2}, \"%s\", STR${g_STRINGSIGN}(${1}));" >> $g_CFILE
    fi
}

#----------------------------------------------------------- $2 = stdout or stderr

function Handle_Print
{
    typeset FORMAT EXP LEN TOKEN TO CHECK SIZE TOPARSE
    typeset -i AM1 AM2

    # If no argument, do nothing
    if [[ "$1" != "PRINT" && "$1" != "EPRINT" ]]
    then
	# Get expression without ;
	if [[ -z ${1##*;} ]]
	then
	    let LEN="${#1}"-1
	    EXP="${1:0:$LEN}"
	else
	    EXP="${1}"
	fi
        # Get rid of escaped quote
        TOPARSE="${EXP//\\\\\"/  }"
        # Prepare for parsing
        AM1=`echo ${TOPARSE%FORMAT *} | tr -d -c "\"" | wc -c`
        AM2=`echo ${TOPARSE%TO *} | tr -d -c "\"" | wc -c`
	# If there is FORMAT/format argument
	if [[ "${EXP}" = +(* FORMAT *) && $((${AM1} % 2)) -eq 0 ]]
	then
	    FORMAT="${EXP##* FORMAT}"
            EXP="${EXP%FORMAT *}"
	    # Optional TO argument?
	    if [[ $FORMAT = +(* TO *) ]]
	    then
		TO=${FORMAT##* TO }
            fi
        elif [[ "${EXP}" = +(* TO *) && $((${AM2} % 2)) -eq 0 ]]
        then
	    TO=${EXP##* TO }
            FORMAT="\"%s\""
            EXP="${EXP%TO *}"
        fi
        if [[ ${TO} = +(* SIZE *) ]]
        then
            SIZE=${TO##* SIZE }
            TO=${TO%% SIZE *}
        else
            SIZE=${g_BUFFER_SIZE}
        fi
        if [[ -n $FORMAT ]]
        then
            if [[ -n $TO ]]
            then
                # Check if string is declared
                if [[ "${TO}" = +(*${g_STRINGSIGN}) && "${TO}" != +(*.*) ]]
                then
                    if [[ -z $(Get_Var ${TO} ${g_FUNCNAME}) ]]
	            then
	                echo "char *${TO} = NULL;" >> $g_HFILE
                        Save_Main_Var "${TO}" "char*"
	            fi
                fi
		echo "__b2c__assign = (char*)calloc($SIZE+1, sizeof(char));" >> $g_CFILE
		echo "snprintf(__b2c__assign, $SIZE+1, ${FORMAT%% TO*}, ${EXP});" >> $g_CFILE
	        # Now see if we have a assoc or a normal variable
	        if [[ "${TO}" = +(*\(*\)) ]]
	        then
	            STR=${TO#*\(}
	            echo "__b2c__${TO%%\(*}__location = __b2c__${TO%%\(*}__add(${STR};" >> $g_CFILE
	            echo "if(__b2c__${TO%%\(*}__location->__b2c_value != NULL) free(__b2c__${TO%%\(*}__location->__b2c_value); __b2c__${TO%%\(*}__location->__b2c_value = __b2c__assign;" >> $g_CFILE
	            # Check for relations
	            Relate_Recurse "${TO%%\(*}" "${STR}" "${TO}" "-1"
	        else
	            echo "if(${TO} != NULL) free(${TO}); ${TO} = __b2c__assign;" >> $g_CFILE
	        fi
	    else
		echo "fprintf(${2}, ${FORMAT%%;*}, ${EXP});" >> $g_CFILE
	    fi
	else
	    # Start miniparser
            while [[ -n ${EXP} ]]
            do
                TOKEN=$(Mini_Parser "${EXP}")
	        Print_Element "${TOKEN}" "${2}"
                EXP="${EXP:${#TOKEN}+1}"
            done

            # If line ends with ';' then skip newline
	    if [[ -n $(echo ${1##*;}) ]]
	    then
		echo "fprintf(${2}, \"\n\");" >> $g_CFILE
	    fi
	fi
    else
	echo "fprintf(${2}, \"\n\");" >> $g_CFILE
    fi

    # Flush buffer
    echo "fflush(${2});" >> $g_CFILE
}

#-----------------------------------------------------------

function Handle_Input
{
    # Local variables
    typeset CHECK VAR STR EXP TOKEN

    # Check if we have an argument at all
    if [[ "$1" = "INPUT" ]]
    then
	echo -e "\nSyntax error: empty INPUT at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    EXP="${1}"

    # Start miniparser to see if we need to print something
    while [[ -n ${EXP} ]]
    do
        TOKEN=$(Mini_Parser "${EXP}")
        EXP="${EXP:${#TOKEN}+1}"
        if [[ -n ${EXP} ]]
        then
	    Print_Element "${TOKEN}" "stdout"
        fi
    done

    # Remove spaces in variable
    VAR=$(echo ${TOKEN})

    # Check if string is declared
    if [[ "${VAR}" = +(*${g_STRINGSIGN}) && "$VAR" != +(*.*) ]]
    then
        if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	then
	    echo "char *$VAR = NULL;" >> $g_HFILE
            Save_Main_Var "${VAR}" "char*"
	fi
    # Not a string?
    elif [[ "$VAR" != +(*\[*\]*) && "$VAR" != +(*.*) && "$VAR" != +(*\(*\)*) && "$VAR" != +(*-\>*) ]]
    then
        if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	then
            Register_Numeric "${VAR}"
	fi
    fi

    # Get the type
    CHECK=$(Get_Var ${VAR} ${g_FUNCNAME})

    # Check type of var, string?
    if [[ "${VAR}" = +(*${g_STRINGSIGN}) || "${VAR%%\(*}" = +(*${g_STRINGSIGN}) || "${VAR%%\[*}" = +(*${g_STRINGSIGN}) ]]
    then
        # Translate function to C function
        echo "__b2c__counter = 1; __b2c__assign = calloc(1, sizeof(char)); do{ if(fgets(__b2c__input__buffer, $g_BUFFER_SIZE, stdin) == NULL)" >> $g_CFILE
	echo "{if(__b2c__trap){ERROR = 35; if(!__b2c__catch_set) RUNTIMEERROR(\"INPUT\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE

        # Make sure internal var is copied to var of program
        echo "__b2c__assign = (char*)realloc(__b2c__assign, $g_BUFFER_SIZE*__b2c__counter*sizeof(char));" >> $g_CFILE
        echo " strncat(__b2c__assign, __b2c__input__buffer, $g_BUFFER_SIZE); __b2c__counter++;" >> $g_CFILE
        echo "} while (!strstr(__b2c__input__buffer, \"\n\") && strlen(__b2c__input__buffer));" >> $g_CFILE
        # Cut off last newline
        echo "if(__b2c__assign != NULL) {__b2c__ctr = strlen(__b2c__assign); if(__b2c__ctr > 0) __b2c__assign[__b2c__ctr-1] = '\0';}" >> $g_CFILE

	# Now see if we have a assoc or a normal variable
	if [[ "${VAR}" = +(*\(*\)) ]]
	then
	    STR=${VAR#*\(}
	    echo "__b2c__${VAR%%\(*}__location = __b2c__${VAR%%\(*}__add(${STR};" >> $g_CFILE
	    echo "if(__b2c__${VAR%%\(*}__location->__b2c_value != NULL) free(__b2c__${VAR%%\(*}__location->__b2c_value); __b2c__${VAR%%\(*}__location->__b2c_value = __b2c__assign;" >> $g_CFILE
	    # Check for relations
	    Relate_Recurse "${VAR%%\(*}" "${STR}" "${VAR}" "-1"
	else
	    echo "if($VAR != NULL) free($VAR); $VAR = __b2c__assign;" >> $g_CFILE
	fi
    # Var is numeric
    else
	# Translate function to C function
	echo "memset(__b2c__input__buffer, '\0', $g_BUFFER_SIZE); if(fgets(__b2c__input__buffer, $g_BUFFER_SIZE, stdin)==NULL)" >> $g_CFILE
	echo "{if(__b2c__trap){ERROR = 35; if(!__b2c__catch_set) RUNTIMEERROR(\"INPUT\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE

	# Now see if we have an assoc or a normal variable
	if [[ "${VAR}" = +(*\(*\)) ]]
	then
	    STR=${VAR#*\(}
	    echo "__b2c__${VAR%%\(*}__location = __b2c__${VAR%%\(*}__add(${STR};" >> $g_CFILE
	    if [[ "$CHECK" = +(*double*) || "$CHECK" = +(*float*) || "$CHECK" = +(*FLOATING*) ]]
	    then
		echo "__b2c__${VAR%%\(*}__location->__b2c_value = atof(__b2c__input__buffer);" >> $g_CFILE
	    elif [[ "$CHECK" = +(*long*) || "$CHECK" = +(*NUMBER*) ]]
	    then
		echo "__b2c__${VAR%%\(*}__location->__b2c_value = atol(__b2c__input__buffer);" >> $g_CFILE
	    else
		echo "__b2c__${VAR%%\(*}__location->__b2c_value = atoi(__b2c__input__buffer);" >> $g_CFILE
	    fi
	    # Check for relations
	    Relate_Recurse "${VAR%%\(*}" "${STR}" "${VAR}" "-1"
	else
	    if [[ "$CHECK" = +(*double*) || "$CHECK" = +(*float*) || "$CHECK" = +(*FLOATING*) ]]
	    then
		echo "$VAR = atof(__b2c__input__buffer);" >> $g_CFILE
	    elif [[ "$CHECK" = +(*long*) || "$CHECK" = +(*NUMBER*) ]]
	    then
		echo "$VAR = atol(__b2c__input__buffer);" >> $g_CFILE
	    else
		echo "$VAR = atoi(__b2c__input__buffer);" >> $g_CFILE
	    fi
	fi
    fi
    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
    then
        g_CATCH_USED=1
    fi
}

#-----------------------------------------------------------

function Handle_For
{
    # Local variables
    typeset FROM TO TMP VAR STEP STR

    # Check if TO is available
    if [[ "${1}" != +(* TO *) && "${1}" != +(* DOWNTO *) && "${1}" != +(* IN *) ]]
    then
	echo -n "\nSyntax error: missing IN/TO/DOWNTO in FOR statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # What kind of FOR are we dealing with
    if [[ "${1}" = +(* TO *) || "${1}" = +(* DOWNTO *) ]]
    then
        # Get the variablename without (surrounding) spaces
        VAR=`echo "${1%%=*}" | tr -d "\040"`; TMP=`echo "${1#*=}"`

        # Get the starting and ending value
        if [[ "${1}" = +(* TO *) ]]
        then
            FROM=`echo "${TMP%% TO *}"`
            TO=`echo "${TMP##* TO }"`
        else
            FROM=`echo "${TMP%% DOWNTO *}"`
            TO=`echo "${TMP##* DOWNTO }"`
        fi

        # Check if there is a STEP
        if [[ "$TO" = +(* STEP *) ]]
        then
	    STEP="${TO##* STEP }"
	    TO="${TO%% STEP *}"
        else
	    STEP=1
        fi
        if [[ "${1}" = +(* DOWNTO *) ]]
        then
            STEP="-${STEP}"
        fi
    else
        # Get the variablename without (surrounding) spaces
        VAR=`echo "${1%% IN *}" | tr -d "\040"`; TMP=`echo "${1#* IN }"`
        # Check if there is a STEP
        if [[ "$TMP" = +(* STEP *) ]]
        then
	    STEP="${TMP##* STEP }"
	    TMP="${TMP%% STEP *}"
        else
	    STEP="\" \""
        fi
        # Define help variables
        if [[ -n $g_FUNCNAME ]]
        then
	    if [[ ${g_STRINGARGS} != +(*__b2c__forin_${VAR}*) ]]
	    then
                g_STRINGARGS="${g_STRINGARGS} char *__b2c__forin_${VAR} = NULL;"
                Save_Func_Var "__b2c__forin_${VAR}" "${g_FUNCNAME}" "char*"
                g_STRINGARGS="${g_STRINGARGS} char *__b2c__forin_${VAR}_end = NULL;"
                Save_Func_Var "__b2c__forin_${VAR}_end" "${g_FUNCNAME}" "char*"
            fi
        else
            if [[ -z $(Get_Var __b2c__forin_${VAR}) ]]
	    then
                echo "char *__b2c__forin_${VAR} = NULL;" >> $g_HFILE
                Save_Main_Var "__b2c__forin_${VAR}" "char*"
                echo "char *__b2c__forin_${VAR}_end = NULL;" >> $g_HFILE
                Save_Main_Var "__b2c__forin_${VAR}_end" "char*"
            fi
        fi
        echo "if($TMP != NULL) __b2c__forin_${VAR} = __b2c__strdup(${TMP});" >> $g_CFILE
    fi

    # Check if string is declared
    if [[ "${VAR}" = +(*${g_STRINGSIGN}) && "$VAR" != +(*.*) ]]
    then
        if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	then
	    echo "char *$VAR = NULL;" >> $g_HFILE
            Save_Main_Var "${VAR}" "char*"
	fi
    # Not a string?
    elif [[ "$VAR" != +(*\[*\]*) && "$VAR" != +(*.*) && "$VAR" != +(*\(*\)*) && "$VAR" != +(*-\>*) ]]
    then
        if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	then
            if [[ $FROM$TO$STEP = +(*[0-9]*.*[0-9]*) || $(Get_Var ${STEP#*-} ${g_FUNCNAME}) = +(*double*|*float*|*FLOATING*) ]]
            then
	        echo "double $VAR;" >> $g_HFILE
                Save_Main_Var "${VAR}" "double"
            else 
                Register_Numeric ${VAR}
            fi
	fi
    fi

    # Check type of var, string?
    if [[ "${VAR}" = +(*${g_STRINGSIGN}) || "${VAR%%\(*}" = +(*${g_STRINGSIGN}) || "${VAR%%\[*}" = +(*${g_STRINGSIGN}) ]]
    then
        echo "${VAR} = (char*)__b2c_Copy_String(${VAR}, strtok_r(__b2c__forin_${VAR}, ${STEP}, &__b2c__forin_${VAR}_end));" >> $g_CFILE
        echo "while(${VAR} != NULL){" >> $g_CFILE
	if [[ $g_LOCALSTRINGS != +(*__b2c__forin_${VAR}*) ]]
        then
            g_LOCALSTRINGS="${g_LOCALSTRINGS} __b2c__forin_${VAR}"
        fi
        g_LOOPVAR[${g_LOOPCTR}]=${VAR}
        g_LOOPSTEP[${g_LOOPCTR}]="${STEP}"
    # Var is numeric
    else
        # Translate function to C function
        if [[ "${STEP}" = +(*-*) ]]
        then
	    echo "for($VAR=$FROM; $VAR >= $TO; $VAR+=$STEP){" >> $g_CFILE
        else
	    echo "for($VAR=$FROM; $VAR <= $TO; $VAR+=$STEP){" >> $g_CFILE
        fi
    fi
}

#-----------------------------------------------------------

function Handle_While
{
    # Check if DO is available
    if [[ "$1" != +(* DO) ]]
    then
        Parse_Equation "${1}"
    else
        Parse_Equation "${1% *}"
    fi
    echo "while(${g_EQUATION}){" >> $g_CFILE
}

#-----------------------------------------------------------
# $1: name of ASSOC variable
# $2: name of index
# $3: actual value to assign
# $4: recursion level

function Relate_Recurse
{
    typeset CTR REL LVL

    # Check endless recursion
    LVL=$4; ((LVL+=1))
    if [[ $LVL -gt $g_RELATE_CTR ]]
    then
	echo -e "\nSyntax error: endless recursion in RELATE statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Now add relation
    CTR=0

    while [[ $CTR -lt $g_RELATE_CTR ]]
    do
	if [[ ${g_RELATE[${CTR}]} = +(${1}*) ]]
	then
	    REL=${g_RELATE[${CTR}]##* }
	    echo "__b2c__${REL}__location = __b2c__${REL}__add(${2};" >> $g_CFILE
	    if [[ "${REL}" = +(*${g_STRINGSIGN}*) ]]
	    then
                echo "__b2c__${REL}__location->__b2c_value = (char*)__b2c_Copy_String(__b2c__${REL}__location->__b2c_value, ${3});" >> $g_CFILE
	    else
	        echo "__b2c__${REL}__location->__b2c_value = ${3};" >> $g_CFILE
	    fi
	    Relate_Recurse ${REL} ${2} ${3} ${LVL}
	fi
	((CTR+=1))
    done
}

#-----------------------------------------------------------

function Handle_Let
{
    # Local variables
    typeset VAR TYPE TMP STR ARG PTR CHAR ESCAPED IN_STRING LINE IN_FUNC
    typeset -i POS LEN

    # Start miniparser to find last unquoted '='
    POS=0
    LEN=${#1}
    LINE="$1"

    # Get the characters
    until [[ $LEN -eq 0 ]]
    do
	CHAR="${LINE:0:1}"
	case $CHAR in
	    "\\")
		if [[ $ESCAPED -eq 1 ]]
		then
		    ESCAPED=0
                else
		    ESCAPED=1
                fi;;
	    "\"")
		if [[ $ESCAPED -eq 0 ]]
		then
		    if [[ $IN_STRING -eq 0 ]]
		    then
			IN_STRING=1
		    else
			IN_STRING=0
		    fi
		fi
		ESCAPED=0;;
	    "(")
		if [[ $IN_STRING -eq 0 ]]
		then
		    ((IN_FUNC=$IN_FUNC+1))
		fi
		ESCAPED=0;;
	    ")")
		if [[ $IN_STRING -eq 0 ]]
		then
		    ((IN_FUNC=$IN_FUNC-1))
		fi
		ESCAPED=0;;

	    "=")
		if [[ $IN_STRING -eq 0 && $IN_FUNC -eq 0 ]]
		then
		    let POS=${#1}-${LEN}
		fi
		ESCAPED=0;;
	    *)
		ESCAPED=0;;
	esac
	let LEN=${#LINE}-1
	LINE="${LINE: -$LEN}"
    done

    # Check if there is an assignment at all, if not exit
    if [[ ${POS} -eq 0 ]]
    then
        if [[ $g_IGNORE_PARSE = "0" || $g_IGNORE_PARSE = "FALSE" ]]
        then
            echo "$1;" >> $g_CFILE
            return
        else
	    echo -e "\nSyntax error: could not parse line $g_COUNTER in file '$g_CURFILE': \"${1}\""
	    exit 1
        fi
    fi

    # Get the variablename without surrounding spaces
    VAR=$(echo ${1:0:${POS}})
    ((POS+=1))
    TMP=$(echo ${1:${POS}})

    # Check if var is string var, exclude RECORD elements
    if [[ "${VAR}" = +(*${g_STRINGSIGN}) && "$VAR" != +(*.*) && $g_DYNAMICARRAYS != +(*${VAR}@${g_FUNCNAME}*) ]]
    then
        if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	then
	    echo "char *$VAR = NULL;" >> $g_HFILE
            Save_Main_Var "${VAR}" "char*"
	fi

    # Assume number, exclude RECORD and ASSOC elements
    elif [[ "$VAR" != +(*\[*\]*) && "$VAR" != +(*.*) && "$VAR" != "ERROR" && "$VAR" != "RETVAL" && "$VAR" != +(*\(*\)*) && "$VAR" != +(*-\>*) && "$VAR" != +(*=*) ]]
    then
        if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
        then
	    if [[ "$TMP" = +(*.*) && "$TMP" != +(*$g_DQUOTESIGN*) ]]
            then
	        echo "double $VAR;" >> $g_HFILE
                Save_Main_Var "${VAR}" "double"
            else
                Register_Numeric ${VAR}
            fi
	fi
    fi

    # Check if there is associative array assignment
    if [[ "${VAR}" = +(*\(*\)) ]]
    then
	STR=${VAR#*\(}
	echo "__b2c__${VAR%%\(*}__location = __b2c__${VAR%%\(*}__add(${STR};" >> $g_CFILE
	if [[ "${VAR%%\(*}" = +(*${g_STRINGSIGN}*) ]]
	then
            echo "__b2c__${VAR%%\(*}__location->__b2c_value = (char*)__b2c_Copy_String(__b2c__${VAR%%\(*}__location->__b2c_value, ${TMP});" >> $g_CFILE
	else
	    echo "__b2c__${VAR%%\(*}__location->__b2c_value = ${TMP};" >> $g_CFILE
	fi
	# Check for relations
	Relate_Recurse "${VAR%%\(*}" "${STR}" "${TMP}" "-1"

    # Is there an array variable without subscript (dynamic array) -> assignment to STATIC returned arrays
    elif [[ "${VAR}" != +(*\[*\]*) && $g_DYNAMICARRAYS = +(* ${VAR}@${g_FUNCNAME}|* ${VAR}@${g_FUNCNAME} *) ]]
    then
	if [[ "${VAR}" = +(*${g_STRINGSIGN}*) ]]
        then
            echo "for(__b2c__ctr=0; __b2c__ctr<__b2c_array_$VAR+$g_OPTION_BASE; __b2c__ctr++)if($VAR[__b2c__ctr]!=NULL){free($VAR[__b2c__ctr]);}" >> $g_CFILE
        fi
        echo "free($VAR);" >> $g_CFILE
	echo "${g_WITHVAR}${1};" >> $g_CFILE

    # Do we have a STRING variable or STRING array?
    elif [[ "${VAR}" = +(*${g_STRINGSIGN}*) && "${VAR}" != +(*\[*${g_STRINGSIGN}*\]*) ]]
    then
        TYPE=$(Get_Var ${VAR} ${g_FUNCNAME})
        # Check if it is some variable directly assigned
        if [[ $TYPE = +(*const*) ]]
        then
            echo "__b2c__assign=(char*)__b2c__strdup(${TMP}); if(__b2c__assign==NULL)__b2c__assign=calloc(1, sizeof(char)); ${g_WITHVAR}${VAR} = __b2c__assign; " >> $g_CFILE
            if [[ -n ${g_FUNCNAME} ]]
            then
	        Save_Func_Var "${VAR}" "${g_FUNCNAME}" "${TYPE##*const }"
            else
                Save_Main_Var "${VAR}" "${TYPE##*const }"
            fi
        else
            echo "${g_WITHVAR}${VAR} = (char*)__b2c_Copy_String(${g_WITHVAR}${VAR}, ${TMP});" >> $g_CFILE
        fi
	# Also check if string var already is used for IMPORT, if so, perform dlopen again
        PTR="${VAR//[[:punct:]]/}"
        if [[ -n $(Get_Var __b2c__dlopen__pointer_$PTR ${g_FUNCNAME}) ]]
	then
	    echo "__b2c__dlopen__pointer_$PTR = dlopen($VAR, RTLD_LAZY);" >> $g_CFILE
	fi
    # Numeric or foreign type
    else
        TYPE=$(Get_Var ${VAR} ${g_FUNCNAME})
        # Make sure compiler treats floating values
        if [[ ${TYPE} = +(*float*|*double*|*FLOATING*) && ${TMP} != +(*${g_STRINGSIGN}*) ]]
        then
	    # Get rid of existing casting
            TMP="${TMP//\(float\)/}"
            TMP="${TMP//\(double\)/}"
            TMP="${TMP//\(FLOATING\)/}"
            # We have to find the first variable name or value in the expression to cast
            STR="${TMP}"
            while [[ ${#STR} -gt 0 ]]
            do
                if [[ ${STR:0:1} = +(*[a-zA-Z0-9_.]*) ]]
                then
	            break
                else
	            STR=${STR:1}
                fi
            done
            ((POS=${#TMP}-${#STR}))
            # Construct line
            TMP="${TMP:0:${POS}}(${TYPE//static/})${TMP:${POS}}"
        fi
        # Cast the expression to type of variable, avoid duplicate cast
        if [[ ${TMP} = +(\(float\)*|\(double\)*|\(FLOATING\)*) ]]
        then
            echo "${g_WITHVAR}${VAR}=${TMP};" >> $g_CFILE
        elif [[ -n ${TYPE} && ${TYPE} != +(*\**) ]]
        then
            echo "${g_WITHVAR}${VAR}=(${TYPE//static/})${TMP};" >> $g_CFILE
        # Other type
        else
	    echo "${g_WITHVAR}${1};" >> $g_CFILE
        fi
    fi
}

#-----------------------------------------------------------

function Handle_Open
{
    # Local variables
    typeset MODE HANDLE TMP CHECK LABEL CTR TOKEN ADDRESS SOURCE BND STR EXP
    typeset -a FILE FROM CTR

    # Check if FOR is available
    if [[ "$1" != +(* FOR *) ]]
    then
	echo -e "\nSyntax error: missing FOR in OPEN statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if AS is available
    if [[ "$1" != +(* AS *) ]]
    then
	echo -e "\nSyntax error: missing AS in OPEN statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    let CTR=0
    EXP=`echo "${1%% FOR *}"`

    # Start miniparser
    while [[ -n ${EXP} ]]
    do
        TOKEN=$(Mini_Parser "${EXP}")
	FILE[$CTR]="${TOKEN}"
        ((CTR+=1))
        EXP="${EXP:${#TOKEN}+1}"
    done
    ((CTR-=1))

    # Get the mode and handle
    TMP=$(echo ${1##* FOR })
    MODE=$(echo ${TMP%% AS *})
    HANDLE=$(echo ${TMP##* AS })

    let BND=0

    # Check for SOURCE address
    if [[ ${HANDLE} = +(*FROM*) ]]
    then
        EXP=$(echo ${HANDLE##* FROM })
        # Start miniparser, convert spaces
        while [[ -n ${EXP} ]]
        do
            TOKEN=$(Mini_Parser "${EXP}")
	    FROM[$BND]="${TOKEN}"
            ((BND+=1))
            EXP="${EXP:${#TOKEN}+1}"
        done
        HANDLE=$(echo ${HANDLE%% FROM *})
        ((BND-=1))
    fi

    # Check if var is string var
    if [[ "${HANDLE}" = +(*${g_STRINGSIGN}) && $MODE != "MEMORY" ]]
    then
	echo -e "\nSyntax error: variable for OPEN at line $g_COUNTER in file '$g_CURFILE' cannot be string!"
	exit 1
    fi

    # Check if variable was declared
    if [[ "$HANDLE" != +(*.*) ]]
    then
        CHECK=$(Get_Var ${HANDLE} ${g_FUNCNAME})
    else
        CHECK="1"
    fi

    # File or dir?
    if [[ $MODE = "DIRECTORY" ]]
    then
	if [[ -z $CHECK ]]
	then
	    echo "DIR *$HANDLE;" >> $g_HFILE
            Save_Main_Var "${HANDLE}" "DIR*"
	fi
    elif [[ $MODE = "MEMORY" ]]
    then
        if [[ -z $(Get_Var ${HANDLE} ${g_FUNCNAME}) ]]
	then
	    echo "char *$HANDLE = NULL;" >> $g_HFILE
            Save_Main_Var "${HANDLE}" "char*"
	fi
        if [[ -z $(Get_Var __b2c_mem_$HANDLE ${g_FUNCNAME}) ]]
	then
	    echo "long __b2c_mem_$HANDLE;" >> $g_HFILE
            Save_Main_Var "__b2c_mem_${HANDLE}" "long"
	fi
    elif [[ $MODE = "NETWORK" || $MODE = "SERVER" || $MODE = "UDP" || $MODE = "DEVICE" ]]
    then
	if [[ -z $CHECK ]]
	then
	    echo "int $HANDLE;" >> $g_HFILE
            Save_Main_Var "${HANDLE}" "int"
	fi
    else
	if [[ -z $CHECK ]]
	then
	    echo "FILE* $HANDLE;" >> $g_HFILE
            Save_Main_Var "${HANDLE}" "FILE*"
	fi
    fi

    # Convert to C syntax
    case $MODE in
	@(READING) )
	    echo "$HANDLE = fopen(${FILE[0]}, \"r\");" >> $g_CFILE
	    echo "if($HANDLE == NULL){if(__b2c__trap){ERROR = 2; if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR READING\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE;;
	@(WRITING) )
	    echo "$HANDLE = fopen(${FILE[0]}, \"w\");" >> $g_CFILE
	    echo "if($HANDLE == NULL){if(__b2c__trap){ERROR = 2; if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR WRITING\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE;;
	@(APPENDING) )
	    echo "$HANDLE = fopen(${FILE[0]}, \"a\");" >> $g_CFILE
	    echo "if($HANDLE == NULL){if(__b2c__trap){ERROR = 2; if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR APPENDING\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE;;
	@(READWRITE) )
	    echo "$HANDLE = fopen(${FILE[0]}, \"r+\");" >> $g_CFILE
	    echo "if($HANDLE == NULL){if(__b2c__trap){ERROR = 2; if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR READWRITE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE;;
	@(DIRECTORY) )
	    echo "$HANDLE = opendir(${FILE[0]});" >> $g_CFILE
	    echo "if($HANDLE == NULL){if(__b2c__trap){ERROR = 2; if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR DIRECTORY\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE;;
	@(MEMORY) )
            if [[ "${HANDLE}" = +(*${g_STRINGSIGN}*) ]]
            then
	        echo "if(${HANDLE}!=NULL) free(${HANDLE});" >> $g_CFILE
            fi
	    echo "$HANDLE = (char*)${FILE[0]}; __b2c_mem_$HANDLE = ${FILE[0]};" >> $g_CFILE
	    echo "if(__b2c__trap){if(__b2c__memory__check($HANDLE, sizeof(__b2c__MEMTYPE))) {ERROR=1; if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR MEMORY\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE;;
        @(NETWORK) )
	    # Network code
            TMP=${CTR}

            # Setup the array of addresses
            echo "__b2c__addr = calloc(${CTR}+1, sizeof(*__b2c__addr));" >> $g_CFILE
            until [[ ${TMP} -lt 0 ]]
            do
	        echo "if (strstr(${FILE[$TMP]}, \":\") == NULL) {ERROR = 10; RUNTIMEERROR(\"OPEN FOR NETWORK\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;}" >> $g_CFILE
	        echo "strncpy(__b2c__data_client, ${FILE[${TMP}]}, $g_BUFFER_SIZE); __b2c__host = strtok(__b2c__data_client, \":\"); __b2c__port = strtok(NULL, \":\"); __b2c__he = gethostbyname(__b2c__host);" >> $g_CFILE
	        echo "if (__b2c__he == NULL || __b2c__he->h_addr == NULL) {if(__b2c__trap){ERROR = 11;if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR NETWORK\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
                echo "__b2c__addr[$TMP].sin_family = AF_INET; __b2c__addr[$TMP].sin_port = htons((long)atol(__b2c__port));" >> $g_CFILE
	        echo "__b2c__addr[$TMP].sin_addr = *((struct in_addr *)__b2c__he->h_addr);" >> $g_CFILE
                ((TMP-=1))
	    done

            # Create the socket
            if [[ ${g_NETWORKTYPE} = "SCTP" ]]
            then
                echo "$HANDLE = socket(AF_INET, ${g_SOCKTYPE}, IPPROTO_SCTP);" >> $g_CFILE
            else
                echo "$HANDLE = socket(AF_INET, ${g_SOCKTYPE}, 0);" >> $g_CFILE
            fi
	    echo "if ($HANDLE == -1) {if(__b2c__trap){ERROR = 12;if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR NETWORK\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE

            # Set socket options
	    echo "__b2c__to.tv_sec = $g_OPTION_SOCKET; __b2c__to.tv_usec = 0; setsockopt($HANDLE, SOL_SOCKET, SO_SNDTIMEO, &__b2c__to, sizeof(struct timeval));" >> $g_CFILE
            if [[ ${g_NETWORKTYPE} = "BROADCAST" ]]
	    then
		echo "setsockopt($HANDLE, SOL_SOCKET, SO_BROADCAST, &__b2c__yes, sizeof(int));" >> $g_CFILE
	    elif [[ ${g_NETWORKTYPE} = "MULTICAST" ]]
	    then
		echo "setsockopt($HANDLE, IPPROTO_IP, IP_MULTICAST_LOOP, &__b2c__yes, sizeof(int));" >> $g_CFILE
		echo "__b2c__ttl=${g_MULTICAST_TTL}; setsockopt($HANDLE, IPPROTO_IP, IP_MULTICAST_TTL, &__b2c__ttl, sizeof(unsigned char));" >> $g_CFILE
            elif [[ ${g_NETWORKTYPE} = "SCTP" ]]
	    then
                echo "memset(&__b2c__initmsg, 0, sizeof(__b2c__initmsg)); __b2c__initmsg.sinit_max_attempts = 3;" >> $g_CFILE
                echo "__b2c__initmsg.sinit_num_ostreams = ${g_SCTP_STREAMS}; __b2c__initmsg.sinit_max_instreams = ${g_SCTP_STREAMS};" >> $g_CFILE
                echo "setsockopt(${HANDLE}, IPPROTO_SCTP, SCTP_INITMSG, &__b2c__initmsg, sizeof(__b2c__initmsg));" >> $g_CFILE
	    fi
	    echo "setsockopt($HANDLE, SOL_SOCKET, SO_REUSEADDR, &__b2c__yes, sizeof(int));" >> $g_CFILE

            # Do we need to specify a source address?
            if [[ -n ${FROM[${BND}]} ]]
            then
                TMP=${BND}
                echo "__b2c__from = calloc(${BND}+1, sizeof(*__b2c__from));" >> $g_CFILE
                until [[ ${TMP} -lt 0 ]]
                do
                    echo "strncpy(__b2c__data_client, ${FROM[${TMP}]}, $g_BUFFER_SIZE);" >> $g_CFILE
                    if [[ ${FROM[${TMP}]} = +(*:*) ]]
                    then
	                echo "__b2c__host = strtok(__b2c__data_client, \":\"); __b2c__port = strtok(NULL, \":\");" >> $g_CFILE
                    else
	                echo "__b2c__host = __b2c__data_client;" >> $g_CFILE
                    fi
	            echo "__b2c__he = gethostbyname(__b2c__host);" >> $g_CFILE
	            echo "if (__b2c__he == NULL || __b2c__he->h_addr == NULL) {if(__b2c__trap){ERROR = 11;if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR NETWORK\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
                    echo "__b2c__from[$TMP].sin_family = AF_INET;" >> $g_CFILE
                    if [[ ${FROM[${TMP}]} = +(*:*) ]]
                    then
                        echo "__b2c__from[$TMP].sin_port = htons((long)atol(__b2c__port));" >> $g_CFILE
                    fi
	            echo "__b2c__from[$TMP].sin_addr = *((struct in_addr *)__b2c__he->h_addr);" >> $g_CFILE
                    ((TMP-=1))
	        done

                # Set source address
                if [[ ${g_NETWORKTYPE} = "SCTP" ]]
                then
                    # Perform a one-one SCTP bind for multiple homes
                    echo "__b2c__result = sctp_bindx($HANDLE, (struct sockaddr *)__b2c__from, ${BND}+1, SCTP_BINDX_ADD_ADDR);" >> $g_CFILE
                else
                    # Perform a bind for TCP or UDP
                    echo "__b2c__result = bind($HANDLE, (struct sockaddr *)__b2c__from, sizeof(struct sockaddr));" >> $g_CFILE
                fi
	        echo "free(__b2c__from); if(__b2c__result == -1){if(__b2c__trap){ERROR = 17;if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR NETWORK\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
            fi

            # Setup connection
            if [[ ${g_NETWORKTYPE} = "SCTP" ]]
            then
                # Create a one-one SCTP socket to multiple homes
                echo "#ifdef SCTP_SOCKOPT_CONNECTX_OLD" >> $g_CFILE
                echo " __b2c__result = sctp_connectx($HANDLE, (struct sockaddr *)__b2c__addr, ${CTR}+1, NULL);" >> $g_CFILE
                echo "#else" >> $g_CFILE
                echo " __b2c__result = sctp_connectx($HANDLE, (struct sockaddr *)__b2c__addr, ${CTR}+1);" >> $g_CFILE
                echo "#endif" >> $g_CFILE
            else
                # Create a socket for TCP or UDP
                echo "__b2c__result = connect($HANDLE, (struct sockaddr *)__b2c__addr, sizeof(struct sockaddr));" >> $g_CFILE
            fi
            echo "free(__b2c__addr); if(__b2c__result == -1) {if(__b2c__trap){ERROR = 13;if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR NETWORK\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE;;
	@(SERVER) )
	    # Network code
            ADDRESS=`echo "${1%% FOR *}" | tr "," " " | tr "\"" " "`
            echo "if(strcmp(__b2c__data_server, \"${ADDRESS}\")) {strncpy(__b2c__data_server, \"${ADDRESS}\", $g_BUFFER_SIZE);" >> $g_CFILE

            # Setup the array of addresses
            TMP=${CTR}
            echo "__b2c__addr = calloc(${CTR}+1, sizeof(*__b2c__addr));" >> $g_CFILE
            until [[ ${TMP} -lt 0 ]]
            do
	        echo "if (strstr(${FILE[$TMP]}, \":\") == NULL) {ERROR = 10; RUNTIMEERROR(\"OPEN FOR NETWORK\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;}" >> $g_CFILE
	        echo "strncpy(__b2c__data_client, ${FILE[${TMP}]}, $g_BUFFER_SIZE); __b2c__host = strtok(__b2c__data_client, \":\"); __b2c__port = strtok(NULL, \":\");" >> $g_CFILE
		echo "if (strstr(${FILE[$TMP]}, \"INADDR_ANY:\") || strstr(${FILE[$TMP]}, \"*:\")){__b2c__addr[$TMP].sin_addr.s_addr = htonl(INADDR_ANY);} else" >> $g_CFILE
		echo "{ __b2c__he = gethostbyname(__b2c__host); if (__b2c__he == NULL || __b2c__he->h_addr == NULL) {if(__b2c__trap){ERROR = 11;if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR SERVER\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
		echo "__b2c__addr[$TMP].sin_addr = *((struct in_addr *)__b2c__he->h_addr);}" >> $g_CFILE
                echo "__b2c__addr[$TMP].sin_family = AF_INET; __b2c__addr[$TMP].sin_port = htons((long)atol(__b2c__port));" >> $g_CFILE
                ((TMP-=1))
	    done

            if [[ ${g_NETWORKTYPE} = "SCTP" ]]
            then
                echo "__b2c__handle = socket(AF_INET, ${g_SOCKTYPE}, IPPROTO_SCTP);" >> $g_CFILE
            else
                echo "__b2c__handle = socket(AF_INET, ${g_SOCKTYPE}, 0);" >> $g_CFILE
            fi
            echo "if (__b2c__handle == -1) {if(__b2c__trap){ERROR = 12;if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR SERVER\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE

            if [[ ${g_NETWORKTYPE} = "SCTP" ]]
	    then
                echo "memset(&__b2c__initmsg, 0, sizeof(__b2c__initmsg)); __b2c__initmsg.sinit_max_attempts = 3;" >> $g_CFILE
                echo "__b2c__initmsg.sinit_num_ostreams = ${g_SCTP_STREAMS}; __b2c__initmsg.sinit_max_instreams = ${g_SCTP_STREAMS};" >> $g_CFILE
                echo "setsockopt(${HANDLE}, IPPROTO_SCTP, SCTP_INITMSG, &__b2c__initmsg, sizeof(__b2c__initmsg));" >> $g_CFILE
	    fi

            echo "__b2c__to.tv_sec = $g_OPTION_SOCKET; __b2c__to.tv_usec = 0; setsockopt(__b2c__handle, SOL_SOCKET, SO_SNDTIMEO, &__b2c__to, sizeof(struct timeval));" >> $g_CFILE
            echo "setsockopt(__b2c__handle, SOL_SOCKET, SO_REUSEADDR, &__b2c__yes, sizeof(int));" >> $g_CFILE

            # Setup connection
            if [[ ${g_NETWORKTYPE} = "SCTP" ]]
            then
                # Perform a one-one SCTP bind for multiple homes
                echo "__b2c__result = sctp_bindx(__b2c__handle, (struct sockaddr *)__b2c__addr, ${CTR}+1, SCTP_BINDX_ADD_ADDR);" >> $g_CFILE
            else
                # Perform a bind for TCP or UDP
                echo "__b2c__result = bind(__b2c__handle, (struct sockaddr *)__b2c__addr, sizeof(struct sockaddr));" >> $g_CFILE
            fi
	    echo "free(__b2c__addr); if(__b2c__result == -1){if(__b2c__trap){ERROR = 17;if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR SERVER\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE

            if [[ ${g_NETWORKTYPE} = "MULTICAST" ]]
	    then
		echo "__b2c__imreq.imr_multiaddr.s_addr = inet_addr(__b2c__host); __b2c__imreq.imr_interface.s_addr = INADDR_ANY;" >> $g_CFILE
		echo "setsockopt(__b2c__handle, IPPROTO_IP, IP_ADD_MEMBERSHIP, &__b2c__imreq, sizeof(__b2c__imreq));" >> $g_CFILE
	    fi
            if [[ ${g_NETWORKTYPE} = "UDP" || ${g_NETWORKTYPE} = "BROADCAST" || ${g_NETWORKTYPE} = "MULTICAST" ]]
            then
	        echo "$HANDLE = __b2c__handle; }" >> $g_CFILE
            else
	        echo "__b2c__result = listen(__b2c__handle, $g_MAX_BACKLOG);" >> $g_CFILE
	        echo "if(__b2c__result == -1){if(__b2c__trap){ERROR = 18;if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR SERVER\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} } }" >> $g_CFILE
	        echo "__b2c__result = accept(__b2c__handle, NULL, 0);" >> $g_CFILE
	        echo "if(__b2c__result == -1){if(__b2c__trap){ERROR = 19;if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR SERVER\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
	        echo "$HANDLE= __b2c__result;" >> $g_CFILE
            fi;;
	@(DEVICE) )
	    echo "$HANDLE = open(${FILE[0]}, __b2c__option_open);" >> $g_CFILE
	    echo "if($HANDLE < 0){if(__b2c__trap){ERROR = 32; if(!__b2c__catch_set) RUNTIMEERROR(\"OPEN FOR DEVICE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE;;
    esac
    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
    then
        g_CATCH_USED=1
    fi
}

#-----------------------------------------------------------

function Handle_Readln
{
    # Local variables
    typeset VAR FROM STR

    # Check if FROM is available
    if [[ "$1" != +(* FROM *) ]]
    then
	echo -e "\nSyntax error: missing FROM in READLN statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the variablename without surrounding spaces
    VAR=$(echo ${1%% FROM *})

    # Get filedescriptor
    FROM=$(echo ${1##* FROM })

    # Check if var is string var
    if [[ "${VAR}" != +(*${g_STRINGSIGN}) && "${VAR%%\(*}" != +(*${g_STRINGSIGN}) && "${VAR%%\[*}" != +(*${g_STRINGSIGN}) ]]
    then
	echo -e "\nSyntax error: variable for READLN at line $g_COUNTER in file '$g_CURFILE' must be string!"
	exit 1
    fi

    # Check if string variable, and if so, if declared
    if [[ "${VAR}" = +(*${g_STRINGSIGN}) && "$VAR" != +(*.*) ]]
    then
        if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	then
	    echo "char *$VAR = NULL;" >> $g_HFILE
            Save_Main_Var "${VAR}" "char*"
	fi
    fi

    # Translate function to C function
    echo "__b2c__counter = 1; __b2c__assign = calloc(1, sizeof(char)); do{ if(fgets(__b2c__input__buffer, $g_BUFFER_SIZE, $FROM) == NULL) break;" >> $g_CFILE

    # Make sure internal var is copied to var of program
    echo "__b2c__assign = (char*)realloc(__b2c__assign, $g_BUFFER_SIZE*__b2c__counter*sizeof(char));" >> $g_CFILE
    echo " strncat(__b2c__assign, __b2c__input__buffer, $g_BUFFER_SIZE); __b2c__counter++;" >> $g_CFILE
    echo "} while (!strstr(__b2c__input__buffer, \"\n\") && strlen(__b2c__input__buffer));" >> $g_CFILE
    # Cut off last newline
    echo "if(__b2c__assign != NULL) {__b2c__ctr = strlen(__b2c__assign); if(__b2c__ctr > 0) __b2c__assign[__b2c__ctr-1] = '\0';}" >> $g_CFILE

    # Now see if we have a assoc or a normal variable
    if [[ "${VAR}" = +(*\(*\)) ]]
    then
        STR=${VAR#*\(}
        echo "__b2c__${VAR%%\(*}__location = __b2c__${VAR%%\(*}__add(${STR};" >> $g_CFILE
        echo "if(__b2c__${VAR%%\(*}__location->__b2c_value != NULL) free(__b2c__${VAR%%\(*}__location->__b2c_value); __b2c__${VAR%%\(*}__location->__b2c_value = __b2c__assign;" >> $g_CFILE
        # Check for relations
        Relate_Recurse "${VAR%%\(*}" "${STR}" "${VAR}" "-1"
    else
        echo "if($VAR != NULL) free($VAR); $VAR = __b2c__assign;" >> $g_CFILE
    fi
}

#-----------------------------------------------------------

function Handle_Writeln
{
    # Local variables
    typeset VAR TO EXP TOKEN

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in WRITELN statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get line to write to file
    EXP=$(echo ${1% TO *})

    # Get filedescriptor
    TO=$(echo ${1##* TO })

    # Start miniparser to see if we need to print something
    while [[ -n ${EXP} ]]
    do
        TOKEN=$(Mini_Parser "${EXP}")
        Print_Element "${TOKEN}" "${TO}"
        EXP="${EXP:${#TOKEN}+1}"
    done

    echo "fprintf($TO, \"\n\");" >> $g_CFILE
    echo "fflush($TO);" >> $g_CFILE
}

#-----------------------------------------------------------

function Handle_Getbyte
{
    # Local variables
    typeset POS FROM SIZE CHECK CHUNK

    # Check if FROM is available
    if [[ "$1" != +(* FROM *) ]]
    then
	echo -e "\nSyntax error: missing FROM in GETBYTE statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the variablename without surrounding spaces
    POS=$(echo ${1%% FROM *})

    # Get filedescriptor
    FROM=$(echo ${1##* FROM })

    # Check for optional chunksize
    if [[ $1 = +(* CHUNK *) ]]
    then
	CHUNK=${1##* CHUNK }
	FROM=${FROM%% CHUNK *}
    else
	CHUNK=
    fi

    # Check for optional return variable
    if [[ $1 = +(* SIZE *) ]]
    then
        FROM=${FROM%% SIZE *}
	SIZE=${1##* SIZE }
        if [[ -z $CHUNK ]]
        then
            CHUNK=$SIZE
	    SIZE="__b2c__counter"
        else
	    CHUNK=${CHUNK%% SIZE *}
        fi
    else
        if [[ -z $CHUNK ]]
        then
            CHUNK=1
        fi
	SIZE="__b2c__counter"
    fi

    # Variable may not be array, these should be defined with DECLARE
    if [[ -n $SIZE && "${SIZE}" != +(*\[*\]*) && "${SIZE}" != +(*.*) && "${SIZE}" != +(*\(*\)*) && "${SIZE}" != +(*-\>*) && "$SIZE" != "__b2c__counter" ]]
    then
	# Declare variable if not done yet, assuming long
        if [[ -z $(Get_Var ${SIZE} ${g_FUNCNAME}) ]]
	then
            Register_Numeric ${SIZE}
        fi
    fi

    # Type of file descriptor
    CHECK=$(Get_Var ${FROM} ${g_FUNCNAME})

    # Translate function to C function
    echo "if(__b2c__trap){if(__b2c__memory__check((void*)$POS, sizeof(__b2c__MEMTYPE))) {ERROR=1; if(!__b2c__catch_set) RUNTIMEERROR(\"GETBYTE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
    if [[ $CHECK = +(*int*) ]]
    then
        echo "if((${SIZE} = read($FROM, (void*)($POS), $CHUNK)) < 0)" >> $g_CFILE
        echo "{if(__b2c__trap){ERROR = 34; if(!__b2c__catch_set) RUNTIMEERROR(\"GETBYTE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
    else
        echo "${SIZE} = fread((void*)($POS), sizeof(__b2c__MEMTYPE), $CHUNK, $FROM);" >> $g_CFILE
    fi
    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
    then
        g_CATCH_USED=1
    fi
}

#-----------------------------------------------------------

function Handle_Putbyte
{
    # Local variables
    typeset VAR TO SIZE POS CHECK CHUNK

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in PUTBYTE statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the variablename without surrounding spaces
    POS=$(echo ${1%% TO *})

    # Get filedescriptor
    TO=$(echo ${1##* TO })

    # Check for optional chunksize
    if [[ $1 = +(* CHUNK *) ]]
    then
	CHUNK=${1##* CHUNK }
	TO=${TO%% CHUNK *}
    else
	CHUNK=
    fi

    # Check for optional return variable
    if [[ $1 = +(* SIZE *) ]]
    then
        TO=${TO%% SIZE *}
	SIZE=${1##* SIZE }
        if [[ -z $CHUNK ]]
        then
            CHUNK=$SIZE
	    SIZE="__b2c__counter"
        else
	    CHUNK=${CHUNK%% SIZE *}
        fi
    else
        if [[ -z $CHUNK ]]
        then
            CHUNK=1
        fi
	SIZE="__b2c__counter"
    fi

    # Variable may not be array, these should be defined with DECLARE
    if [[ -n $SIZE && "${SIZE}" != +(*\[*\]*) && "${SIZE}" != +(*.*) && "${SIZE}" != +(*\(*\)*) && "${SIZE}" != +(*-\>*) && "$SIZE" != "__b2c__counter" ]]
    then
	# Declare variable if not done yet, assuming long
	if [[ -z $(Get_Var ${SIZE} ${g_FUNCNAME}) ]]
	then
            Register_Numeric ${SIZE}
	fi
    fi

    # Type of file descriptor
    CHECK=$(Get_Var ${TO} ${g_FUNCNAME})

    # Translate function to C function
    echo "if(__b2c__trap){if(__b2c__memory__check((void*)$POS, sizeof(__b2c__MEMTYPE))) {ERROR=1; if(!__b2c__catch_set) RUNTIMEERROR(\"PUTBYTE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
    if [[ $CHECK = +(*int*) ]]
    then
        echo "if(($SIZE = write(${TO}, (void*)($POS), $CHUNK)) < 0)" >> $g_CFILE
        echo "{if(__b2c__trap){ERROR = 34; if(!__b2c__catch_set) RUNTIMEERROR(\"PUTBYTE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
    else
        echo "$SIZE = fwrite((void*)($POS), sizeof(__b2c__MEMTYPE), $CHUNK, $TO); fflush($TO);" >> $g_CFILE
    fi
    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
    then
        g_CATCH_USED=1
    fi
}

#-----------------------------------------------------------

function Handle_Getfile
{
    # Local variables
    typeset VAR FROM SIZE STR

    # Check if FROM is available
    if [[ "$1" != +(* FROM *) ]]
    then
	echo -e "\nSyntax error: missing FROM in GETFILE statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the variablename without surrounding spaces
    VAR=$(echo ${1%% FROM *})

    # Get dirdescriptor
    FROM=$(echo ${1##* FROM })

    # Check if var is string var
    if [[ "${VAR}" != +(*${g_STRINGSIGN}) && "${VAR%%\(*}" != +(*${g_STRINGSIGN}) && "${VAR%%\[*}" != +(*${g_STRINGSIGN}) ]]
    then
	echo -e "\nSyntax error: variable for GETFILE at line $g_COUNTER in file '$g_CURFILE' must be string!"
	exit 1
    fi

    # Check if string is declared
    if [[ "${VAR}" = +(*${g_STRINGSIGN}) && "$VAR" != +(*.*) ]]
    then
        if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	then
	    echo "char *$VAR = NULL;" >> $g_HFILE
            Save_Main_Var "${VAR}" "char*"
	fi
    fi

    # Translate function to C function
    echo "__b2c__dir = readdir($FROM);" >> $g_CFILE

    # Make sure internal var is copied to var of program
    echo "if(__b2c__dir != NULL) __b2c__assign = __b2c__strdup(__b2c__dir->d_name);" >> $g_CFILE
    echo "else __b2c__assign = calloc(1, sizeof(char));" >> $g_CFILE
    # Now see if we have an assoc or a normal variable
    if [[ "${VAR}" = +(*\(*\)) ]]
    then
	STR=${VAR#*\(}
	echo "__b2c__${VAR%%\(*}__location = __b2c__${VAR%%\(*}__add(${STR};" >> $g_CFILE
	echo "if(__b2c__${VAR%%\(*}__location->__b2c_value != NULL) free(__b2c__${VAR%%\(*}__location->__b2c_value); __b2c__${VAR%%\(*}__location->__b2c_value = __b2c__assign;" >> $g_CFILE
	# Check for relations
	Relate_Recurse "${VAR%%\(*}" "${STR}" "${VAR}" "-1"
    else
	echo "if($VAR != NULL) free($VAR); $VAR = __b2c__assign;" >> $g_CFILE
    fi
}

#-----------------------------------------------------------

function Handle_Receive
{
    # Local variables
    typeset VAR FROM STR CHUNK SIZE

    # Check if FROM is available
    if [[ "$1" != +(* FROM *) ]]
    then
	echo -e "\nSyntax error: missing FROM in RECEIVE statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the variablename without surrounding spaces
    VAR=$(echo ${1%% FROM *})

    # Get filedescriptor
    FROM=$(echo ${1##* FROM })

   # Check for optional chunksize
    if [[ $1 = +(* CHUNK *) ]]
    then
	CHUNK=${1##* CHUNK }
	FROM=${FROM%% CHUNK *}
    else
	CHUNK=$g_BUFFER_SIZE
    fi

    # Check for optional return variable
    if [[ $1 = +(* SIZE *) ]]
    then
        FROM=${FROM%% SIZE *}
	SIZE=${1##* SIZE }
	CHUNK=${CHUNK%% SIZE *}
    else
	SIZE=
    fi

    # Variable may not be array, these should be defined with DECLARE
    if [[ -n $SIZE && "${SIZE}" != +(*\[*\]*) && "${SIZE}" != +(*.*) && "${SIZE}" != +(*\(*\)*) && "${SIZE}" != +(*-\>*) ]]
    then
	# Declare variable if not done yet, assuming long
	if [[ -z $(Get_Var ${SIZE} ${g_FUNCNAME}) ]]
	then
            Register_Numeric ${SIZE}
	fi
    else
        if [[ -z $SIZE ]]
        then
	    SIZE="__b2c__counter"
        fi
    fi

    # Check if string variable, and if so, if declared
    if [[ "${VAR}" = +(*${g_STRINGSIGN}) && "$VAR" != +(*.*) ]]
    then
	if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	then
	    echo "char *$VAR = NULL;" >> $g_HFILE
            Save_Main_Var "${VAR}" "char*"
	fi
    fi

    # Translate function to C function
    echo "__b2c__assign = (char*)calloc(($CHUNK+1), sizeof(char));" >> $g_CFILE
    if [[ ${g_NETWORKTYPE} = "SCTP" ]]
    then
	echo "if(($SIZE = sctp_recvmsg($FROM, (void*)__b2c__assign, $CHUNK, 0, 0, 0, 0)) < 0)" >> $g_CFILE
    else
	echo "if(($SIZE = recv($FROM, (void*)__b2c__assign, $CHUNK, 0)) < 0)" >> $g_CFILE
    fi
    echo "{if(__b2c__trap){ERROR = 14;if(!__b2c__catch_set) RUNTIMEERROR(\"RECEIVE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE

    # Now see if we have an assoc or a normal variable
    if [[ "${VAR}" = +(*\(*\)) ]]
    then
	STR=${VAR#*\(}
	echo "__b2c__${VAR%%\(*}__location = __b2c__${VAR%%\(*}__add(${STR};" >> $g_CFILE
	echo "if(__b2c__${VAR%%\(*}__location->__b2c_value != NULL) free(__b2c__${VAR%%\(*}__location->__b2c_value); __b2c__${VAR%%\(*}__location->__b2c_value = __b2c__assign;" >> $g_CFILE
	# Check for relations
	Relate_Recurse "${VAR%%\(*}" "${STR}" "${VAR}" "-1"
    elif [[ "${VAR}" = +(*${g_STRINGSIGN}) || "${VAR%%\[*}" = +(*${g_STRINGSIGN}) ]]
    then
	echo "if($VAR != NULL) free($VAR); $VAR = __b2c__assign;" >> $g_CFILE
    else
	echo "memcpy((void*)${VAR}, (void*)__b2c__assign, $CHUNK); free(__b2c__assign);" >> $g_CFILE
    fi
    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
    then
        g_CATCH_USED=1
    fi
}

#-----------------------------------------------------------

function Handle_Send
{
    # Local variables
    typeset VAR TO CHUNK SIZE

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in SEND statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the variablename without surrounding spaces
    VAR=$(echo ${1%% TO *})

    # Get filedescriptor
    TO=$(echo ${1##* TO })

   # Check for optional chunksize
    if [[ $1 = +(* CHUNK *) ]]
    then
	CHUNK=${1##* CHUNK }
	TO=${TO%% CHUNK *}
    else
	CHUNK="strlen($VAR)"
    fi

    # Check for optional return variable
    if [[ $1 = +(* SIZE *) ]]
    then
        TO=${TO%% SIZE *}
	SIZE=${1##* SIZE }
        if [[ $CHUNK = +(* SIZE *) ]]
        then
	    CHUNK=${CHUNK%% SIZE *}
        fi
    else
	SIZE=
    fi

    # Variable may not be array, these should be defined with DECLARE
    if [[ -n $SIZE && "${SIZE}" != +(*\[*\]*) && "${SIZE}" != +(*.*) && "${SIZE}" != +(*\(*\)*) && "${SIZE}" != +(*-\>*) ]]
    then
	# Declare variable if not done yet, assuming long
	if [[ -z $(Get_Var ${SIZE} ${g_FUNCNAME}) ]]
	then
            Register_Numeric ${SIZE}
	fi
    else
        if [[ -z $SIZE ]]
        then
	    SIZE="__b2c__counter"
        fi
    fi

    # Translate function to C function
    if [[ ${g_NETWORKTYPE} = "SCTP" ]]
    then
        echo "if(($SIZE = sctp_sendmsg($TO, (void*)$VAR, $CHUNK, NULL, 0, 0, 0, 0, 0, 0)) < 0)" >> $g_CFILE
    else
        echo "if(($SIZE = send($TO, (void*)$VAR, $CHUNK, 0)) < 0)" >> $g_CFILE
    fi
    echo "{if(__b2c__trap){ERROR = 15; if(!__b2c__catch_set) RUNTIMEERROR(\"SEND\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
    then
        g_CATCH_USED=1
    fi
}

#-----------------------------------------------------------

function Handle_Getline
{
    # Local variables
    typeset VAR FROM STR

    # Check if FROM is available
    if [[ "$1" != +(* FROM *) ]]
    then
	echo -e "\nSyntax error: missing FROM in GETLINE statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the variablename without surrounding spaces
    VAR=$(echo ${1%% FROM *})

    # Get filedescriptor
    FROM=$(echo ${1##* FROM })

    # Check if var is string var
    if [[ "${VAR}" != +(*${g_STRINGSIGN}) && "${VAR%%\(*}" != +(*${g_STRINGSIGN}) && "${VAR%%\[*}" != +(*${g_STRINGSIGN}) ]]
    then
	echo -e "\nSyntax error: variable for GETLINE at line $g_COUNTER in file '$g_CURFILE' must be string!"
	exit 1
    fi

    # Check if string variable, and if so, if declared
    if [[ "${VAR}" = +(*${g_STRINGSIGN}) && "$VAR" != +(*.*) ]]
    then
	if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	then
	    echo "char *$VAR = NULL;" >> $g_HFILE
            Save_Main_Var "${VAR}" "char*"
	fi
    fi

    # Translate function to C function
    echo "if ($FROM == NULL || *$FROM == '\0') {__b2c__assign = (char*)calloc(1, sizeof(char));} else { __b2c__assign = $FROM; while(*$FROM != '\0' && *$FROM != '\n') $FROM++;" >> $g_CFILE

    # Make sure internal var is copied to var of program
    echo "__b2c__assign = strndup(__b2c__assign, (size_t)($FROM-__b2c__assign+1)); __b2c__assign[strlen(__b2c__assign)-1]='\0'; if(*$FROM == '\n') $FROM++;}" >> $g_CFILE

    # Now see if we have an assoc or a normal variable
    if [[ "${VAR}" = +(*\(*\)) ]]
    then
	STR=${VAR#*\(}
	echo "__b2c__${VAR%%\(*}__location = __b2c__${VAR%%\(*}__add(${STR};" >> $g_CFILE
	echo "if(__b2c__${VAR%%\(*}__location->__b2c_value != NULL) free(__b2c__${VAR%%\(*}__location->__b2c_value); __b2c__${VAR%%\(*}__location->__b2c_value = __b2c__assign;" >> $g_CFILE
	# Check for relations
	Relate_Recurse "${VAR%%\(*}" "${STR}" "${VAR}" "-1"
    else
	echo "if($VAR != NULL) free($VAR); $VAR = __b2c__assign;" >> $g_CFILE
    fi
}

#-----------------------------------------------------------

function Handle_Putline
{
    # Local variables
    typeset VAR TO EXP TOKEN

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in PUTLINE statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get text to add
    EXP=$(echo ${1% TO *})

    # Get memorydescriptor
    TO=$(echo ${1##* TO })

    # Start miniparser to see if we need to print something
    while [[ -n ${EXP} ]]
    do
        TOKEN=$(Mini_Parser "${EXP}")
	# Check if var is string var
	if [[ "${TOKEN%%\(*}" = +(*${g_STRINGSIGN}*) || "${TOKEN%%\(*}" = +(*${g_DQUOTESIGN}*) || "${TOKEN%%\(*}" = +(gettext*|ngettext*) ]]
	then
	    echo "strcat($TO, $TOKEN); $TO+=strlen($TOKEN);" >> $g_CFILE
	else
	    echo "strcat($TO, STR${g_STRINGSIGN}($TOKEN)); $TO+=strlen(STR${g_STRINGSIGN}($TOKEN));" >> $g_CFILE
	fi
        EXP="${EXP:${#TOKEN}+1}"
    done

    echo "strcat($TO, \"\n\"); $TO+=1;" >> $g_CFILE
}

#-----------------------------------------------------------

function Handle_Import
{
    # Local variables
    typeset TMP SYM LIB CHECK TOKEN PTR TYPE ALIAS TYPE

    # Check if FROM is available
    if [[ "$1" != +(* FROM *) ]]
    then
	echo -e "\nSyntax error: missing FROM in IMPORT statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the symbolname without surrounding spaces and doublequotes
    if [[ "$1" = +(*\(*) ]]
    then
	SYM=`echo ${1%%\(*} | tr -d "\042"`; TMP=${1#* FROM }
	TOKEN=$(echo ${1%%\)*})
    else
	SYM=`echo ${1%% FROM *} | tr -d "\042"`; TMP=${1#* FROM }
	TOKEN=
    fi

    # Check if TYPE is available
    if [[ "$1" != +(* TYPE *) ]]
    then
	echo -e "\nSyntax error: missing TYPE in IMPORT statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get library and type
    LIB=$(echo ${TMP%% TYPE *})
    TYPE=$(echo ${TMP##* TYPE })

    # Check if ALIAS is there
    if [[ $TYPE = +(* ALIAS *) ]]
    then
	ALIAS=`echo ${TYPE##* ALIAS } | tr -d "\042"`
	echo "#define $ALIAS $SYM" >> $g_HFILE
	g_IMPORTED="$ALIAS $g_IMPORTED"
	TYPE=${TYPE%% ALIAS *}
    fi

    # If library is libm or libc, skip dlopen as we're linking with those anyway
    if [[ $LIB != +(*libc.so*) && $LIB != +(*libm.so*) ]]
    then
        # Link flags
        if [[ `uname` != "OSF1" && `uname` != +(*BSD*) && ${g_LDFLAGS} != +(*ldl*) ]]
        then
            g_LDFLAGS="${g_LDFLAGS} -ldl"
        fi

	# Create name from libname
        PTR="${LIB//[[:punct:]]/}"

	# Check if variable was declared
	if [[ -z $(Get_Var __b2c__dlopen__pointer_$PTR ${g_FUNCNAME}) ]]
	then
	    echo "void* __b2c__dlopen__pointer_$PTR;" >> $g_CFILE
            if [[ -z ${g_FUNCNAME} ]]
            then
                Save_Main_Var "__b2c__dlopen__pointer_${PTR}" "void*"
            else
                Save_Func_Var "__b2c__dlopen__pointer_${PTR}" "${g_FUNCNAME}" "void*"
            fi
	    echo "__b2c__dlopen__pointer_$PTR = dlopen($LIB, RTLD_LAZY);" >> $g_CFILE
	fi
	echo "if(__b2c__dlopen__pointer_$PTR == NULL){if(__b2c__trap){ERROR = 3; if(!__b2c__catch_set) RUNTIMEERROR(\"IMPORT\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE

        # Create prototype
	echo "$TYPE (*$SYM)(${TOKEN#*\(});" >> $g_HFILE

	# Translate to C function
	echo "*(${TYPE}**) (&$SYM) = dlsym(__b2c__dlopen__pointer_$PTR, \"$SYM\");" >> $g_CFILE
	echo "if($SYM == NULL) {if(__b2c__trap){ERROR = 4; if(!__b2c__catch_set) RUNTIMEERROR(\"IMPORT\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
        if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
        then
            g_CATCH_USED=1
        fi
    fi

    # Make symbol known to parser
    g_IMPORTED="$SYM $g_IMPORTED"
}

#-----------------------------------------------------------
# $1 = TYPE - $2 = VAR - $3 = ARRAY - $4 = static

function Normal_Dyn_Array
{
    typeset i j TYPE NR OLD TMP_ARR IDX END ORG_TYPE AM

    for i in $2
    do
        TYPE="$1"
        g_DYNAMICARRAYS="${g_DYNAMICARRAYS} $i@${g_FUNCNAME}"

	# Initialize strings
	if [[ "${TYPE}" = +(*STRING*|*char\*) || "${i}" = +(*${g_STRINGSIGN}*) ]]
	then
            if [[ $3 = +(* *) ]]
            then
	        echo -e "\nSyntax error: string array cannot have more than one dimension line $g_COUNTER in file '$g_CURFILE'!"
	        exit 1
            fi
            if [[ -n $g_FUNCNAME ]]
            then
                echo "$TYPE* $i;" >> $g_CFILE
                Save_Func_Var "${i}" "${g_FUNCNAME}" "${TYPE}"
                g_STRINGARGS="$g_STRINGARGS long __b2c_array_$i;"
                if [[ $4 -eq 0 ]]
                then
                    g_STRINGARRAYS="$g_STRINGARRAYS for(__b2c__ctr=0; __b2c__ctr<__b2c_array_$i+$g_OPTION_BASE; __b2c__ctr++)if($i[__b2c__ctr]!=NULL){free($i[__b2c__ctr]);}"
		    g_LOCALSTRINGS="$g_LOCALSTRINGS ${i}"
                fi
            else
                echo "$TYPE* $i;" >> $g_HFILE
                Save_Main_Var "${i}" "${TYPE}"
	        echo "long __b2c_array_$i;" >> $g_HFILE
            fi
	    echo "$i = (${TYPE}*)calloc(${3}+$g_OPTION_BASE, sizeof(${TYPE}));" >> $g_CFILE
            echo "__b2c_array_$i = ${3};" >> $g_CFILE
	    echo "for(__b2c__ctr=0; __b2c__ctr < $3+$g_OPTION_BASE; __b2c__ctr++) $i[__b2c__ctr] = calloc(1, sizeof(char));" >> $g_CFILE
        else
            ORG_TYPE="${TYPE}"
            # Count elements
            NR=0
            for j in $3                
            do
                ((NR+=1))
                TYPE="${TYPE}*"
            done

            # Declare top most dimension
            if [[ -n $g_FUNCNAME ]]
            then
                echo "$TYPE $i;" >> $g_CFILE
                Save_Func_Var "${i}" "${g_FUNCNAME}" "${ORG_TYPE}"
                if [[ $4 -eq 0 ]]
                then
		    g_LOCALSTRINGS="$g_LOCALSTRINGS ${i}"
                else
                    AM=`echo ${TYPE} | tr -d -c "\*" | wc -c`
                    g_STATICARRAYS="$g_STATICARRAYS ${i}:${AM}"
                fi
            else
                echo "$TYPE $i;" >> $g_HFILE
                Save_Main_Var "${i}" "${ORG_TYPE}"
            fi
            echo "$i = (${TYPE})calloc((size_t)${3%% *}+$g_OPTION_BASE, sizeof(${TYPE%\**}));" >> $g_CFILE

            # Proceed with other dimensions in array
            if [[ $NR -gt 1 ]]
            then
                OLD=${3%% *}
                TMP_ARR=${3#* }
                NR=0
                IDX="$i"
                END=

                # Construct array initialization
                for j in $TMP_ARR
                do
                    ((NR+=1))
                    if [[ -n $g_FUNCNAME ]]
                    then
                        g_STRINGARGS="$g_STRINGARGS int __b2c_${i}${NR};"
                    else
                        echo "int __b2c_${i}${NR};" >> $g_HFILE
                    fi
                    IDX="$IDX[__b2c_${i}${NR}]"
                    echo "for(__b2c_${i}${NR} = 0; __b2c_${i}${NR} < $OLD+$g_OPTION_BASE; __b2c_${i}${NR}++){" >> $g_CFILE
                    TYPE="${TYPE%\**}"
                    echo "${IDX} = (${TYPE})calloc((size_t)${j}+$g_OPTION_BASE, sizeof(${TYPE%\**}));" >> $g_CFILE
                    END="$END }"
                    OLD="$j"
                done
                echo ${END} >> $g_CFILE
                TYPE="${TYPE%\**}"

                # De-initialize array members in case of FUNCTION
                if [[ -n $g_FUNCNAME && $NR -gt 0 ]]
                then
                    NR=1
                    END=
                    for j in ${3% *}
                    do
                        if [[ $4 -eq 0 ]]
                        then
                            g_STRINGARRAYS="$g_STRINGARRAYS for(__b2c_${i}${NR} = 0; __b2c_${i}${NR} < $j+$g_OPTION_BASE; __b2c_${i}${NR}++){"
                            END="${END} if(${IDX}!=NULL) free (${IDX}); }"
                            IDX="${IDX%\[*}"
                            ((NR+=1))
                        fi
                    done
                    if [[ $4 -eq 0 ]]
                    then
                        g_STRINGARRAYS="$g_STRINGARRAYS $END"
                    fi
                fi
            fi
        fi
    done
}

#-----------------------------------------------------------
# $1 = TYPE - $2 = VAR - $3 = ARRAY - $4 = static

function Record_Dyn_Array
{
    typeset i j TYPE NR OLD TMP_ARR IDX END ORG_TYPE AM

    for i in $2
    do
        TYPE="$1"
        g_DYNAMICARRAYS="${g_DYNAMICARRAYS} $i@${g_FUNCNAME}"

	# Initialize strings
	if [[ "${TYPE}" = +(*STRING*|*char\*) || "${i}" = +(*${g_STRINGSIGN}*) ]]
	then
            if [[ $3 = +(* *) ]]
            then
	        echo -e "\nSyntax error: string array cannot have more than one dimension line $g_COUNTER in file '$g_CURFILE'!"
	        exit 1
            fi
	    g_RECORDEND_BODY="${g_RECORDEND_BODY} $g_RECORDVAR.$i = (${TYPE}*)calloc(${3}+$g_OPTION_BASE, sizeof(${TYPE}));"
            if [[ -n $g_FUNCNAME ]]
            then
                echo "$TYPE* $i;" >> $g_CFILE
                Save_Func_Var "${i}" "${g_FUNCNAME}" "${TYPE}"
		g_RECORDEND_BODY="${g_RECORDEND_BODY} long __b2c_array_$i; __b2c_array_$i = ${3}; for(__b2c__ctr=0; __b2c__ctr<${3}+$g_OPTION_BASE; __b2c__ctr++) $g_RECORDVAR.$i[__b2c__ctr] = calloc(1, sizeof(char));"
                if [[ $4 -eq 0 ]]
                then
		    g_STRINGARRAYS="$g_STRINGARRAYS for(__b2c__ctr=0; __b2c__ctr<__b2c_array_$i+$g_OPTION_BASE; __b2c__ctr++)if($g_RECORDVAR.$i[__b2c__ctr]!=NULL){free($g_RECORDVAR.$i[__b2c__ctr]);}"
		    g_LOCALSTRINGS="$g_LOCALSTRINGS $g_RECORDVAR.${i}"
                fi
            else
                echo "$TYPE* $i;" >> $g_HFILE
                Save_Main_Var "${i}" "${TYPE}"
                g_RECORDEND_HEADER="${g_RECORDEND_HEADER} long __b2c_array_$i;"
		g_RECORDEND_BODY="${g_RECORDEND_BODY} __b2c_array_$i = $3; for(__b2c__ctr=0; __b2c__ctr<$3+$g_OPTION_BASE; __b2c__ctr++) $g_RECORDVAR.$i[__b2c__ctr] = calloc(1, sizeof(char));"
            fi
        else
            ORG_TYPE="${TYPE}"
            # Count elements
            NR=0
            for j in $3                
            do
                ((NR+=1))
                TYPE="${TYPE}*"
            done

            # Declare top most dimension
            if [[ -n $g_FUNCNAME ]]
            then
                echo "$TYPE $i;" >> $g_CFILE
                Save_Func_Var "${i}" "${g_FUNCNAME}" "${ORG_TYPE}"
                if [[ $4 -eq 0 ]]
                then
		    g_LOCALSTRINGS="$g_LOCALSTRINGS $g_RECORDVAR.${i}"
                else
                    AM=`echo ${TYPE} | tr -d -c "\*" | wc -c`
                    g_STATICARRAYS="$g_STATICARRAYS ${i}:${AM}"
                fi
            else
                echo "$TYPE $i;" >> $g_HFILE
                Save_Main_Var "${i}" "${ORG_TYPE}"
            fi
	    g_RECORDEND_BODY="${g_RECORDEND_BODY} $g_RECORDVAR.$i = (${TYPE})calloc((size_t)${3%% *}+$g_OPTION_BASE, sizeof(${TYPE%\**}));"

            # Proceed with other dimensions in array
            if [[ $NR -gt 1 ]]
            then
                OLD=${3%% *}
                TMP_ARR=${3#* }
                NR=0
                IDX="$g_RECORDVAR.$i"
                END=

                # Construct array initialization
                for j in $TMP_ARR
                do
                    ((NR+=1))
                    if [[ -n $g_FUNCNAME ]]
                    then
                        g_STRINGARGS="${g_STRINGARGS} int __b2c_${i}${NR};"
                    else
                        g_RECORDEND_HEADER="${g_RECORDEND_HEADER} int __b2c_${i}${NR};"
                    fi
                    IDX="$IDX[__b2c_${i}${NR}]"
                    g_RECORDEND_BODY="${g_RECORDEND_BODY} for(__b2c_${i}${NR} = 0; __b2c_${i}${NR} < $OLD+$g_OPTION_BASE; __b2c_${i}${NR}++){"
                    TYPE="${TYPE%\**}"
                    g_RECORDEND_BODY="${g_RECORDEND_BODY} ${IDX} = (${TYPE})calloc((size_t)${j}+$g_OPTION_BASE, sizeof(${TYPE%\**}));"
                    END="$END }"
                    OLD="$j"
                done
                g_RECORDEND_BODY="${g_RECORDEND_BODY} ${END}"
                TYPE="${TYPE%\**}"

                # De-initialize array members in case of FUNCTION
                if [[ -n $g_FUNCNAME && $NR -gt 0 ]]
                then
                    NR=1
                    END=
                    for j in ${3% *}
                    do
                        if [[ $4 -eq 0 ]]
                        then
                            g_STRINGARRAYS="$g_STRINGARRAYS for(__b2c_${i}${NR} = 0; __b2c_${i}${NR} < $j+$g_OPTION_BASE; __b2c_${i}${NR}++){"
                            END="${END} if(${IDX}!=NULL) free (${IDX}); }"
                            IDX="${IDX%\[*}"
                            ((NR+=1))
                        fi
                    done
                    if [[ $4 -eq 0 ]]
                    then
                        g_STRINGARRAYS="$g_STRINGARRAYS $END"
                    fi
                fi
            fi
        fi
    done
}

#-----------------------------------------------------------

function Handle_Declare
{
    # Local variables
    typeset VAR TYPE CHECK NEW VALUE OPTION ARRAY i PTR TOKEN
    typeset -i CTR

    if [[ -n $g_RECORDNAME ]]
    then
	echo -e "\nSyntax error: DECLARE/GLOBAL cannot be used within a RECORD at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    #  Check on a GLOBAL RECORD
    if [[ "$1" = +(*RECORD *) ]]
    then
	# Translate to C typedef struct
	g_RECORDNAME="RECORD_${g_COUNTER}"
	echo "struct $g_RECORDNAME{" >> $g_HFILE
	g_RECORDVAR=${1#* }
	# Store current function name
	if [[ -n $g_FUNCNAME ]]
	then
	    g_RECORDCACHE=$g_FUNCNAME
	    g_FUNCNAME=
	fi
    else
	# Get the variablename and type
	if [[ "$1" = +(* TYPE *) ]]
	then
            VAR=$(echo "${1%% TYPE *}")
	    TYPE=$(echo "${1##* TYPE }")
	    if [[ ${TYPE} = +(* ARRAY *) ]]
	    then
		ARRAY=${TYPE##* ARRAY }
		TYPE=${TYPE%% ARRAY *}
	    fi
	elif [[ "$1" = +(* ASSOC *) ]]
	then
	    VAR=$(echo "${1%% ASSOC *}")
	    TYPE=$(echo "${1##* ASSOC }")
	else
	    if [[ "${1}" = +(* ARRAY *) ]]
	    then
		ARRAY=${1##* ARRAY }
	        VAR=$(echo "${1%% ARRAY *}")
            elif [[ "${@}" = +(DIR|FILE|*int|*short|*long|*float|*double|*char|void|STRING|NUMBER|FLOATING) && "${@}" != +(*TYPE*) ]]
            then
	        echo -e "\nSyntax error: missing TYPE keyword in DECLARE/GLOBAL at line $g_COUNTER in file '$g_CURFILE'!"
	        exit 1
            else
	        VAR=$(echo "${1}")
	    fi
	    if [[ "${VAR}" = +(*${g_STRINGSIGN}*) ]]
	    then
		TYPE="char*"
	    elif [[ "${VAR}" = +(*${g_FLOATSIGN}*) ]]
	    then
		TYPE="double"
	    else
		TYPE="${g_VARTYPE}"
	    fi
	fi

        # Check if variable was already declared - no record and not a function pointer?
        if [[ "$VAR" != +(*.*) && "$VAR" != +(\(*) ]]
        then
            IFS=","
	    for i in ${VAR// /}
            do
                if [[ -n $(Get_Var "${i%%=*}") ]]
                then
	            echo -e "\nSyntax error: variable '${i}' in DECLARE/GLOBAL statement at line $g_COUNTER in file '$g_CURFILE' was defined previously!"
	            exit 1
                fi
            done
            IFS="${g_ORGIFS}"
        fi

	# Check for associative array
	if [[ "${1}" = +(* ASSOC *) ]]
	then
	    for i in ${VAR//,/ }
	    do
		echo "struct __b2c__${i}_type {char *__b2c_key; ${TYPE} __b2c_value;};" >> $g_HFILE
		echo "struct __b2c__${i}_type *__b2c__${i} = { NULL }; struct __b2c__${i}_type *__b2c__${i}__location; size_t __b2c__${i}_idx = 0;" >> $g_HFILE
                Save_Main_Var "__b2c__${i}_type" "__b2c__${i}_type"

		echo "static int __b2c__${i}_comp(const void *__b2c__m1, const void *__b2c__m2){ " >> $g_HFILE
		echo "struct __b2c__${i}_type *__b2c__mi1 = (struct __b2c__${i}_type *) __b2c__m1;" >> $g_HFILE
		echo "struct __b2c__${i}_type *__b2c__mi2 = (struct __b2c__${i}_type *) __b2c__m2;" >> $g_HFILE
		echo "if(__b2c__mi1->__b2c_key == NULL && __b2c__mi2->__b2c_key == NULL) return 0;" >> $g_HFILE
		echo "if(__b2c__mi1->__b2c_key == NULL && __b2c__mi2->__b2c_key != NULL) return 1;" >> $g_HFILE
		echo "if(__b2c__mi1->__b2c_key != NULL && __b2c__mi2->__b2c_key == NULL) return -1;" >> $g_HFILE
		echo "return strcmp(__b2c__mi1->__b2c_key, __b2c__mi2->__b2c_key); }" >> $g_HFILE

                echo "static int __b2c__${i}_sort(const void *__b2c__m1, const void *__b2c__m2){" >> $g_HFILE
		echo "struct __b2c__${i}_type *__b2c__mi1 = (struct __b2c__${i}_type *) __b2c__m1;" >> $g_HFILE
		echo "struct __b2c__${i}_type *__b2c__mi2 = (struct __b2c__${i}_type *) __b2c__m2;" >> $g_HFILE
                if [[ ${i} = +(*${g_STRINGSIGN}*) || ${TYPE} = +(*STRING*) || ${TYPE} = +(*char\**) ]]
		then
		    echo "if(__b2c__mi1->__b2c_value == NULL && __b2c__mi2->__b2c_value == NULL) return 0;" >> $g_HFILE
		    echo "if(__b2c__mi1->__b2c_value == NULL && __b2c__mi2->__b2c_value != NULL) return 1;" >> $g_HFILE
		    echo "if(__b2c__mi1->__b2c_value != NULL && __b2c__mi2->__b2c_value == NULL) return -1;" >> $g_HFILE
		    echo "return strcmp(__b2c__mi1->__b2c_value, __b2c__mi2->__b2c_value); }" >> $g_HFILE
		else
		    echo "if(__b2c__mi1->__b2c_value == __b2c__mi2->__b2c_value) return 0;" >> $g_HFILE
		    echo "else {if(__b2c__mi1->__b2c_value < __b2c__mi2->__b2c_value) return -1;" >> $g_HFILE
		    echo "else return 1; } }" >> $g_HFILE
                fi

                echo "static int __b2c__${i}_sort_down(const void *__b2c__m1, const void *__b2c__m2){" >> $g_HFILE
		echo "struct __b2c__${i}_type *__b2c__mi1 = (struct __b2c__${i}_type *) __b2c__m1;" >> $g_HFILE
		echo "struct __b2c__${i}_type *__b2c__mi2 = (struct __b2c__${i}_type *) __b2c__m2;" >> $g_HFILE
                if [[ ${i} = +(*${g_STRINGSIGN}*) || ${TYPE} = +(*STRING*) || ${TYPE} = +(*char\**) ]]
		then
		    echo "if(__b2c__mi1->__b2c_value == NULL && __b2c__mi2->__b2c_value == NULL) return 0;" >> $g_HFILE
		    echo "if(__b2c__mi1->__b2c_value == NULL && __b2c__mi2->__b2c_value != NULL) return -1;" >> $g_HFILE
		    echo "if(__b2c__mi1->__b2c_value != NULL && __b2c__mi2->__b2c_value == NULL) return 1;" >> $g_HFILE
		    echo "return strcmp(__b2c__mi2->__b2c_value, __b2c__mi1->__b2c_value); }" >> $g_HFILE
		else
		    echo "if(__b2c__mi1->__b2c_value == __b2c__mi2->__b2c_value) return 0;" >> $g_HFILE
		    echo "else {if(__b2c__mi1->__b2c_value < __b2c__mi2->__b2c_value) return 1;" >> $g_HFILE
		    echo "else return -1; } }" >> $g_HFILE
                fi

		echo "struct __b2c__${i}_type *__b2c__${i}__add_secure(int __b2c__action, char *__b2c__index, ...){struct __b2c__${i}_type __b2c__${i}_key, *__b2c__${i}__result = NULL; char *__b2c__nxt; va_list __b2c__ap; size_t __b2c__x;" >> $g_HFILE
                echo "__b2c__${i}_key.__b2c_key = __b2c__strdup(__b2c__index); va_start (__b2c__ap, __b2c__index); while((__b2c__nxt = va_arg (__b2c__ap, char *)) != NULL){" >> $g_HFILE
                echo "__b2c__${i}_key.__b2c_key = realloc(__b2c__${i}_key.__b2c_key, (strlen(__b2c__${i}_key.__b2c_key)+strlen(__b2c__nxt)+2)*sizeof(char)); strcat(__b2c__${i}_key.__b2c_key, \" \"); strcat(__b2c__${i}_key.__b2c_key, __b2c__nxt); } va_end (__b2c__ap);" >> $g_HFILE
                echo "for(__b2c__x=0; __b2c__x < __b2c__${i}_idx; __b2c__x++) if(!strcmp(__b2c__${i}_key.__b2c_key, __b2c__${i}[__b2c__x].__b2c_key)) {__b2c__${i}__result = &__b2c__${i}[__b2c__x]; break;}" >> $g_HFILE
                echo "if(__b2c__${i}__result == NULL && __b2c__action == 1){__b2c__${i}_idx++; __b2c__${i} = (struct __b2c__${i}_type *) realloc (__b2c__${i}, __b2c__${i}_idx * sizeof (struct __b2c__${i}_type));" >> $g_HFILE
		echo "__b2c__${i}[__b2c__${i}_idx - 1].__b2c_key = __b2c__${i}_key.__b2c_key; __b2c__${i}[__b2c__${i}_idx-1].__b2c_value = 0;" >> $g_HFILE
                echo "__b2c__${i}__result = &__b2c__${i}[__b2c__${i}_idx - 1];} else free(__b2c__${i}_key.__b2c_key); return(__b2c__${i}__result);}" >> $g_HFILE
                echo "#define __b2c__${i}__add(...) __b2c__${i}__add_secure(1, __VA_ARGS__, NULL)" >> $g_HFILE
                echo "#define __b2c__${i}__find(...) __b2c__${i}__add_secure(0, __VA_ARGS__, NULL)" >> $g_HFILE

		echo "void __b2c__${i}__del(struct __b2c__${i}_type *__b2c__${i}__arg){size_t __b2c__x, __b2c__y;" >> $g_HFILE
		echo "if(__b2c__${i}__arg != NULL) {for(__b2c__x=0; __b2c__x < __b2c__${i}_idx; __b2c__x++) if(!strcmp(__b2c__${i}__arg->__b2c_key, __b2c__${i}[__b2c__x].__b2c_key)) break;" >> $g_HFILE
                echo "free(__b2c__${i}[__b2c__x].__b2c_key); for(__b2c__y=__b2c__x; __b2c__y < __b2c__${i}_idx-1; __b2c__y++) __b2c__${i}[__b2c__y] = __b2c__${i}[__b2c__y+1];" >> $g_HFILE
		echo "__b2c__${i}_idx--; __b2c__${i} = (struct __b2c__${i}_type *) realloc (__b2c__${i}, __b2c__${i}_idx * sizeof (struct __b2c__${i}_type));} }" >> $g_HFILE

		echo "${TYPE} _${i}(char *__b2c__index, ...){struct __b2c__${i}_type __b2c__${i}_key, *__b2c__${i}__result = NULL; char *__b2c__nxt; va_list __b2c__ap; size_t __b2c__x;" >> $g_HFILE
                echo "__b2c__${i}_key.__b2c_key = __b2c__strdup(__b2c__index); va_start (__b2c__ap, __b2c__index); while((__b2c__nxt = va_arg (__b2c__ap, char *)) != NULL){" >> $g_HFILE
                echo "__b2c__${i}_key.__b2c_key = realloc(__b2c__${i}_key.__b2c_key, (strlen(__b2c__${i}_key.__b2c_key)+strlen(__b2c__nxt)+2)*sizeof(char)); strcat(__b2c__${i}_key.__b2c_key, \" \"); strcat(__b2c__${i}_key.__b2c_key, __b2c__nxt); } va_end (__b2c__ap);" >> $g_HFILE
                echo "for(__b2c__x=0; __b2c__x < __b2c__${i}_idx; __b2c__x++) if(!strcmp(__b2c__${i}_key.__b2c_key, __b2c__${i}[__b2c__x].__b2c_key)) {__b2c__${i}__result = &__b2c__${i}[__b2c__x]; break;} free(__b2c__${i}_key.__b2c_key);" >> $g_HFILE

		if [[ ${i} = +(*${g_STRINGSIGN}*) || ${TYPE} = +(*STRING*) || ${TYPE} = +(*char\**) ]]
		then
		    echo "if(__b2c__${i}__result == NULL) return(\"\"); return __b2c__${i}__result->__b2c_value;}" >> $g_HFILE
		else
		    echo "if(__b2c__${i}__result == NULL) return(0); return __b2c__${i}__result->__b2c_value;}" >> $g_HFILE
		fi
                echo "#define ${i}(...) _${i}(__VA_ARGS__, NULL)" >> $g_HFILE
                Save_Main_Var "${i}" "${TYPE}"
	    done

        # Check if it is a known type, if not BaCon has to use external .h file
        elif [[ ${TYPE%%\**} != +(DIR|FILE|*short|*int|*long|*float|*double|*char|void|STRING|NUMBER|FLOATING) ]]
        then
	    if [[ "$VAR" = +(*=*) ]]
	    then
	        echo "$TYPE $VAR;" >> $g_HFILE
		Save_Main_Var "${VAR}" "${TYPE}"
	    else
		for i in ${VAR//,/ }
		do
	            echo "$TYPE $i;" >> $g_HFILE
		    Save_Main_Var "${i}" "${TYPE}"
		done
	    fi

	#  Check for dynamic array declaration
	elif [[ -n ${ARRAY} ]]
	then
            Normal_Dyn_Array "$TYPE" "${VAR//,/ }" "${ARRAY//,/ }"

	# Check if var is string var
	elif [[ ( "${VAR}" = +(*${g_STRINGSIGN}*) || "${TYPE}" = +(STRING|char\*) ) && "${VAR}" != +(*=*) ]]
	then
	    for i in ${VAR//,/ }
	    do
                if [[ -z $(Get_Var ${i}) ]]
	        then
		    if [[ "${i}" = +(*\[*\]*) ]]
		    then
			echo "char *${i//]/+$g_OPTION_BASE]} = { NULL };" >> $g_HFILE
			# Determine dimension needed for SORT
			VALUE=${i#*\[}
                        Save_Dim "${i%%\[*}" "${VALUE%\]*}"
                        # Save type
                        Save_Main_Var "${i}" "char**"
                    elif [[ ${i} = +(*\(*\)*) ]]
                    then
                        # Function pointer
		        echo "$TYPE $i;" >> $g_HFILE
                        i=`echo ${i%%\)*} | tr -d "\052"`
                        Save_Main_Var "${i##*\(}" "void*"
		    else
			echo "char *$i = NULL;" >> $g_HFILE
                        Save_Main_Var "${i}" "char*"
			# Pointer var should not be initialized
			if [[ "${i}" = +(*${g_STRINGSIGN}*) ]]
			then
			    echo "$i = calloc(1, sizeof(char));" >> $g_CFILE
			fi
		    fi
	        fi
	    done
        # Var is string array assignment
	elif [[ ( "${VAR}" = +(*${g_STRINGSIGN}*) || "${TYPE}" = +(*STRING*|*char\**) ) && "${VAR}" = +(*=*) ]]
        then
            if [[ -z $(Get_Var ${VAR}) ]]
	    then
		if [[ "${VAR}" = +(*\[*\]*) ]]
		then
                    echo "char* ${VAR%%\{*} {" >> $g_HFILE
                    OPTION=$g_OPTION_BASE
                    while [[ ${OPTION} -gt 0 ]]
                    do
                        echo " \"\", " >> $g_HFILE
                        ((OPTION-=1))
                    done
	            echo "${VAR#*\{};" >> $g_HFILE
		    # Determine dimension needed for SORT
                    VALUE=`echo ${VAR} | tr -d -c "," | wc -c`
                    ((VALUE+=1))
                    Save_Dim "${VAR%%\[*}" "${VALUE}"
                    # Save type
                    Save_Main_Var "${VAR}" "const char**"
                else
                    while [[ -n ${VAR} ]]
                    do
                        TOKEN=$(Mini_Parser "${VAR}")
		        echo "char *$TOKEN;" >> $g_HFILE
                        Save_Main_Var "${TOKEN%%=*}" "const char*"
                        VAR="${VAR:${#TOKEN}+1}"
                    done
                fi
            fi
	# Assume char assignment or number
	else
	    if [[ "$VAR" = +(*\[*\]*) && "$VAR" != +(*=*) ]]
	    then
                IFS=","
		for i in ${VAR// /}
		do
		    echo "$TYPE ${i//]/+$g_OPTION_BASE]} = { 0 };" >> $g_HFILE
		    # Determine dimension needed for SORT
		    VALUE=${i#*\[}
                    Save_Dim "${i%%\[*}" "${VALUE%\]*}"
                    # Save type
                    Save_Main_Var "${i}" "${TYPE}"
		done
                IFS="${g_ORGIFS}"
	    elif [[ "$VAR" = +(*\[*\]*) && "$VAR" = +(*=*) ]]
            then
                # Numeric array assignment
                echo "$TYPE ${VAR%%\{*} {" >> $g_HFILE
                OPTION=$g_OPTION_BASE
                CTR=`echo ${VAR} | tr -d -c "[" | wc -c` ; PTR=
                if [[ ${OPTION} -gt 0 && $CTR -gt 1 ]]
                then
	            echo -e "\nWARNING: OPTION BASE has no impact on multidimensional array '${VAR%%\[*}' in DECLARE/GLOBAL statement at line $g_COUNTER in file '$g_CURFILE'!"
                fi
                while [[ ${OPTION} -gt 0 && $CTR -eq 1 ]]
                do
                    echo " 0, " >> $g_HFILE
                    ((OPTION-=1))
                done
	        echo "${VAR#*\{};" >> $g_HFILE
                # Count elements of array
                CTR=`echo ${VAR} | tr -d -c "," | wc -c`
                ((CTR+=1))
                Save_Dim "${VAR%%\[*}" "${CTR}"
                Save_Main_Var "${VAR%%\[*}" "${TYPE}"
            elif [[ ${VAR} = +(*\(*\)*) ]]
            then
                # Function pointer
		echo "$TYPE $VAR;" >> $g_HFILE
                VAR=`echo ${VAR%%\)*} | tr -d "\052"`
                Save_Main_Var "${VAR##*\(}" "void*"
	    else
                IFS=","
                for i in ${VAR// /}
                do
		    echo "$TYPE $i;" >> $g_HFILE
                    if [[ "$i" != +(*=*) && "$i" != +(*\**) && "${TYPE}" = +(*char*|*short*|*int*|*long*|*double*|*float*|*NUMBER*|*FLOATING*) ]]
                    then
		        echo "${i} = 0;" >> $g_CFILE
                    fi
                    Save_Main_Var "${i}" "${TYPE}"
                done
                IFS="${g_ORGIFS}"
            fi
	fi
    fi
}

#-----------------------------------------------------------

function Handle_Local
{
    # Local variables
    typeset VAR TYPE DIM NEW VALUE i OPTION ARRAY STATIC PTR TOKEN
    typeset -i CTR

    # Get the variablename and type
    if [[ "$1" = +(* TYPE *) ]]
    then
	VAR=$(echo "${1%% TYPE *}")
	TYPE=$(echo "${1##* TYPE }")
	if [[ ${TYPE} = +(* ARRAY *) ]]
	then
	    ARRAY=${TYPE##* ARRAY }
	    TYPE=${TYPE%% ARRAY *}
	fi
    else
	if [[ "${1}" = +(* ARRAY *) ]]
	then
	    ARRAY=${1##* ARRAY }
	    VAR=$(echo "${1%% ARRAY *}")
        elif [[ "${@}" = +(DIR|FILE|*int|*short|*long|*float|*double|*char|void|STRING|NUMBER|FLOATING) && "${@}" != +(*TYPE*) ]]
        then
	    echo -e "\nSyntax error: missing TYPE keyword in LOCAL at line $g_COUNTER in file '$g_CURFILE'!"
	    exit 1
        else
	    VAR=$(echo "${1}")
	fi
	if [[ "${VAR}" = +(*${g_STRINGSIGN}*) ]]
	then
	    TYPE="char*"
	elif [[ "${VAR}" = +(*${g_FLOATSIGN}*) ]]
	then
	    TYPE="double"
	else
	    TYPE="long"
	fi
    fi

    # Check if variable was already declared - no record and not function pointer?
    if [[ "$VAR" != +(*.*) && "$VAR" != +(\(*) ]]
    then
        IFS=","
	for i in ${VAR// /}
        do
            if [[ -n $(Get_Var "${i%%=*}" ${g_FUNCNAME}) ]]
            then
	        echo -e "\nSyntax error: variable '${i}' in LOCAL statement at line $g_COUNTER in file '$g_CURFILE' was defined previously!"
	        exit 1
            fi
        done
        IFS="${g_ORGIFS}"
    fi

    # Check if it is a known type, if not BaCon has to use external .h file
    if [[ ${TYPE%%\**} != +(DIR|FILE|*int|*short|*long|*float|*double|*char|void|STRING|NUMBER|FLOATING) && -z $g_RECORDNAME ]]
    then
	if [[ "$VAR" = +(*=*) ]]
	then
	    echo "$TYPE $VAR;" >> $g_CFILE
	    if [[ -z ${g_FUNCNAME} ]]
	    then
		Save_Main_Var "${VAR}" "${TYPE}"
	    else
		Save_Func_Var "${VAR}" "${g_FUNCNAME}" "${TYPE}"
	    fi
	else
	    for i in ${VAR//,/ }
	    do
	        echo "$TYPE $i;" >> $g_CFILE
		if [[ -z ${g_FUNCNAME} ]]
		then
		    Save_Main_Var "${i}" "${TYPE}"
		else
		    Save_Func_Var "${i}" "${g_FUNCNAME}" "${TYPE}"
		fi
	    done
	fi

    # Check for dynamic array declaration
    elif [[ -n ${ARRAY} ]]
    then
        if [[ $ARRAY = +(*STATIC*) ]]
        then
            STATIC=1
	    ARRAY=`echo ${ARRAY%% STATIC*} | tr "," " "`
        else
            STATIC=0
	    ARRAY="${ARRAY//,/ }"
        fi
        if [[ -n $g_RECORDNAME ]]
        then
            Record_Dyn_Array "$TYPE" "${VAR//,/ }" "$ARRAY" $STATIC
        else
            Normal_Dyn_Array "$TYPE" "${VAR//,/ }" "$ARRAY" $STATIC
        fi

    # Check if var is string var
    elif [[ ( "${TYPE}" = +(STRING|char\*) || "${VAR}" = +(*${g_STRINGSIGN}*) ) && "${VAR}" != +(*=*) && "${VAR}" != +(*\[*${g_STRINGSIGN}\]*) ]]
    then
	for i in ${VAR//,/ }
	do
            if [[ -z $(Get_Var ${i} ${g_FUNCNAME}) ]]
	    then
		# Check on multidimensional stringarrays
		if [[ "${i}" = +(*\[*\]*\]*) ]]
		then
		    echo -e "\nSyntax error: multidimensional stringarrays at line $g_COUNTER in file '$g_CURFILE' are not supported!"
		    exit 1
		fi
		# Are we in a function?
		if [[ -n $g_FUNCNAME ]]
		then
		    if [[ -n $g_RECORDNAME ]]
		    then
			if [[ "${i}" = +(*\[*\]*) ]]
			then
			    echo "char *$i;" >> $g_CFILE
			    DIM=${i##*\[}; DIM=${DIM%%\]*}
			    g_STRINGARRAYS="$g_STRINGARRAYS for(__b2c__ctr=0; __b2c__ctr<$DIM; __b2c__ctr++)if($g_RECORDVAR.${i%%\[*}[__b2c__ctr]!=NULL){free($g_RECORDVAR.${i%%\[*}[__b2c__ctr]);}"
			else
			    echo "char *$i;" >> $g_CFILE
			    # Pointer var should not be initialized
			    if [[ "${i}" = +(*${g_STRINGSIGN}*) ]]
			    then
			        g_LOCALSTRINGS="$g_LOCALSTRINGS ${g_RECORDVAR}.${i}"
                                g_RECORDEND_BODY="${g_RECORDEND_BODY} $g_RECORDVAR.$i = (char*)calloc(1, sizeof(char));"
                            fi
			fi
                        Save_Func_Var "${i}" "${g_FUNCNAME}" "char*"
		    else
			if [[ "${i}" = +(*\[*\]*) ]]
			then
			    echo "char *${i//]/+$g_OPTION_BASE]} = { NULL };" >> $g_CFILE
			    # Determine dimension needed for SORT
			    VALUE=${i#*\[}
                            Save_Dim "${i%%\[*}" "${VALUE%\]*}"
			    DIM=${i##*\[}; DIM=${DIM%%\]*}
			    g_STRINGARRAYS="$g_STRINGARRAYS for(__b2c__ctr=0; __b2c__ctr<$DIM; __b2c__ctr++)if(${g_WITHVAR}${i%%\[*}[__b2c__ctr]!=NULL){free(${g_WITHVAR}${i%%\[*}[__b2c__ctr]);}"
			    # Save type
                            Save_Func_Var "${i}" "${g_FUNCNAME}" "char**"
                        elif [[ ${i} = +(*\(*\)*) ]]
                        then
                            # Function pointer
		            echo "$TYPE $i;" >> $g_CFILE
                            i=`echo ${i%%\)*} | tr -d "\052"`
                            Save_Func_Var "${i##*\(}" "${g_FUNCNAME}" "void*"
			else
			    echo "char *$i = NULL;" >> $g_CFILE
                            Save_Func_Var "${i}" "${g_FUNCNAME}" "char*"
			    # Pointer var should not be initialized
			    if [[ "${i}" = +(*${g_STRINGSIGN}*) ]]
			    then
				echo "$i = calloc(1, sizeof(char));" >> $g_CFILE
				g_LOCALSTRINGS="$g_LOCALSTRINGS ${i}"
			    fi
			fi
		    fi
		# We are in the mainprogram
		else
		    if [[ -n $g_RECORDNAME ]]
		    then
			echo "char *$i;" >> $g_HFILE
                        Save_Main_Var "${i}" "char*"
			# Pointer var should not be initialized
			if [[ "${i}" = +(*${g_STRINGSIGN}*) && "${i}" != +(*\[*\]*) ]]
			then
                            g_RECORDEND_BODY="${g_RECORDEND_BODY} $g_RECORDVAR.$i = (char*)calloc(1, sizeof(char));"
                        fi
		    else
			if [[ "${i}" = +(*\[*\]*) ]]
			then
			    echo "char *${i//]/+$g_OPTION_BASE]} = { NULL };" >> $g_HFILE
			    # Determine dimension needed for SORT
			    VALUE=${i#*\[}
                            Save_Dim "${i%%\[*}" "${VALUE%\]*}"
			    # Save type
                            Save_Main_Var "${i}" "char**"
                        elif [[ ${i} = +(*\(*\)*) ]]
                        then
                            # Function pointer
		            echo "$TYPE $i;" >> $g_HFILE
                            i=`echo ${i%%\)*} | tr -d "\052"`
                            Save_Main_Var "${i##*\(}" "void*"
			else
			    echo "char *$i = NULL;" >> $g_HFILE
                            Save_Main_Var "${i}" "char*"
			    # Pointer var should not be initialized
			    if [[ "${i}" = +(*${g_STRINGSIGN}*) ]]
			    then
				echo "$i = calloc(1, sizeof(char));" >> $g_CFILE
			    fi
			fi
		    fi
		fi
	    fi
	done
    elif [[ ( "${VAR}" = +(*${g_STRINGSIGN}*) || "${TYPE}" = +(*STRING*|*char\**) ) && "${VAR}" = +(*=*) ]]
    then
        if [[ -n $g_FUNCNAME ]]
	then
            if [[ -z $(Get_Var ${VAR}) ]]
	    then
		if [[ "${VAR}" = +(*\[*\]*) ]]
		then
                    echo "char* ${VAR%%\{*} {" >> $g_CFILE
                    OPTION=$g_OPTION_BASE
                    while [[ ${OPTION} -gt 0 ]]
                    do
                        echo " \"\", " >> $g_CFILE
                        ((OPTION-=1))
                    done
	            echo "${VAR#*\{};" >> $g_CFILE
		    # Determine dimension needed for SORT
                    VALUE=`echo ${VAR} | tr -d -c "," | wc -c`
                    ((VALUE+=1))
                    Save_Dim "${VAR%%\[*}" "${VALUE}"
                    # Save type
                    Save_Func_Var "${VAR}" "${g_FUNCNAME}" "const char**"
                else
                    while [[ -n ${VAR} ]]
                    do
                        TOKEN=$(Mini_Parser "${VAR}")
		        echo "char *$TOKEN;" >> $g_CFILE
                        Save_Func_Var "${TOKEN%%=*}" "${g_FUNCNAME}" "const char*"
                        VAR="${VAR:${#TOKEN}+1}"
                    done
                fi
            fi
        else
            if [[ -z $(Get_Var ${VAR}) ]]
	    then
		if [[ "${VAR}" = +(*\[*\]*) ]]
		then
                    echo "char* ${VAR%%\{*} {" >> $g_HFILE
                    OPTION=$g_OPTION_BASE
                    while [[ ${OPTION} -gt 0 ]]
                    do
                        echo " \"\", " >> $g_HFILE
                        ((OPTION-=1))
                    done
	            echo "${VAR#*\{};" >> $g_HFILE
		    # Determine dimension needed for SORT
                    VALUE=`echo ${VAR} | tr -d -c "," | wc -c`
                    ((VALUE+=1))
                    Save_Dim "${VAR%%\[*}" "${VALUE}"
                    # Save type
                    Save_Main_Var "${VAR}" "const char**"
                else
                    while [[ -n ${VAR} ]]
                    do
                        TOKEN=$(Mini_Parser "${VAR}")
		        echo "char *$TOKEN;" >> $g_HFILE
                        Save_Main_Var "${TOKEN%%=*}" "const char*"
                        VAR="${VAR:${#TOKEN}+1}"
                    done
                fi
            fi
        fi
    # Assume number or complicated type
    else
	if [[ -n $g_FUNCNAME ]]
	then
	    if [[ "$VAR" = +(*\[*\]*) && "$VAR" != +(*=*) ]]
	    then
                IFS=","
		for i in ${VAR// /}
		do
                    if [[ -z $g_RECORDNAME ]]
                    then
			echo "$TYPE ${i//]/+$g_OPTION_BASE]} = { 0 };" >> $g_CFILE
                    else
			echo "$TYPE ${i//]/+$g_OPTION_BASE]};" >> $g_CFILE
                    fi
		    # Determine dimension needed for SORT
		    VALUE=${i#*\[}
                    Save_Dim "${i%%\[*}" "${VALUE%\]*}"
                    Save_Func_Var "${i}" "${g_FUNCNAME}" "${TYPE}"
		done
                IFS="${g_ORGIFS}"
	    elif [[ "$VAR" = +(*\[*\]*) && "$VAR" = +(*=*) ]]
            then
                # Numeric array assignment
                echo "$TYPE ${VAR%%\{*} {" >> $g_CFILE
                OPTION=$g_OPTION_BASE
                CTR=`echo ${VAR} | tr -d -c "[" | wc -c` ; PTR=
                if [[ ${OPTION} -gt 0 && $CTR -gt 1 ]]
                then
	            echo -e "\nWARNING: OPTION BASE has no impact on multidimensional array '${VAR%%\[*}' in LOCAL statement at line $g_COUNTER in file '$g_CURFILE'!"
                fi
                while [[ ${OPTION} -gt 0 && $CTR -eq 1 ]]
                do
                    echo " 0, " >> $g_CFILE
                    ((OPTION-=1))
                done
	        echo "${VAR#*\{};" >> $g_CFILE
                # Count elements of array
                CTR=`echo ${VAR} | tr -d -c "," | wc -c`
                ((CTR+=1))
                Save_Dim "${VAR%%\[*}" "${CTR}"
                Save_Func_Var "${VAR}" "${g_FUNCNAME}" "${TYPE}"
            elif [[ ${VAR} = +(*\(*\)*) ]]
            then
                # Function pointer
		echo "$TYPE $VAR;" >> $g_CFILE
                VAR=`echo ${VAR%%\)*} | tr -d "\052"`
                Save_Func_Var "${VAR##*\(}" "${g_FUNCNAME}" "void*"
	    else
                IFS=","
                for i in ${VAR// /}
                do
		    echo "$TYPE $i;" >> $g_CFILE
                    if [[ "$i" != +(*=*) && "$i" != +(*\**) && -z ${g_RECORDVAR} && "${TYPE}" = +(*char*|*short*|*int*|*long*|*double*|*float*|*NUMBER*|*FLOATING*) ]]
                    then
		        echo "${i} = 0;" >> $g_CFILE
                    fi
                    Save_Func_Var "${i}" "${g_FUNCNAME}" "${TYPE}"
                done
                IFS="${g_ORGIFS}"
	    fi
	else
	    if [[ "$VAR" = +(*\[*\]*) && "$VAR" != +(*=*) ]]
	    then
                IFS=","
		for i in ${VAR// /}
		do
                    if [[ -z $g_RECORDNAME ]]
                    then
			echo "$TYPE ${i//]/+$g_OPTION_BASE]} = { 0 };" >> $g_HFILE
                    else
			echo "$TYPE ${i//]/+$g_OPTION_BASE]};" >> $g_HFILE
                    fi
		    # Determine dimension needed for SORT
		    VALUE=${i#*\[}
                    Save_Dim "${i%%\[*}" "${VALUE%\]*}"
                    Save_Main_Var "${i}" "${TYPE}"
		done
                IFS="${g_ORGIFS}"
	    elif [[ "$VAR" = +(*\[*\]*) && "$VAR" = +(*=*) ]]
            then
                # Numeric array assignment
                echo "$TYPE ${VAR%%\{*} {" >> $g_HFILE
                OPTION=$g_OPTION_BASE
                CTR=`echo ${VAR} | tr -d -c "[" | wc -c` ; PTR=
                if [[ ${OPTION} -gt 0 && $CTR -gt 1 ]]
                then
	            echo -e "\nWARNING: OPTION BASE has no impact on multidimensional array '${VAR%%\[*}' in LOCAL statement at line $g_COUNTER in file '$g_CURFILE'!"
                fi
                while [[ ${OPTION} -gt 0 && $CTR -eq 1 ]]
                do
                    echo " 0, " >> $g_HFILE
                    ((OPTION-=1))
                done
	        echo "${VAR#*\{};" >> $g_HFILE
                # Count elements of array
                CTR=`echo ${VAR} | tr -d -c "," | wc -c`
                ((CTR+=1))
                Save_Dim "${VAR%%\[*}" "${CTR}"
                Save_Main_Var "${VAR}" "${TYPE}"
            elif [[ ${VAR} = +(*\(*\)*) ]]
            then
                # Function pointer
		echo "$TYPE $VAR;" >> $g_HFILE
                VAR=`echo ${VAR%%\)*} | tr -d "\052"`
                Save_Main_Var "${VAR##*\(}" "void*"
            else
                IFS=","
                for i in ${VAR// /}
                do
		    echo "$TYPE $i;" >> $g_HFILE
                    if [[ "$i" != +(*=*) && "$i" != +(*\**) && -z ${g_RECORDVAR} && "${TYPE}" = +(*char*|*short*|*int*|*long*|*double*|*float*|*NUMBER*|*FLOATING*) ]]
                    then
		        echo "${i} = 0;" >> $g_CFILE
                    fi
                    Save_Main_Var "${i}" "${TYPE}"
                done
                IFS="${g_ORGIFS}"
	    fi
	fi
    fi
}

#-----------------------------------------------------------

function Handle_Read
{
    # Local variables
    typeset CHECK STR ITEM

    # Check if we have an argument at all
    if [[ "$1" = "READ" ]]
    then
	echo -e "\nSyntax error: empty READ at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    for ITEM in ${1//,/ }
    do
	# Check if string variable, and if so, if declared
	if [[ "${ITEM}" = +(*${g_STRINGSIGN}) && "$ITEM" != +(*.*) ]]
	then
            if [[ -z $(Get_Var ${ITEM} ${g_FUNCNAME}) ]]
	    then
		echo "char *$ITEM = NULL;" >> $g_HFILE
                Save_Main_Var "${ITEM}" "char*"
	    fi
	    CHECK="char*"
        # Variable may not be array, these should be defined with DECLARE
	elif [[ "${ITEM}" != +(*\[*\]*) && "${ITEM}" != +(*.*) && "$ITEM" != +(*\(*\)*) && "$ITEM" != +(*-\>*) ]]
	then
	    # Not declared? Assume long
            if [[ -z $(Get_Var ${ITEM} ${g_FUNCNAME}) ]]
	    then
                Register_Numeric ${ITEM}
                CHECK=$(Get_Var ${ITEM} ${g_FUNCNAME})
            else
                CHECK=$(Get_Var ${ITEM} ${g_FUNCNAME})
	    fi
	else
	    # See how var was declared
            CHECK=$(Get_Var ${ITEM} ${g_FUNCNAME})
	fi

        # Check type of var, string?
        if [[ "${ITEM}" = +(*${g_STRINGSIGN}) || "${ITEM%%\(*}" = +(*${g_STRINGSIGN}) || "${ITEM%%\[*}" = +(*${g_STRINGSIGN}) ]]
        then
	    # Convert to C
	    echo "__b2c__assign = (char*)calloc((strlen(__b2c__stringarray[__b2c__stringarray_ptr])+1), sizeof(char));" >> $g_CFILE
	    echo "strcpy(__b2c__assign, __b2c__stringarray[__b2c__stringarray_ptr]); __b2c__stringarray_ptr++;" >> $g_CFILE
	    if [[ "${ITEM}" = +(*\(*\)) ]]
	    then
		STR=${ITEM#*\(}
		echo "__b2c__${ITEM%%\(*}__location = __b2c__${ITEM%%\(*}__add(${STR};" >> $g_CFILE
		echo "if(__b2c__${ITEM%%\(*}__location->__b2c_value != NULL) free(__b2c__${ITEM%%\(*}__location->__b2c_value); __b2c__${ITEM%%\(*}__location->__b2c_value = __b2c__assign;" >> $g_CFILE
		# Check for relations
		Relate_Recurse "${ITEM%%\(*}" "${STR}" "${ITEM}" "-1"
	    else
		echo "if($ITEM != NULL) free($ITEM); $ITEM = __b2c__assign;" >> $g_CFILE
	    fi
        else
	    # Now see if we have an assoc or a normal variable
	    if [[ "${ITEM}" = +(*\(*\)) ]]
	    then
	        echo "__b2c__${ITEM%%\(*}__location = __b2c__${ITEM%%\(*}__add(${ITEM#*\(};" >> $g_CFILE
		echo "__b2c__${ITEM%%\(*}__location->__b2c_value = (${CHECK})__b2c__floatarray[__b2c__floatarray_ptr];" >> $g_CFILE
	        echo "__b2c__floatarray_ptr++;" >> $g_CFILE
		# Check for relations
		Relate_Recurse "${ITEM%%\(*}" "${STR}" "${ITEM}" "-1"
            else
	        echo "${ITEM} = (${CHECK})__b2c__floatarray[__b2c__floatarray_ptr];" >> $g_CFILE
	        echo "__b2c__floatarray_ptr++;" >> $g_CFILE
            fi
        fi
    done
}

#-----------------------------------------------------------

function Handle_Endfunction
{
    # Check if return was found
    if [[ -z $g_FUNCTYPE ]]
    then
	echo -e "\nSyntax error: function '$g_FUNCNAME' was defined without returning a value or string!"
	exit 1
    fi

    # Put prototype to header file
    echo "$g_FUNCTYPE ${g_PROTOTYPE};" >> $g_HFILE
    g_PROTOTYPE=

    # Now setup function in main program
    echo "/* Created with BASH BaCon $g_VERSION - (c) Peter van Eerten - MIT License (Expat) */" > ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    echo "/* FILE $g_CURFILE LINE $g_COPY_COUNTER */" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    if [[ $g_ORIGFUNCNAME != +(*\(*\)*) ]]
    then
	echo "$g_FUNCTYPE $g_ORIGFUNCNAME(void) {" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    else
	echo "$g_FUNCTYPE $g_ORIGFUNCNAME {" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    fi

    # Add function body
    echo "${g_STRINGARGS}" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    cat $g_CFILE >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    if [[ $g_CATCH_USED -eq 1 ]]
    then
        echo "__B2C__PROGRAM__EXIT: ;" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    fi
    # Make sure the function always returns something
    if [[ $g_FUNCTYPE = +(*char\**) ]]
    then
	echo "return (NULL);}" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    else
	echo "return (0);}" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    fi

    # Include header file
    if [[ ${g_INCLUDE_FILES} != +(*${g_CURFILE%.*}.$g_FUNCNAME.h*) ]]
    then
	g_INCLUDE_FILES="$g_INCLUDE_FILES ${g_CURFILE%.*}.$g_FUNCNAME.h"
    fi

    # Add to total filelist
    g_TMP_FILES="$g_TMP_FILES ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h"

    # Delete temp funcfile
    rm $g_CFILE

    # Restore mainfile
    g_CFILE=$g_COPY_CFILE

    # Restore CATCH routine
    g_CATCHGOTO="$g_ORIGCATCHGOTO"
    g_CATCH_USED=${g_ORIGCATCH_USED}

    # Clear function variables
    g_ORIGFUNCNAME=
    g_FUNCNAME=
    g_FUNCTYPE=
    g_LOCALSTRINGS=
    g_STRINGARRAYS=
    g_STRINGARGS=
}

#-----------------------------------------------------------

function Handle_Return
{
    # Local variables
    typeset CHECK STR ARG LEN
    typeset -i CTR

    # Check if we have an argument at all, if not, we return from a GOSUB
    if [[ "${1}" = "RETURN" ]]
    then
	echo "if(__b2c__gosub_buffer_ptr >= 0) longjmp(__b2c__gosub_buffer[__b2c__gosub_buffer_ptr], 1);" >> $g_CFILE
	return
    fi

    CHECK=$(Get_Var ${1%%\(*} ${g_FUNCNAME})

    # Check type of returned var, is it a string?
    if [[ -n ${g_FUNCTYPE} ]]
    then
	ARG="${1}"
    elif [[ "${1}" = +(*${g_STRINGSIGN}) || "${1%%\(*}" = +(*${g_STRINGSIGN}) || "${1%%\[*}" = +(*${g_STRINGSIGN}) || "${1}" = +(*${g_DQUOTESIGN}) || ${g_FUNCNAME} = +(*${g_STRINGSIGN}) ]]
    then
        # Static dynamic array or array created by SPLIT or LOOKUP
        if [[ ${g_DYNAMICARRAYS} = +(* ${1}@${g_FUNCNAME}*) || ${g_STRINGARGS} = +(* __b2c__split__${1} *) ]]
        then
	    g_FUNCTYPE="char**"
	    ARG="${1}"
        # We return a string
        else
	    g_FUNCTYPE="char*"
	    echo "__b2c__rbuffer_ptr++; if(__b2c__rbuffer_ptr >= $g_MAX_RBUFFERS) __b2c__rbuffer_ptr=0; if($1 != NULL)" >> $g_CFILE
	    echo " {__b2c__rbuffer[__b2c__rbuffer_ptr] = (char*)__rbuf_realloc(__b2c__rbuffer[__b2c__rbuffer_ptr], (strlen($1)+1)*sizeof(char));" >> $g_CFILE
	    echo "strcpy(__b2c__rbuffer[__b2c__rbuffer_ptr], $1);}" >> $g_CFILE
	    echo "else {__b2c__rbuffer[__b2c__rbuffer_ptr] = (char*)calloc(1, sizeof(char));}" >> $g_CFILE
	    ARG="__b2c__rbuffer[__b2c__rbuffer_ptr]"
        fi

    # Assume variable, check if declared before
    elif [[ -n $CHECK ]]
    then
	ARG="${1}"
        if [[ ${ARG} = +(*\[*\]*) ]]
        then
            CTR=`echo ${ARG} | tr -d -c "[" | wc -c`
            until [[ $CTR -eq 0 ]]
            do
                if [[ ${CHECK} = +(*\*) ]]
                then
		    let LEN=${#CHECK}-1
		    CHECK="${CHECK:0:$LEN}"
                fi
                let CTR=${CTR}-1
            done
        else
            for STR in $g_STATICARRAYS
            do
                if [[ $STR = +(*${ARG}*) ]]
                then
                    CTR=${STR##*:}
                    until [[ $CTR -eq 0 ]]
                    do
                        CHECK="${CHECK}*"
                        let CTR=${CTR}-1
                    done
                fi
            done
        fi
	g_FUNCTYPE="${CHECK}"

    # Not declared, assume actual value
    else
        if [[ "${1}" = +(*.*) || "${1}" = +(*${g_FLOATSIGN}) || ${g_FUNCNAME} = +(*${g_FLOATSIGN}) ]]
        then
	    g_FUNCTYPE="double"
        else
	    g_FUNCTYPE="${g_VARTYPE}"
        fi
	ARG="${1}"
    fi

    # Free strings variables if there are any
    echo "${g_STRINGARRAYS}" >> $g_CFILE
    for STR in $g_LOCALSTRINGS
    do
        # If return argument contains string, make sure to point to return buffer
        if [[ ${ARG} = +(*${STR}*) ]]
        then
	    echo "__b2c__rbuffer_ptr++; if(__b2c__rbuffer_ptr >= $g_MAX_RBUFFERS) __b2c__rbuffer_ptr=0; if(${STR} != NULL)" >> $g_CFILE
	    echo " {__b2c__rbuffer[__b2c__rbuffer_ptr] = (char*)__rbuf_realloc(__b2c__rbuffer[__b2c__rbuffer_ptr], (strlen(${STR})+1)*sizeof(char));" >> $g_CFILE
	    echo "strcpy(__b2c__rbuffer[__b2c__rbuffer_ptr], $STR); free(${STR}); ${STR} = __b2c__rbuffer[__b2c__rbuffer_ptr];}" >> $g_CFILE
        else
	    echo "if($STR != NULL) free($STR);" >> $g_CFILE
        fi
    done

    # The actual return value
    echo "__b2c__catch_set = __b2c__catch_set_backup;" >> $g_CFILE
    echo "return (${ARG});" >> $g_CFILE
}

#-----------------------------------------------------------

function Handle_Push
{
    # Local variables
    typeset CHECK

    # Check if we have an argument at all
    if [[ "$1" = "PUSH" ]]
    then
	echo -e "\nSyntax error: empty PUSH at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    if [[ "$VAR" != +(*.*) ]]
    then
        CHECK=$(Get_Var ${1} ${g_FUNCNAME})
    fi

    # Allocate space for type
    echo "__b2c__typestack = (int*)realloc(__b2c__typestack, (__b2c__stackptr+1)*sizeof(int));" >> $g_CFILE

    # Check type of var, string?
    if [[ "${1}" = +(*${g_STRINGSIGN}) || "${1%%\(*}" = +(*${g_STRINGSIGN}) || "${1%%\[*}" = +(*${g_STRINGSIGN}) || "${1}" = +(*${g_DQUOTESIGN}*) ]]
    then
	echo "__b2c__stringstack = (char**)realloc(__b2c__stringstack, (__b2c__stackptr+1)*sizeof(char*));" >> $g_CFILE
	echo "if(__b2c__stackptr == 0){ __b2c__stringstack[__b2c__stackptr] = realloc(__b2c__stringstack[__b2c__stackptr], (strlen($1)+1)*sizeof(char));" >> $g_CFILE
	echo "strcpy(__b2c__stringstack[__b2c__stackptr], $1);} else __b2c__stringstack[__b2c__stackptr] = __b2c__strdup($1);" >> $g_CFILE
	echo "__b2c__typestack[__b2c__stackptr] = 1;" >> $g_CFILE
    # Check if float
    elif [[ "$1" = +(*.*) ]]
    then
	echo "__b2c__doublestack = (double*)realloc(__b2c__doublestack, (__b2c__stackptr+1)*sizeof(double));" >> $g_CFILE
	echo "__b2c__doublestack[__b2c__stackptr] = $1;" >> $g_CFILE
	echo "__b2c__typestack[__b2c__stackptr] = 2;" >> $g_CFILE
    # Check if no alpha chars (then integer value)
    elif [[ "$1" = +(![a-zA-Z]) ]]
    then
	echo "__b2c__longstack = (long*)realloc(__b2c__longstack, (__b2c__stackptr+1)*sizeof(long));" >> $g_CFILE
	echo "__b2c__longstack[__b2c__stackptr] = $1;" >> $g_CFILE
	echo "__b2c__typestack[__b2c__stackptr] = 3;" >> $g_CFILE
    # Assume variable, check if declared before
    elif [[ -n $CHECK ]]
    then
	if [[ $CHECK = +(double*) ]]
	then
	    echo "__b2c__doublestack = (double*)realloc(__b2c__doublestack, (__b2c__stackptr+1)*sizeof(double));" >> $g_CFILE
	    echo "__b2c__doublestack[__b2c__stackptr] = $1;" >> $g_CFILE
	    echo "__b2c__typestack[__b2c__stackptr] = 2;" >> $g_CFILE
	else
	    echo "__b2c__longstack = (long*)realloc(__b2c__longstack, (__b2c__stackptr+1)*sizeof(long));" >> $g_CFILE
	    echo "__b2c__longstack[__b2c__stackptr] = $1;" >> $g_CFILE
	    echo "__b2c__typestack[__b2c__stackptr] = 3;" >> $g_CFILE
	fi
    # Not declared, assume integer variable
    else
	echo "__b2c__longstack = (long*)realloc(__b2c__longstack, (__b2c__stackptr+1)*sizeof(long));" >> $g_CFILE
	echo "__b2c__longstack[__b2c__stackptr] = $1;" >> $g_CFILE
	echo "__b2c__typestack[__b2c__stackptr] = 3;" >> $g_CFILE
    fi

    # Increase stackpointer
    echo "__b2c__stackptr++;" >> $g_CFILE
}

#-----------------------------------------------------------

function Handle_Pull
{
    typeset CHECK STR

    # Check if we have an argument at all
    if [[ "$1" = "PULL" ]]
    then
	echo -e "\nSyntax error: empty PULL at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Argument must be a variable
    if [[ "$1" = +(![a-zA-Z]) ]]
    then
	echo -e "\nSyntax error: argument in PULL statement at line $g_COUNTER in file '$g_CURFILE' is not a variable!"
	exit 1
    fi

    # Check if string is declared
    if [[ "${1}" = +(*${g_STRINGSIGN}) && "${1}" != +(*.*) ]]
    then
        if [[ -z $(Get_Var ${1} ${g_FUNCNAME}) ]]
	then
	    echo "char *${1} = NULL;" >> $g_HFILE
            Save_Main_Var "${1}" "char*"
	    CHECK="char*"
	fi
    # Not a string?
    elif [[ "${1}" != +(*\[*\]*) && "${1}" != +(*.*) && "${1}" != +(*\(*\)*) && "${1}" != +(*-\>*) ]]
    then
        if [[ -z $(Get_Var ${1} ${g_FUNCNAME}) ]]
	then
            Register_Numeric ${1}
            CHECK=$(Get_Var ${1} ${g_FUNCNAME})
	fi
    else
        CHECK=$(Get_Var ${1} ${g_FUNCNAME})
    fi

    # Decrease stackpointer again
    echo "__b2c__stackptr--; if(__b2c__stackptr < 0) __b2c__stackptr=0;" >> $g_CFILE

    # Get the string from stack
    if [[ "${1}" = +(*${g_STRINGSIGN}) || "${1%%\(*}" = +(*${g_STRINGSIGN}) || "${1%%\[*}" = +(*${g_STRINGSIGN}) ]]
    then
	echo "if(__b2c__typestack[__b2c__stackptr] == 1) {__b2c__assign = (char*)calloc(strlen(__b2c__stringstack[__b2c__stackptr])+1, sizeof(char));" >> $g_CFILE
	echo "strcpy(__b2c__assign, __b2c__stringstack[__b2c__stackptr]); if(__b2c__stackptr > 0) free(__b2c__stringstack[__b2c__stackptr]);}" >> $g_CFILE
	# Now see if we have a assoc or a normal variable
	if [[ "${1}" = +(*\(*\)) ]]
	then
	    STR=${1#*\(}
	    echo "__b2c__${1%%\(*}__location = __b2c__${1%%\(*}__add(${STR};" >> $g_CFILE
	    echo "if(__b2c__${1%%\(*}__location->__b2c_value != NULL) free(__b2c__${1%%\(*}__location->__b2c_value); __b2c__${1%%\(*}__location->__b2c_value = __b2c__assign;" >> $g_CFILE
	    # Check for relations
	    Relate_Recurse "${1%%\(*}" "${STR}" "${1}" "-1"
	else
	    echo "if(${1} != NULL) free(${1}); ${1} = __b2c__assign;" >> $g_CFILE
	fi
    else
	# Now see if we have an assoc or a normal variable
	if [[ "${1}" = +(*\(*\)) ]]
	then
	    STR=${1#*\(}
	    echo "__b2c__${1%%\(*}__location = __b2c__${1%%\(*}__add(${STR};" >> $g_CFILE
	    if [[ "$CHECK" = +(*double*) || "$CHECK" = +(*float*) || "$CHECK" = +(*FLOATING*) ]]
	    then
		echo "__b2c__${1%%\(*}__location->__b2c_value = __b2c__doublestack[__b2c__stackptr];" >> $g_CFILE
	    else
		echo "__b2c__${1%%\(*}__location->__b2c_value = __b2c__longstack[__b2c__stackptr];" >> $g_CFILE
	    fi
	    # Check for relations
	    Relate_Recurse "${1%%\(*}" "${STR}" "${1}" "-1"
	else
	    if [[ "$CHECK" = +(*double*) || "$CHECK" = +(*float*) || "$CHECK" = +(*FLOATING*) ]]
	    then
		echo "if(__b2c__typestack[__b2c__stackptr] == 2) ${1} = __b2c__doublestack[__b2c__stackptr];" >> $g_CFILE
	    else
		echo "if(__b2c__typestack[__b2c__stackptr] == 3) ${1} = __b2c__longstack[__b2c__stackptr];" >> $g_CFILE
	    fi
	fi
    fi
}

#-----------------------------------------------------------

function Handle_SubFunc
{
    typeset ARGS TOKEN LEN CHAR DIM ARR CHECK SIZE CURFUNC

    # Check argument
    if [[ $(echo ${1}) = "SUB" || $(echo ${1}) = "FUNCTION" ]]
    then
	echo -e "\nSyntax error: empty SUB/FUNCTION at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if we are in a sub already
    if [[ -n $g_FUNCNAME ]]
    then
	echo -e "\nSyntax error: cannot define a SUB/FUNCTION within a SUB/FUNCTION at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the funcname
    if [[ ${1} = +(*\(*) ]]
    then
        g_ORIGFUNCNAME=$(echo ${1%%\(*}"(")
        g_PROTOTYPE=$(echo ${1%%\(*}"(")
        if [[ ${1} = +(* TYPE *) ]]
        then
            g_FUNCTYPE=${1##* TYPE }
        fi
    else
        if [[ ${1} = +(* TYPE *) ]]
        then
            g_FUNCTYPE=${1##* TYPE }
            g_ORIGFUNCNAME="${1%% TYPE *}("
            g_PROTOTYPE="${1%% TYPE *}("
        else
            g_ORIGFUNCNAME=$(echo ${1}"(")
            g_PROTOTYPE=$(echo ${1}"(")
        fi
    fi
    CURFUNC=$(echo ${g_ORIGFUNCNAME%%\(*})

    if [[ "${1}" = +(* TYPE *) ]]
    then
	ARGS=$(echo ${1%% TYPE *})
    else
	ARGS=$(echo ${1})
    fi

    # Get original function name
    if [[ "${ARGS}" = +(*\(*\)*) ]]
    then
	g_FUNCNAME=$(echo ${ARGS%%\(*})
    else
	g_FUNCNAME=$(echo ${ARGS})
    fi

    # Start miniparser to duplicate string arguments, convert spaces
    ARGS=$(echo "${ARGS#*\(}")

    # If there are no arguments to the function at all
    if [[ ${ARGS} != +(*\)) || -z $(echo ${ARGS%%\)*}) ]]
    then
	g_ORIGFUNCNAME="${g_ORIGFUNCNAME} void)"
	g_PROTOTYPE="${g_PROTOTYPE} void)"
    else
        while [[ -n ${ARGS} ]]
        do
	    # Get the arguments
            TOKEN=$(Mini_Parser "${ARGS}")
            ARGS="${ARGS:${#TOKEN}+1}"

            if [[ ${TOKEN} = +(*\(*\)*) ]]
            then
		g_ORIGFUNCNAME="$g_ORIGFUNCNAME ${TOKEN}"
		g_PROTOTYPE="$g_PROTOTYPE ${TOKEN}"
	    elif [[ $TOKEN = +(*VAR *) ]]
	    then
	        TOKEN=$(echo ${TOKEN//\)/})
		if [[ $ARGS = +(*,*) ]]
		then
		    echo -e "\nSyntax error: variable argument list cannot be followed by other arguments at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		elif [[ $g_PROTOTYPE = +(*,*) ]]
		then
		    echo -e "\nSyntax error: variable argument list cannot be preceded by other arguments at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		fi
		if [[ "${TOKEN}" != +(* SIZE *) ]]
		then
		    echo -e "\nSyntax error: variable argument list lacks SIZE argument at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		fi
		ARR=${TOKEN#* }; ARR=${ARR%%SIZE *}; SIZE=${TOKEN##* }
		if [[ "${ARR}" != +(*${g_STRINGSIGN}*) ]]
		then
		    echo -e "\nSyntax error: variable argument list is not string at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		fi
		# These are in the function header, and do not exist yet - no need to check with Get_Var
		g_STRINGARGS="$g_STRINGARGS long ${SIZE};"
		Save_Func_Var ${SIZE} "${CURFUNC}" "long"
		Save_Func_Var ${ARR} "${CURFUNC}" "char**"
		g_STRINGARGS="$g_STRINGARGS long __b2c__var_$ARR = $g_OPTION_BASE; va_list __b2c__ap; char **${ARR} = NULL; char* __b2c__va = NULL; $ARR = (char **)realloc($ARR, (__b2c__var_$ARR+1) * sizeof(char*));"
		g_STRINGARGS="$g_STRINGARGS va_start(__b2c__ap, __b2c__name); if(__b2c__name != NULL) ${ARR}[__b2c__var_$ARR] = __b2c__strdup(__b2c__name); else ${ARR}[__b2c__var_$ARR] = NULL; while (${ARR}[__b2c__var_$ARR] != NULL) {__b2c__var_$ARR++; $ARR = (char **)realloc($ARR, (__b2c__var_$ARR+1) * sizeof(char*));"
		g_STRINGARGS="$g_STRINGARGS __b2c__va = va_arg(__b2c__ap, char*); if(__b2c__va!=NULL) ${ARR}[__b2c__var_$ARR] = __b2c__strdup(__b2c__va); else ${ARR}[__b2c__var_$ARR] = NULL; }"
		g_STRINGARGS="$g_STRINGARGS va_end(__b2c__ap); ${SIZE} = __b2c__var_$ARR - $g_OPTION_BASE; if(__b2c__var_$ARR > 0) __b2c__var_$ARR--;"
		g_PROTOTYPE="__${g_PROTOTYPE}char*, ..."
		g_ORIGFUNCNAME="${g_ORIGFUNCNAME}char *__b2c__name, ..."
		g_STRINGARRAYS="$g_STRINGARRAYS if($ARR != NULL) {for(__b2c__ctr=$g_OPTION_BASE; __b2c__ctr<=__b2c__var_$ARR; __b2c__ctr++) if($ARR[__b2c__ctr]!=NULL){free($ARR[__b2c__ctr]);} free($ARR);}"
		# Add macro in case of VAR argument
		echo "#define ${g_FUNCNAME}(...) __${g_FUNCNAME}(__VA_ARGS__, NULL)" >> $g_HFILE
		g_ORIGFUNCNAME="__${g_ORIGFUNCNAME}"
	    elif [[ ${TOKEN} = +(*STRING *) || ${TOKEN} = +(*char\* *) || ${TOKEN} = +(*${g_STRINGSIGN}*) ]]
	    then
	        TOKEN=$(echo ${TOKEN//\)/})
		# Add type if it is missing
		if [[ ${TOKEN} != +(* *) ]]
		then
		    TOKEN="char* ${TOKEN}"
		fi
                # Check if already declared
                if [[ -z $(Get_Var ${TOKEN##* } ${g_FUNCNAME}) ]]
	        then
		    Save_Func_Var "${TOKEN##* }" "${CURFUNC}" "${TOKEN% *}"
                else
	            echo -e "\nWarning: variable '${TOKEN##* }' in function header at line $g_COUNTER in file '$g_CURFILE' was defined previously!"
	        fi
		DIM=${TOKEN##*\[}; ARR=${TOKEN##* }
		if [[ $TOKEN != +(*${g_STRINGSIGN}*) && $TOKEN = +(*\[*\]*) ]]
		then
		    g_ORIGFUNCNAME="$g_ORIGFUNCNAME char *__b2c_${ARR%%\[*}[${DIM%%\]*}+$g_OPTION_BASE]"
		    g_STRINGARGS="$g_STRINGARGS char** ${ARR%%\[*} = __b2c_${ARR%%\[*};"
		    g_PROTOTYPE="$g_PROTOTYPE ${TOKEN}"
		elif [[ $TOKEN != +(*${g_STRINGSIGN}*) ]]
		then
		    g_ORIGFUNCNAME="$g_ORIGFUNCNAME char *__b2c_${TOKEN##* }"
		    g_STRINGARGS="$g_STRINGARGS char* ${TOKEN##* } = __b2c_${TOKEN##* };"
		    g_PROTOTYPE="$g_PROTOTYPE ${TOKEN}"
		elif [[ $TOKEN = +(*\[*\]*) ]]
		then
		    if [[ -z ${DIM%%\]*} ]]
		    then
			g_ORIGFUNCNAME="$g_ORIGFUNCNAME ${TOKEN}"
			g_PROTOTYPE="$g_PROTOTYPE ${TOKEN}"
		    else
			g_ORIGFUNCNAME="$g_ORIGFUNCNAME char *__b2c_${ARR%%\[*}[${DIM%%\]*}+$g_OPTION_BASE]"
			g_STRINGARGS="$g_STRINGARGS char *${ARR%%\[*}[${DIM%%\]*}+$g_OPTION_BASE] = { NULL };"
			g_STRINGARGS="$g_STRINGARGS for(__b2c__ctr=0; __b2c__ctr<${DIM%%\]*}+$g_OPTION_BASE; __b2c__ctr++){if(__b2c_${ARR%%\[*}[__b2c__ctr]!=NULL) ${ARR%%\[*}[__b2c__ctr] = __b2c__strdup(__b2c_${ARR%%\[*}[__b2c__ctr]);}"
			g_STRINGARRAYS="$g_STRINGARRAYS for(__b2c__ctr=0; __b2c__ctr<${DIM%%\]*}+$g_OPTION_BASE; __b2c__ctr++)if(${ARR%%\[*}[__b2c__ctr]!=NULL){free(${ARR%%\[*}[__b2c__ctr]);}"
			g_PROTOTYPE="$g_PROTOTYPE char *__b2c_${TOKEN##* }"
		    fi
		else
		    g_ORIGFUNCNAME="$g_ORIGFUNCNAME char *__b2c_${TOKEN##* }"
		    g_STRINGARGS="$g_STRINGARGS char *${TOKEN##* } = __b2c__strdup(__b2c_${TOKEN##* });"
		    g_LOCALSTRINGS="$g_LOCALSTRINGS ${TOKEN##* }"
		    g_PROTOTYPE="$g_PROTOTYPE ${TOKEN}"
		fi
	    else
	        TOKEN=$(echo ${TOKEN//\)/})
		# Add type if it is missing
		if [[ ${TOKEN} != +(* *) && ${TOKEN} != +(DIR*|FILE*|int*|short*|long*|float*|double*|char*|void*|STRING*|NUMBER*|FLOATING*) ]]
		then
		    if [[ ${TOKEN} = +(*${g_FLOATSIGN}) ]]
		    then
			TOKEN="double ${TOKEN}"
		    else
			TOKEN="${g_VARTYPE} ${TOKEN}"
		    fi
                fi
                # Check if already declared
                if [[ -z $(Get_Var ${TOKEN##* } ${g_FUNCNAME}) ]]
	        then
		    Save_Func_Var "${TOKEN##* }" "${CURFUNC}" "${TOKEN% *}"
                else
	            echo -e "\nWarning: variable '${TOKEN##* }' in function header at line $g_COUNTER in file '$g_CURFILE' was defined previously!"
	        fi
		if [[ $TOKEN = +(*\[*\]*\]*) ]]
		then
		    echo -e "\nSyntax error: cannot pass multidimensional numeric array at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		elif [[ $TOKEN = +(*\[\]*) ]]
		then
		    g_ORIGFUNCNAME="$g_ORIGFUNCNAME ${TOKEN}"
		elif [[ $TOKEN = +(*\[*\]*) ]]
		then
		    DIM=${TOKEN##*\[}; ARR=${TOKEN##* }
		    g_ORIGFUNCNAME="$g_ORIGFUNCNAME ${TOKEN%% *} __b2c_${ARR%%\[*}[${DIM%%\]*}+$g_OPTION_BASE]"
		    g_STRINGARGS="$g_STRINGARGS ${TOKEN%% *} ${ARR%%\[*}[${DIM%%\]*}+$g_OPTION_BASE] = { 0 };"
		    g_STRINGARGS="$g_STRINGARGS for(__b2c__ctr=0; __b2c__ctr<${DIM%%\]*}+$g_OPTION_BASE; __b2c__ctr++){ ${ARR%%\[*}[__b2c__ctr] = __b2c_${ARR%%\[*}[__b2c__ctr];}"
		elif [[ $TOKEN = +(*VAR *) ]]
		then
		    echo -e "\nSyntax error: variable argument list cannot be followed by other arguments at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    g_ORIGFUNCNAME="$g_ORIGFUNCNAME ${TOKEN}"
		fi
		g_PROTOTYPE="$g_PROTOTYPE ${TOKEN}"
	    fi
	    if [[ -n ${ARGS} ]]
	    then
		g_ORIGFUNCNAME="${g_ORIGFUNCNAME},"
		g_PROTOTYPE="${g_PROTOTYPE},"
	    else
		g_ORIGFUNCNAME="${g_ORIGFUNCNAME})"
		g_PROTOTYPE="${g_PROTOTYPE})"
	    fi
        done
    fi

    # Make symbol known to parser
    g_IMPORTED="$g_FUNCNAME $g_IMPORTED"

    # Save CATCH routine
    g_ORIGCATCHGOTO="$g_CATCHGOTO"
    g_ORIGCATCH_USED=${g_CATCH_USED}
    g_CATCHGOTO="__B2C__PROGRAM__EXIT"
    g_CATCH_USED=0
    g_STRINGARGS="$g_STRINGARGS __b2c__catch_set_backup = __b2c__catch_set; __b2c__catch_set = 0;"

    # Switch to header file
    g_COPY_CFILE=$g_CFILE
    g_COPY_COUNTER=$g_COUNTER
    g_CFILE=${g_CFILE%.*}.${g_FUNCNAME}.tmp

    touch $g_CFILE
}

#-----------------------------------------------------------

function Handle_Endsub
{
    typeset STR

    # Put prototype to header file
    echo "void ${g_PROTOTYPE};" >> $g_HFILE
    g_PROTOTYPE=

    # Get original function name
    echo "/* Created with BASH BaCon $g_VERSION - (c) Peter van Eerten - MIT License (Expat) */" > ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    echo "/* FILE $g_CURFILE LINE $g_COPY_COUNTER */" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    if [[ "$g_ORIGFUNCNAME" = +(* \(*\)*) ]]
    then
	echo "void ${g_ORIGFUNCNAME} {" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    elif [[ "$g_ORIGFUNCNAME" = +(*\(*\)*) ]]
    then
	echo "void ${g_ORIGFUNCNAME} {" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    else
	echo "void ${g_FUNCNAME}(void) {" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    fi

    # Finalize sub
    echo "${g_STRINGARGS}" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    cat $g_CFILE >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h

    # Free strings variables if there are any
    echo "${g_STRINGARRAYS}" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    for STR in $g_LOCALSTRINGS
    do
	echo "if($STR != NULL) free(${STR});" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    done
    if [[ $g_CATCH_USED -eq 1 ]]
    then
        echo "__B2C__PROGRAM__EXIT: ;" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    fi
    echo "__b2c__catch_set = __b2c__catch_set_backup;" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h
    echo "}" >> ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h

    # Include header file
    if [[ ${g_INCLUDE_FILES} != +(*${g_CURFILE%.*}.$g_FUNCNAME.h*) ]]
    then
	g_INCLUDE_FILES="$g_INCLUDE_FILES ${g_CURFILE%.*}.$g_FUNCNAME.h"
    fi

    # Add to total filelist
    g_TMP_FILES="$g_TMP_FILES ${g_TEMPDIR}/${g_CURFILE%.*}.$g_FUNCNAME.h"

    # Delete temp funcfile
    rm $g_CFILE

    # Restore mainfile
    g_CFILE=$g_COPY_CFILE

    # Restore CATCH routine
    g_CATCHGOTO="$g_ORIGCATCHGOTO"
    g_CATCH_USED=${g_ORIGCATCH_USED}

    # Reset variables
    g_ORIGFUNCNAME=
    g_FUNCNAME=
    g_LOCALSTRINGS=
    g_STRINGARRAYS=
    g_STRINGARGS=
}

#-----------------------------------------------------------

function Handle_Deffn
{
    typeset SYM
	
    # Check if we have an argument at all
    if [[ "$1" = "DEF" ]]
    then
	echo -e "\nSyntax error: empty DEF FN at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Translate to C macro
    SYM=${1#* }

    echo "#define ${SYM%%=*} (${SYM#*=})" >> $g_HFILE

    # Make symbol known to parser
    g_IMPORTED="${SYM%%\(*} $g_IMPORTED"
}

#-----------------------------------------------------------

function Handle_Const
{
    # Check if we have an argument at all
    if [[ "$1" = "CONST" ]]
    then
	echo -e "\nSyntax error: empty CONST at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    echo "#define ${1%%=*} ($(echo ${1#*=}))" >> $g_HFILE
}

#-----------------------------------------------------------

function Handle_Seek
{
    typeset FILE OFFSET WHENCE

    # Check if we have an argument at all
    if [[ "$1" = "SEEK" ]]
    then
	echo -e "\nSyntax error: empty SEEK at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if TO is available
    if [[ "$1" != +(* OFFSET *) ]]
    then
	echo -e "\nSyntax error: missing OFFSET in SEEK statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the variablename without surrounding spaces
    FILE=$(echo ${1%% OFFSET *})

    # Get filedescriptor
    OFFSET=$(echo ${1##* OFFSET })

    WHENCE=

    # Check if WHENCE is available
    if [[ "$1" = +(* WHENCE *) ]]
    then
	WHENCE=${OFFSET##* WHENCE }
	OFFSET=${OFFSET%% WHENCE *}
    fi

    # Convert to C function
    case $WHENCE in
	+(START) )
	    echo "fseek($FILE, $OFFSET, SEEK_SET);" >> $g_CFILE;;
	+(CURRENT) )
	    echo "fseek($FILE, $OFFSET, SEEK_CUR);" >> $g_CFILE;;
	+(END) )
	    echo "fseek($FILE, $OFFSET, SEEK_END);" >> $g_CFILE;;
	*)
	    echo "fseek($FILE, $OFFSET, SEEK_SET);" >> $g_CFILE;;
    esac
}

#-----------------------------------------------------------

function Handle_Copy
{
    typeset FROM TO SIZE

    # Check if we have an argument at all
    if [[ "$1" = "COPY" ]]
    then
	echo -e "\nSyntax error: empty COPY at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in COPY statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the filename and copyname
    FROM=$(echo ${1%% TO *})
    TO=$(echo ${1##* TO })

    if [[ ${TO} = +(* SIZE *) ]]
    then
        SIZE=$(echo ${TO##* SIZE })
        TO=$(echo ${TO%% SIZE *})
    fi

    # Translate to C function
    if [[ -z $SIZE ]]
    then
        echo "__b2c__inFile = fopen($FROM, \"r\"); __b2c__outFile = fopen($TO, \"w\");" >> $g_CFILE
        echo "while ((__b2c__Byte = fread(__b2c__input__buffer, sizeof(char), sizeof(__b2c__input__buffer), __b2c__inFile)) > 0){" >> $g_CFILE
        echo "if (fwrite(__b2c__input__buffer, sizeof(char), __b2c__Byte, __b2c__outFile) != __b2c__Byte) {if(__b2c__trap){ERROR = 2; if(!__b2c__catch_set) RUNTIMEERROR(\"COPY\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
        echo "} fclose(__b2c__inFile); fclose(__b2c__outFile);" >> $g_CFILE
    else
	echo "if (__b2c__trap){if(__b2c__memory__check((void*)${TO}, sizeof(__b2c__MEMTYPE)*${SIZE})) {ERROR=1; if(!__b2c__catch_set) RUNTIMEERROR(\"COPY\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
        if [[ ${FROM} = +(*${g_STRINGSIGN}*) ]]
        then
            echo "for(__b2c__ctr=0;__b2c__ctr<${SIZE};__b2c__ctr++){if(${TO}[__b2c__ctr+$g_OPTION_BASE]!=NULL){free(${TO}[__b2c__ctr+$g_OPTION_BASE]); ${TO}[__b2c__ctr+$g_OPTION_BASE] = NULL;}" >> $g_CFILE
            echo "if(${FROM}[__b2c__ctr+$g_OPTION_BASE]!=NULL) ${TO}[__b2c__ctr+$g_OPTION_BASE]=strdup(${FROM}[__b2c__ctr+$g_OPTION_BASE]);}" >> $g_CFILE
        else
            echo "memmove(${TO}, ${FROM}, sizeof(__b2c__MEMTYPE)*${SIZE});" >> $g_CFILE
        fi
    fi
    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
    then
        g_CATCH_USED=1
    fi
}

#-----------------------------------------------------------

function Handle_Rename
{
    typeset FROM TO

    # Check if we have an argument at all
    if [[ "$1" = "RENAME" ]]
    then
	echo -e "\nSyntax error: empty RENAME at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi
    
    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in RENAME statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the filename and copyname
    FROM=$(echo ${1%% TO *})
    TO=$(echo ${1##* TO })

    # Translate to C function
    echo "if(rename($FROM, $TO) < 0) {if(__b2c__trap){ERROR = 9; if(!__b2c__catch_set) RUNTIMEERROR(\"RENAME\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
    then
        g_CATCH_USED=1
    fi
}

#-----------------------------------------------------------

function Handle_Color
{
    typeset TO FROM BFG COL

    # Check if we have an argument at all
    if [[ "$1" = "COLOR" ]]
    then
	echo -e "\nSyntax error: empty COLOR at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if we need to reset
    if [[ "$1" = +(*RESET*) ]]
    then
	echo "fprintf(stdout,\"\033[0m\"); fflush(stdout);" >> $g_CFILE
    elif [[ "$1" = +(*INTENSE*) ]]
    then
	echo "fprintf(stdout,\"\033[1m\"); fflush(stdout);" >> $g_CFILE
    elif [[ "$1" = +(*INVERSE*) ]]
    then
	echo "fprintf(stdout,\"\033[7m\"); fflush(stdout);" >> $g_CFILE
    elif [[ "$1" = +(*NORMAL*) ]]
    then
	echo "fprintf(stdout,\"\033[22m\"); fflush(stdout);" >> $g_CFILE
    # Check if TO is available
    elif [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in COLOR statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    else
	# Get the target and colorname
	FROM=$(echo ${1%% TO *})
	case $FROM in
	    FG)
		BFG=3;;
	    BG)
		BFG=4;;
	    [01])
		((BFG=${FROM}+3));;
	    *)
		BFG=${FROM};;
	esac

	TO=$(echo ${1##* TO })
	case $TO in
	    BLACK)
		COL=0;;
	    RED)
		COL=1;;
	    GREEN)
		COL=2;;
	    YELLOW)
		COL=3;;
	    BLUE)
		COL=4;;
	    MAGENTA)
		COL=5;;
	    CYAN)
		COL=6;;
	    WHITE)
		COL=7;;
	    *)
		COL=${TO};;
	esac

	# Now select color
	echo "fprintf(stdout,\"\033[%ld%ldm\", (long)${BFG}, (long)${COL}); fflush(stdout);" >> $g_CFILE
    fi
}

#-----------------------------------------------------------

function Handle_Gotoxy
{
    typeset X Y

    # Check if we have an argument at all
    if [[ "$1" = "GOTOXY" ]]
    then
	echo -e "\nSyntax error: empty GOTOXY at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the target and colorname
    if [[ "$1" = +(*,*) ]]
    then
	X=$(echo ${1%%,*})
	Y=$(echo ${1##*,})
    else
	echo -e "\nSyntax error: missing coordinate in GOTOXY at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Translate to C
    echo "fprintf(stdout, \"\033[%ld;%ldH\",(long)(${Y}),(long)(${X}));fflush(stdout);" >> $g_CFILE
}

#-----------------------------------------------------------

function Handle_Split
{
    typeset SOURCE REST BY TO SIZE CHECK STATIC

    # Check if we have an argument at all
    if [[ "$1" = "SPLIT" ]]
    then
	echo -e "\nSyntax error: empty SPLIT at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi
    
    # Check if BY is available
    if [[ "$1" != +(* BY *) ]]
    then
	echo -e "\nSyntax error: missing BY in SPLIT statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in SPLIT statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if SIZE is available
    if [[ "$1" != +(* SIZE *) ]]
    then
	echo -e "\nSyntax error: missing SIZE in SPLIT statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the source string
    SOURCE=$(echo ${1%% BY *})
    REST=$(echo ${1##* BY })

    BY=$(echo ${REST%% TO *})
    REST=$(echo ${REST##* TO })

    TO=$(echo ${REST%% SIZE *})
    SIZE=$(echo ${REST##* SIZE })

    if [[ $SIZE = +(* STATIC*) ]]
    then
        SIZE=${SIZE%% STATIC*}
        STATIC=1
    else
        STATIC=0
    fi

    # Variable may not be array, these should be defined with DECLARE
    if [[ "${SIZE}" != +(*\[*\]*) && "${SIZE}" != +(*.*) && "${SIZE}" != +(*\(*\)*) && "${SIZE}" != +(*-\>*) ]]
    then
	# Declare variable if not done yet, assuming long
        if [[ -z $(Get_Var ${SIZE} ${g_FUNCNAME}) ]]
	then
            Register_Numeric ${SIZE}
	fi
    fi

    # Translate to C code
    if [[ -n $g_FUNCNAME ]]
    then
	if [[ $g_STRINGARGS != +(*\*\*$TO*) ]]
	then
	    g_STRINGARGS="$g_STRINGARGS char **$TO = NULL; char *__b2c__${TO}__dup = NULL; int __b2c__split__$TO = $g_OPTION_BASE;" 
            Save_Func_Var "${TO}" "$g_FUNCNAME" "char*"
            Save_Func_Var "__b2c__${TO}__dup" "$g_FUNCNAME" "char*"
            Save_Func_Var "__b2c__split__${TO}" "$g_FUNCNAME" "int"
	fi
    else
        if [[ -z $(Get_Var ${TO}) ]]
	then
	    echo "char **$TO = NULL; char *__b2c__${TO}__dup = NULL; int __b2c__split__$TO = $g_OPTION_BASE;" >> $g_HFILE
            Save_Main_Var "${TO}" "char*"
            Save_Main_Var "__b2c__${TO}__dup" "char*"
            Save_Main_Var "__b2c__split__${TO}" "int"
	fi
    fi

    # If the split array was used before in a loop, clear it
    if [[ $TO = +(*${g_STRINGSIGN}*) ]]
    then
        echo "if($TO != NULL) {for(__b2c__ctr=$g_OPTION_BASE; __b2c__ctr <= __b2c__split__$TO; __b2c__ctr++) if($TO[__b2c__ctr]!=NULL) {free($TO[__b2c__ctr]);} free($TO); $TO = NULL;}" >> $g_CFILE
    fi
    echo "__b2c__split__$TO = $g_OPTION_BASE;" >> $g_CFILE
    echo "if(__b2c__${TO}__dup != NULL) {free(__b2c__${TO}__dup);  __b2c__${TO}__dup = NULL;}" >> $g_CFILE

    # Run the SPLIT code
    echo "if ($SOURCE != NULL && strlen($SOURCE) > 0 && $BY != NULL && strlen($BY) > 0) {__b2c__${TO}__dup = __b2c__strdup($SOURCE); __b2c__split_tmp = __b2c__${TO}__dup;" >> $g_CFILE
    echo "while(1) {if((__b2c__split = strstr(__b2c__split_tmp, $BY)) != NULL) *__b2c__split = '\0'; if(strlen(__b2c__split_tmp) >0 || (strlen(__b2c__split_tmp) == 0 && __b2c__collapse == 0)) {" >> $g_CFILE
    echo "$TO = (char **)realloc($TO, (__b2c__split__$TO + 1) * sizeof(char*));" >> $g_CFILE
    if [[ $TO = +(*${g_STRINGSIGN}*) ]]
    then
        echo "${TO}[__b2c__split__${TO}++] = __b2c__strdup(__b2c__split_tmp);}" >> $g_CFILE
    else
        echo "${TO}[__b2c__split__${TO}++] = __b2c__split_tmp;}" >> $g_CFILE
    fi
    echo "if(__b2c__split == NULL) break; __b2c__split_tmp = __b2c__split + strlen($BY); } } $SIZE = __b2c__split__$TO - $g_OPTION_BASE; if(__b2c__split__$TO > 0) __b2c__split__$TO--;" >> $g_CFILE

    # Save information needed for a REDIM
    if [[ -n $g_FUNCNAME ]]
    then
        if [[ $g_STRINGARGS != +(*__b2c_array_${TO}*) ]]
        then
            g_STRINGARGS="$g_STRINGARGS long __b2c_array_${TO};"
        fi
    else
	echo "long __b2c_array_${TO};" >> $g_HFILE
    fi
    echo "__b2c_array_${TO} = ${SIZE};" >> $g_CFILE

    # Add declared array to array list if we are in a function
    if [[ -n $g_FUNCNAME && $g_STRINGARRAYS != +(*${TO}*) ]]
    then
        g_LOCALSTRINGS="${g_LOCALSTRINGS} __b2c__${TO}__dup"
        if [[ $STATIC -eq 0 ]]
        then
            if [[ $TO = +(*${g_STRINGSIGN}*) ]]
	    then
                g_STRINGARRAYS="$g_STRINGARRAYS if($TO != NULL) {for(__b2c__ctr=$g_OPTION_BASE; __b2c__ctr<__b2c_array_$TO+$g_OPTION_BASE; __b2c__ctr++) if($TO[__b2c__ctr]!=NULL){free($TO[__b2c__ctr]);} }"
            fi
            g_LOCALSTRINGS="$g_LOCALSTRINGS $TO"
        fi
    fi
}

#-----------------------------------------------------------

function Handle_Join
{
    typeset SOURCE REST BY TO SIZE STR

    # Check if we have an argument at all
    if [[ "$1" = "JOIN" ]]
    then
	echo -e "\nSyntax error: empty JOIN at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi
    
    # Check if BY is available
    if [[ "$1" != +(* BY *) ]]
    then
	echo -e "\nSyntax error: missing BY in JOIN statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in JOIN statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if SIZE is available
    if [[ "$1" != +(* SIZE *) ]]
    then
	echo -e "\nSyntax error: missing SIZE in JOIN statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the source string
    SOURCE=$(echo ${1%% BY *})
    REST=$(echo ${1##* BY })

    BY=$(echo ${REST%% TO *})
    REST=$(echo ${REST##* TO })

    TO=$(echo ${REST%% SIZE *})
    SIZE=$(echo ${REST##* SIZE })

    # Check type of var, string?
    if [[ "${TO}" != +(*${g_STRINGSIGN}) && "${TO%%\(*}" != +(*${g_STRINGSIGN}) && "${TO%%\[*}" != +(*${g_STRINGSIGN}) ]]
    then
	echo -e "\nSyntax error: variable ${TO} in JOIN statement must be string at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    else
        if [[ "${TO}" = +(*${g_STRINGSIGN}) && "${TO}" != +(*.*) ]]
	then
            if [[ -z $(Get_Var ${TO} ${g_FUNCNAME}) ]]
	    then
		echo "char *$TO = NULL;" >> $g_HFILE
                Save_Main_Var "${TO}" "char*"
	    fi
	fi
    fi

    echo "${TO} = realloc(${TO}, (strlen(${SOURCE}[0+$g_OPTION_BASE])+1)*sizeof(char)); strcpy(${TO}, ${SOURCE}[0+$g_OPTION_BASE]);" >> $g_CFILE

    echo "for(__b2c__ctr=1; __b2c__ctr < ${SIZE}; __b2c__ctr++){if(${SOURCE}[__b2c__ctr+$g_OPTION_BASE]!=NULL){" >> $g_CFILE
    echo "${TO} = realloc(${TO}, (strlen(${TO})+strlen(${BY})+strlen(${SOURCE}[__b2c__ctr+$g_OPTION_BASE])+1)*sizeof(char));" >> $g_CFILE
    echo "strcat(${TO}, ${BY}); strcat(${TO}, ${SOURCE}[__b2c__ctr+$g_OPTION_BASE]);} }" >> $g_CFILE
}

#-----------------------------------------------------------

function Handle_Sort
{
    typeset STR CHECK DIM TYPE VAR TMP DOWN

    # Check if we have an argument at all
    if [[ "$1" = "SORT" ]]
    then
	echo -e "\nSyntax error: empty SORT at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check on SIZE argument
    if [[ ${1} = +(* SIZE *) ]]
    then
	DIM=${1##* SIZE }
	VAR=${1%% SIZE *}
    else
	VAR=${1}
    fi

    # Check on DOWN argument
    if [[ ${1} = +(* DOWN*) ]]
    then
	DIM=${DIM%% DOWN}
	VAR=${VAR%% DOWN}
	DOWN="_down"
    else
	DOWN=
    fi

    # What kind of array are we dealing with? Associative
    CHECK=$(Get_Var __b2c__${VAR}_type ${g_FUNCNAME})
    if [[ -n $CHECK ]]
    then
        CHECK="assoc"
    else
        # Static Array? Determine data type
        CHECK=$(Get_Var ${VAR} ${g_FUNCNAME})
        if [[ -n $CHECK && ${g_DYNAMICARRAYS} != +(*${VAR}@${g_FUNCNAME}*) ]]
        then
            if [[ -z $DIM ]]
            then
	        if [[ -n $(Get_Var __b2c__split__${VAR} ${g_FUNCNAME}) ]]
                then
	            DIM="__b2c__split__${VAR}+1"
                else
	            DIM="$(Get_Dim ${VAR})"
                fi
            fi
        else
            # Assuming dynamic array - determine data type
            if [[ -n $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
            then
                if [[ -z $DIM ]]
                then
	            echo -e "\nSyntax error: SORT needs SIZE in case of dynamic array '${VAR}' at line $g_COUNTER in file '$g_CURFILE'!"
	            exit 1
                fi
            fi
        fi
    fi

    # Check if it is an assoc array
    if [[ "${CHECK}" = "assoc" ]]
    then
	echo "qsort(__b2c__$VAR, __b2c__${VAR}_idx, sizeof(struct __b2c__${VAR}_type), __b2c__${VAR}_sort$DOWN);" >> $g_CFILE
    # Check if we have a string
    elif [[ "${VAR}" = +(*${g_STRINGSIGN}) ]]
    then
	echo "qsort(&$VAR[$g_OPTION_BASE], ${DIM}-${g_OPTION_BASE}, sizeof(char*), __b2c__sortstr$DOWN);" >> $g_CFILE
    # It is a value
    else
	TYPE=${CHECK}
	if [[ $TYPE = +(*double*) || $TYPE = +(*FLOATING*) ]]
	then
	    echo "qsort(&$VAR[$g_OPTION_BASE], ${DIM}-${g_OPTION_BASE}, sizeof(double), __b2c__sortnrd$DOWN);" >> $g_CFILE
	elif [[ $TYPE = +(*float*) ]]
	then
	    echo "qsort(&$VAR[$g_OPTION_BASE], ${DIM}-${g_OPTION_BASE}, sizeof(float), __b2c__sortnrf$DOWN);" >> $g_CFILE
	elif [[ $TYPE = +(*long*) ||  $TYPE = +(*NUMBER*) ]]
	then
	    echo "qsort(&$VAR[$g_OPTION_BASE], ${DIM}-${g_OPTION_BASE}, sizeof(long), __b2c__sortnrl$DOWN);" >> $g_CFILE
	elif [[ $TYPE = +(*int*) ]]
	then
	    echo "qsort(&$VAR[$g_OPTION_BASE], ${DIM}-${g_OPTION_BASE}, sizeof(int), __b2c__sortnri$DOWN);" >> $g_CFILE
	elif [[ $TYPE = +(*short*) ]]
	then
	    echo "qsort(&$VAR[$g_OPTION_BASE], ${DIM}-${g_OPTION_BASE}, sizeof(short), __b2c__sortnrs$DOWN);" >> $g_CFILE
        else
	    echo "qsort(&$VAR[$g_OPTION_BASE], ${DIM}-${g_OPTION_BASE}, sizeof(char), __b2c__sortnrc$DOWN);" >> $g_CFILE
	fi
    fi
}

#-----------------------------------------------------------

function Handle_Alias
{
    typeset ORG NEW

    # Check if we have an argument at all
    if [[ "$1" = "ALIAS" ]]
    then
	echo -e "\nSyntax error: empty ALIAS at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in ALIAS statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the source string
    ORG=`echo ${1%% TO *} | tr -d "\042"`
    NEW=`echo ${1##* TO } | tr -d "\042"`

    echo "#define $NEW $ORG" >> $g_HFILE
    g_IMPORTED="$NEW $g_IMPORTED"
}

#-----------------------------------------------------------

function Handle_Lookup
{
    typeset SOURCE REST TO SIZE CHECK STATIC

    # Check if we have an argument at all
    if [[ "$1" = "LOOKUP" ]]
    then
	echo -e "\nSyntax error: empty LOOKUP at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in LOOKUP statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if SIZE is available
    if [[ "$1" != +(* SIZE *) ]]
    then
	echo -e "\nSyntax error: missing SIZE in LOOKUP statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the source string
    SOURCE=$(echo ${1%% TO *})
    REST=$(echo ${1##* TO })

    TO=$(echo ${REST%% SIZE *})
    SIZE=$(echo ${REST##* SIZE })

    if [[ $SIZE = +(* STATIC*) ]]
    then
        SIZE=${SIZE%% STATIC*}
        STATIC=1
    else
        STATIC=0
    fi

    # Variable may not be array, these should be defined with DECLARE
    if [[ "${SIZE}" != +(*\[*\]*) && "${SIZE}" != +(*.*) && "${SIZE}" != +(*\(*\)*) && "${SIZE}" != +(*-\>*) ]]
    then
	# Declare variable if not done yet, assuming long
        if [[ -z $(Get_Var ${SIZE} ${g_FUNCNAME}) ]]
	then
            Register_Numeric ${SIZE}
	fi
    fi

    # Translate to C code
    if [[ -n $g_FUNCNAME ]]
    then
	if [[ $g_STRINGARGS != +(*\*\*$TO*) ]]
	then
	    g_STRINGARGS="$g_STRINGARGS char **$TO = NULL; int __b2c__split__$TO = $g_OPTION_BASE;" 
            Save_Func_Var "${TO}" "$g_FUNCNAME" "char*"
            Save_Func_Var "__b2c__split__${TO}" "$g_FUNCNAME" "int"
	fi
    else
        if [[ -z $(Get_Var ${TO}) ]]
	then
	    echo "char **$TO = NULL; int __b2c__split__$TO = $g_OPTION_BASE;" >> $g_HFILE
            Save_Main_Var "${TO}" "char*"
            Save_Main_Var "__b2c__split__${TO}" "int"
	fi
    fi

    # If the split array was used before in a loop, clear it
    echo "if($TO != NULL) {for(__b2c__ctr=$g_OPTION_BASE; __b2c__ctr <= __b2c__split__$TO; __b2c__ctr++) if($TO[__b2c__ctr] != NULL)" >> $g_CFILE
    echo "{free($TO[__b2c__ctr]);} free($TO); $TO = NULL;} __b2c__split__$TO = $g_OPTION_BASE;" >> $g_CFILE

    # Run the LOOKUP code
    echo "for(__b2c__ctr = $g_OPTION_BASE; __b2c__ctr < __b2c__${SOURCE}_idx + $g_OPTION_BASE; __b2c__ctr++){$TO = (char **)realloc($TO, (__b2c__split__$TO + 1) * sizeof(char*));" >> $g_CFILE
    if [[ $TO = +(*${g_STRINGSIGN}*) ]]
    then
        echo "$TO[__b2c__split__$TO++] = __b2c__strdup(__b2c__${SOURCE}[__b2c__ctr-$g_OPTION_BASE].__b2c_key);" >> $g_CFILE
    else
        echo "$TO[__b2c__split__$TO++] = __b2c__${SOURCE}[__b2c__ctr-$g_OPTION_BASE].__b2c_key;" >> $g_CFILE
    fi
    echo "} $SIZE = __b2c__split__$TO - $g_OPTION_BASE; if(__b2c__split__$TO > 0) __b2c__split__$TO--;" >> $g_CFILE

    # Save information needed for a REDIM
    if [[ -n $g_FUNCNAME ]]
    then
        if [[ $g_STRINGARGS != +(*__b2c_array_${TO}*) ]]
        then
            g_STRINGARGS="$g_STRINGARGS long __b2c_array_${TO};"
        fi
    else
	echo "long __b2c_array_${TO};" >> $g_HFILE
    fi
    echo "__b2c_array_${TO} = ${SIZE};" >> $g_CFILE

    # Add declared array to array list if we are in a function
    if [[ -n $g_FUNCNAME && $g_STRINGARRAYS != +(*${TO}*) ]]
    then
        if [[ $STATIC -eq 0 ]]
        then
            if [[ $TO = +(*${g_STRINGSIGN}*) ]]
	    then
                g_STRINGARRAYS="$g_STRINGARRAYS if($TO != NULL) {for(__b2c__ctr=$g_OPTION_BASE; __b2c__ctr<__b2c_array_$TO+$g_OPTION_BASE; __b2c__ctr++) if($TO[__b2c__ctr]!=NULL){free($TO[__b2c__ctr]);} }"
            fi
            g_LOCALSTRINGS="$g_LOCALSTRINGS $TO"
        fi
    fi
}

#-----------------------------------------------------------

function Handle_Relate
{
    typeset SOURCE TO STR

    # Check if we have an argument at all
    if [[ "$1" = "RELATE" ]]
    then
	echo -e "\nSyntax error: empty RELATE at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in RELATE statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the source string
    SOURCE=$(echo ${1%% TO *})
    TO=`echo ${1##* TO } | tr "," " "`

    # Check if variable is declared as ASSOC
    if [[ -z $(Get_Var __b2c__${SOURCE}_type) ]]
    then
	echo -e "\nSyntax error: variable '$SOURCE' not declared as ASSOC in RELATE statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Assign relations
    for STR in ${TO}
    do
        if [[ -z $(Get_Var __b2c__${STR}_type) ]]
	then
	    echo -e "\nSyntax error: variable '$STR' not declared as ASSOC in RELATE statement at line $g_COUNTER in file '$g_CURFILE'!"
	    exit 1
	fi
	g_RELATE[${g_RELATE_CTR}]="$SOURCE ${STR}"
	((g_RELATE_CTR+=1))
    done
}

#-----------------------------------------------------------

function Handle_Data
{
    typeset LINE EXP TOKEN

    # Check if we have an argument at all
    if [[ "$1" = "DATA" ]]
    then
	echo -e "\nSyntax error: empty DATA at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    EXP=$(echo $1)

    # Start miniparser to see if we need to print something
    while [[ -n ${EXP} ]]
    do
        TOKEN=$(Mini_Parser "${EXP}")
	if [[ "${TOKEN}" = +(*${g_DQUOTESIGN}*) ]]
	then
	    echo "${TOKEN}, " >> $STRINGARRAYFILE
            ((g_CCTR+=1))
	else
	    echo "${TOKEN}, " >> $FLOATARRAYFILE
            ((g_FCTR+=1))
	fi
        EXP="${EXP:${#TOKEN}+1}"
    done
}

#-----------------------------------------------------------

function Handle_Redim
{
    typeset VAR TO CHECK TYPE

    # Check if we have an argument at all
    if [[ "$1" = "REDIM" ]]
    then
	echo -e "\nSyntax error: empty REDIM at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if TO is available
    if [[ "$1" != +(* TO *) ]]
    then
	echo -e "\nSyntax error: missing TO in REDIM statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the variable and resize
    VAR=$(echo ${1%% TO *})
    TO=$(echo ${1##* TO })

    CHECK=$(Get_Var ${VAR} ${g_FUNCNAME})
    if [[ -z $CHECK ]]
    then
	echo -e "\nSyntax error: cannot REDIM array which is not declared previously at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Delete old data from strings if new size is smaller
    if [[ "${CHECK%% *}" = +(*STRING*|*char\*\*) || "${VAR}" = +(*${g_STRINGSIGN}) ]]
    then
	echo "if(${TO}<__b2c_array_${VAR##*.}) {for(__b2c__ctr=${TO}+$g_OPTION_BASE; __b2c__ctr<__b2c_array_${VAR##*.}+$g_OPTION_BASE; __b2c__ctr++) {if($VAR[__b2c__ctr]!=NULL) free($VAR[__b2c__ctr]);} }" >> $g_CFILE
    fi

    # Realloc
    TYPE=${CHECK}
    echo "${VAR} = (${TYPE}*)realloc(${VAR}, (${TO}+$g_OPTION_BASE)*sizeof(${TYPE}));" >> $g_CFILE

    # Re-initialize strings if new area is bigger
    if [[ "${CHECK}" = +(*STRING*|*char\*\*) || "${VAR}" = +(*${g_STRINGSIGN}) ]]
    then
	echo "if(${TO}>__b2c_array_${VAR##*.}) {for(__b2c__ctr=__b2c_array_${VAR##*.}+$g_OPTION_BASE; __b2c__ctr<${TO}+$g_OPTION_BASE; __b2c__ctr++) $VAR[__b2c__ctr] = calloc(1, sizeof(char));}" >> $g_CFILE
        echo "__b2c_array_${VAR##*.} = $TO;" >> $g_CFILE
    fi
}

#-----------------------------------------------------------

function Handle_Swap
{
    typeset VAR TO CHECK TYPE

    # Check if we have an argument at all
    if [[ "$1" = "SWAP" ]]
    then
	echo -e "\nSyntax error: empty SWAP at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Get the variable names without spaces
    VAR=`echo ${1%%,*} | tr -d "\040"`
    TO=`echo ${1##*,} | tr -d "\040"`

    # Determine type
    if [[ "${VAR}" = +(*${g_STRINGSIGN}*) ]]
    then
        TYPE="char*"
    else
        CHECK=$(Get_Var ${VAR} ${g_FUNCNAME})
        if [[ -z $CHECK ]]
        then
	    echo -e "\nSyntax error: cannot determine type of variables in SWAP at line $g_COUNTER in file '$g_CURFILE'!"
	    exit 1
        fi
        # Leave one dimension out to exchange array variables
        TYPE=${CHECK%%\**}
    fi

    # Declare temp variable
    if [[ -n $g_FUNCNAME ]]
    then
        if [[ -z $(Get_Var __b2c__${VAR%%\[*}_swap ${g_FUNCNAME}) ]]
        then
            echo "${TYPE} __b2c__${VAR%%\[*}_swap;" >> $g_CFILE
            Save_Func_Var "__b2c__${VAR%%\[*}_swap" "${g_FUNCNAME}" "${TYPE}"
        fi
    else
        if [[ -z $(Get_Var __b2c__${VAR%%\[*}_swap) ]]
        then
            echo "${TYPE} __b2c__${VAR%%\[*}_swap;" >> $g_HFILE
            Save_Main_Var "__b2c__${VAR%%\[*}_swap" "${TYPE}"
        fi
    fi

    echo "__b2c__${VAR%%\[*}_swap = ${VAR}; ${VAR} = ${TO}; ${TO} = __b2c__${VAR%%\[*}_swap;" >> $g_CFILE
}

#-----------------------------------------------------------

function Handle_Setserial
{
    typeset DESC VALUE

    # Check if we have an argument at all
    if [[ "$1" = "SETSERIAL" ]]
    then
	echo -e "\nSyntax error: empty SETSERIAL at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Check if a mode is available
    if [[ "$1" != +(* IMODE *) && "$1" != +(* OMODE *) && "$1" != +(* CMODE *) && "$1" != +(* LMODE *) && "$1" != +(* OTHER *) && "$1" != +(* SPEED *) ]]
    then
	echo -e "\nSyntax error: no mode specified in SETSERIAL statement at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    DESC=${1%% *}

    # Get the setting
    if [[ ${1} = +(* OTHER *) ]]
    then
        VALUE=${1##* OTHER }
    elif [[ ${1} = +(* SPEED *) ]]
    then
        VALUE=${1##* SPEED }
    else
        VALUE=${1##*MODE }
    fi

    # Set the option for the file descriptor
    echo "memset (&__b2c__tty, 0, sizeof __b2c__tty); if (tcgetattr (${DESC}, &__b2c__tty) != 0)" >> $g_CFILE
    echo "{if(__b2c__trap){ERROR = 33; if(!__b2c__catch_set) RUNTIMEERROR(\"SETSERIAL\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE

    case $1 in
        +(*IMODE*) )
            if [[ $VALUE = +(*~*) ]]
            then
                echo "__b2c__tty.c_iflag &= ${VALUE};" >> $g_CFILE
            else
                echo "__b2c__tty.c_iflag |= ${VALUE};" >> $g_CFILE
            fi
            ;;
        +(*OMODE*) )
            if [[ $VALUE = +(*~*) ]]
            then
                echo "__b2c__tty.c_oflag &= ${VALUE};" >> $g_CFILE
            else
                echo "__b2c__tty.c_oflag |= ${VALUE};" >> $g_CFILE
            fi
            ;;
        +(*CMODE*) )
            if [[ $VALUE = +(*~*) ]]
            then
                echo "__b2c__tty.c_cflag &= ${VALUE};" >> $g_CFILE
            else
                echo "__b2c__tty.c_cflag |= ${VALUE};" >> $g_CFILE
            fi
            ;;
        +(*LMODE*) )
            if [[ $VALUE = +(*~*) ]]
            then
                echo "__b2c__tty.c_lflag &= ${VALUE};" >> $g_CFILE
            else
                echo "__b2c__tty.c_lflag |= ${VALUE};" >> $g_CFILE
            fi
            ;;
        +(*OTHER*) )
            echo "__b2c__tty.c_cc[${VALUE%=*}] = ${VALUE#*=};" >> $g_CFILE
            ;;
        +(*SPEED*) )
            echo "cfsetospeed (&__b2c__tty, ${VALUE}); cfsetispeed (&__b2c__tty, ${VALUE});" >> $g_CFILE
            ;;
    esac

    echo "if (tcsetattr (${DESC}, TCSANOW, &__b2c__tty) != 0)" >> $g_CFILE
    echo "{if(__b2c__trap){ERROR = 33; if(!__b2c__catch_set) RUNTIMEERROR(\"SETSERIAL\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
    then
        g_CATCH_USED=1
    fi
}

#-----------------------------------------------------------

function Handle_Call
{
    typeset CHECK STR VAR

    # Check if we have an argument at all
    if [[ "$1" = "CALL" ]]
    then
	echo -e "\nSyntax error: empty CALL at line $g_COUNTER in file '$g_CURFILE'!"
	exit 1
    fi

    # Just call, no assignment
    if [[ "${1}" != +(* TO *) ]]
    then
	if [[ "${1}" = +(*\(*\)*) ]]
	then
	    echo "${1};" >> $g_CFILE
	else
	    echo "${1}();" >> $g_CFILE
	fi
    else
        VAR="${1##*TO }"
        # Check if string is declared
        if [[ "${VAR}" = +(*${g_STRINGSIGN}) && "${VAR}" != +(*.*) ]]
        then
            if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	    then
	        echo "char *${VAR} = NULL;" >> $g_HFILE
                Save_Main_Var "${VAR}" "char*"
	    fi
        # Not a string?
        elif [[ "${VAR}" != +(*\[*\]*) && "${VAR}" != +(*.*) && "${VAR}" != +(*\(*\)*) && "${VAR}" != +(*-\>*) ]]
        then
            if [[ -z $(Get_Var ${VAR} ${g_FUNCNAME}) ]]
	    then
                Register_Numeric ${VAR}
	    fi
        fi

        # String variable?
        if [[ "${VAR}" = +(*${g_STRINGSIGN}) || "${VAR%%\(*}" = +(*${g_STRINGSIGN}) || "${VAR%%\[*}" = +(*${g_STRINGSIGN}) ]]
        then
            if [[ "${1%% TO*}" = +(*\(*\)*) ]]
            then
                echo "__b2c__assign=(char*)__b2c__strdup(${1%% TO*});" >> $g_CFILE
            else
                echo "__b2c__assign=(char*)__b2c__strdup(${1%% TO*}());" >> $g_CFILE
            fi
            echo "if(__b2c__assign==NULL) __b2c__assign = calloc(1, sizeof(char));" >> $g_CFILE
            # Now see if we have a assoc or a normal variable
	    if [[ "${VAR}" = +(*\(*\)) ]]
	    then
	        STR=${VAR#*\(}
	        echo "__b2c__${VAR%%\(*}__location = __b2c__${VAR%%\(*}__add(${STR};" >> $g_CFILE
	        echo "if(__b2c__${VAR%%\(*}__location->__b2c_value != NULL) free(__b2c__${VAR%%\(*}__location->__b2c_value); __b2c__${VAR%%\(*}__location->__b2c_value = __b2c__assign;" >> $g_CFILE
	        # Check for relations
	        Relate_Recurse "${VAR%%\(*}" "${STR}" "${VAR}" "-1"
	    else
                echo "if(${VAR} != NULL) free(${VAR}); ${VAR} = __b2c__assign;" >> $g_CFILE
	    fi
        else
	    # Now see if we have an assoc or a normal variable
	    if [[ "${VAR}" = +(*\(*\)) ]]
	    then
	        STR=${VAR#*\(}
	        echo "__b2c__${VAR%%\(*}__location = __b2c__${VAR%%\(*}__add(${STR};" >> $g_CFILE
	        if [[ "${1%% TO*}" = +(*\(*\)*) ]]
                then
                    echo "__b2c__${VAR%%\(*}__location->__b2c_value = ${1%% TO*};" >> $g_CFILE
                else
                    echo "__b2c__${VAR%%\(*}__location->__b2c_value = ${1%% TO*};" >> $g_CFILE
                fi
	        # Check for relations
	        Relate_Recurse "${VAR%%\(*}" "${STR}" "${VAR}" "-1"
            else
	        if [[ "${1%% TO*}" = +(*\(*\)*) ]]
	        then
		    echo "${VAR} = ${1%% TO*};" >> $g_CFILE
	        else
		    echo "${VAR} = ${1%% TO*}();" >> $g_CFILE
                fi
	    fi
	fi
    fi
}

#-----------------------------------------------------------
#
# Simple parser to tokenize line.
#
# Each line should begin with a statement.
# The rest of the line may contain functions, these are
#   converted using C macros.
#
#-----------------------------------------------------------

function Parse_Line
{
    typeset FOUND SYM INC COPY_COUNTER COPY_CURFILE STATEMENT CHECK FLINES
    typeset LEN SEQ TOTAL EXP LINE TO_PARSE NEWFEED TRC_BACKUP TOKEN

    if [[ -z ${1} ]]
    then
        return
    fi

    # Get statement without spaces
    if [[ ${1} != +(*\*/) ]]
    then
        STATEMENT=$(echo ${1%% *})
    else
        STATEMENT=$(echo ${1})
    fi

    # See if we need to pass C code
    if [[ $g_USE_C -eq 1 ]]
    then
	if [[ ${@} = +(END*USEC) ]]
	then
	    let g_USE_C=0
	elif [[ ${@} = +(END*ENUM) ]]
	then
	    let g_USE_C=0
            echo "};" >> $g_CFILE
	else
	    echo "${1}" >> $g_CFILE
	fi
    elif [[ $g_USE_H -eq 1 ]]
    then
	if [[ ${@} = +(END*USEH) ]]
	then
	    let g_USE_H=0
	else
	    echo "${1}" >> $g_HFILE
	fi
    # This covers both 1 line and multiline comments with */
    elif [[ "$STATEMENT" = +(*\*/) ]]
    then
        g_COMMENT="false"
    elif [[ ${g_COMMENT} = "false" ]]
    then
	case "${STATEMENT}" in
	    "USEC")
		let g_USE_C=1;;
	    "USEH")
		let g_USE_H=1;;
	    "PRINT")
		Handle_Print "${1#* }" "stdout";;
	    "EPRINT")
		Handle_Print "${1#* }" "stderr";;
	    "INPUT")
		Handle_Input "${1#* }";;
	    "FOR")
                ((g_LOOPCTR+=1))
		Handle_For "${1#* }";;
	    "NEXT")
                if [[ ${g_LOOPVAR[${g_LOOPCTR}]} = +(*${g_STRINGSIGN}*) ]]
                then
                    echo "${g_LOOPVAR[${g_LOOPCTR}]} = (char*)__b2c_Copy_String(${g_LOOPVAR[${g_LOOPCTR}]}, strtok_r(NULL, ${g_LOOPSTEP[${g_LOOPCTR}]}, &__b2c__forin_${g_LOOPVAR[${g_LOOPCTR}]}_end));}" >> $g_CFILE
		    echo "if(__b2c__forin_${g_LOOPVAR[${g_LOOPCTR}]}!=NULL) { free(__b2c__forin_${g_LOOPVAR[${g_LOOPCTR}]}); __b2c__forin_${g_LOOPVAR[${g_LOOPCTR}]} = NULL; }" >> $g_CFILE
		    g_LOOPVAR[${g_LOOPCTR}]=
		    g_LOOPSTEP[${g_LOOPCTR}]=
                else
		    echo "}" >> $g_CFILE
                fi
                if [[ $g_LOOPCTR -gt 0 ]]
                then
                    ((g_LOOPCTR-=1))
                    if [[ $g_LOOPCTR -gt 0 ]]
                    then
                        echo "if(__b2c__break_ctr) {__b2c__break_ctr--; if (!__b2c__break_ctr){if(__b2c__break_flag == 1) break; else continue;} else break; }" >> $g_CFILE
                    fi
                fi;;
	    "IF")
		# Check if THEN is available
		if [[ "${1}" != +(* THEN*) ]]
		then
		    echo -e "\nSyntax error: missing THEN in IF statement at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    SYM="${1#* }"
		    # Translate function to C function
                    Parse_Equation "${SYM% THEN*}"
		    echo "if(${g_EQUATION}){" >> $g_CFILE
		    if [[ ${SYM##* THEN } != +(*THEN*) ]]
		    then
                        TRC_BACKUP=${g_TRACE}
                        g_TRACE=0
			Tokenize "${SYM##* THEN }"
                        g_TRACE=${TRC_BACKUP}
                        echo "}" >> $g_CFILE
		    fi
		fi;;
	    "ELIF")
		# Check if THEN is available
		if [[ "${1}" != +(* THEN*) ]]
		then
		    echo -e "\nSyntax error: missing THEN in ELIF statement at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    SYM="${1#* }"
		    # Translate function to C function
                    Parse_Equation "${SYM% THEN*}"
		    if [[ ${SYM##* THEN } != +(*THEN*) ]]
		    then
		        echo "else if(${g_EQUATION}){" >> $g_CFILE
                        g_TRACE_PREFIX="ELIF "
			Tokenize "${SYM##* THEN }"
                        echo "}" >> $g_CFILE
                    else
		        echo "} else if(${g_EQUATION}){" >> $g_CFILE
                        g_TRACE_PREFIX="ELIF "
		    fi
		fi;;
	    "ELSE")
		if [[ ${1##*ELSE } != +(*ELSE*) ]]
		then
		    echo "else {" >> $g_CFILE
                    g_TRACE_PREFIX="ELSE "
		    Tokenize "${1##*ELSE }"
                    echo "}" >> $g_CFILE
                else
		    echo "} else {" >> $g_CFILE
                    g_TRACE_PREFIX="ELSE "
		fi;;
	    "ENDIF")
		echo "}" >> $g_CFILE;;
	    "FI")
		echo "}" >> $g_CFILE;;
	    "WHILE")
                ((g_LOOPCTR+=1))
		Handle_While "${1#* }";;
	    "WEND")
		echo "}" >> $g_CFILE
                if [[ $g_LOOPCTR -gt 0 ]]
                then
                    ((g_LOOPCTR-=1))
                    if [[ $g_LOOPCTR -gt 0 ]]
                    then
                        echo "if(__b2c__break_ctr) {__b2c__break_ctr--; if (!__b2c__break_ctr){if(__b2c__break_flag == 1) break; else continue;} else break; }" >> $g_CFILE
                    fi
                fi;;
	    "BREAK")
                # Check argument
		if [[ "${1%% *}" != "${1#* }" && ${1#* } != "0" ]]
		then
                    echo "__b2c__break_ctr = ${1#* }-1; __b2c__break_flag = 1;" >> $g_CFILE
                fi
		echo "break;" >> $g_CFILE;;
            "CONTINUE")
                # Check argument
		if [[ "${1%% *}" != "${1#* }" && ${1#* } != "0" ]]
		then
                    echo "__b2c__break_ctr = ${1#* }-1; __b2c__break_flag = 2;" >> $g_CFILE
                fi
                if [[ ${1#* } -gt 1 ]]
                then
		    echo "break;" >> $g_CFILE
                else
		    echo "continue;" >> $g_CFILE
                fi;;
	    "REPEAT")
                ((g_LOOPCTR+=1))
		echo "do{" >> $g_CFILE;;
	    "UNTIL")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty UNTIL at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    # Convert to legal C code
                    Parse_Equation "${1#* }"
		    echo "} while(!(${g_EQUATION}));" >> $g_CFILE
                    if [[ $g_LOOPCTR -gt 0 ]]
                    then
                        ((g_LOOPCTR-=1))
                        if [[ $g_LOOPCTR -gt 0 ]]
                        then
                            echo "if(__b2c__break_ctr) {__b2c__break_ctr--; if (!__b2c__break_ctr){if(__b2c__break_flag == 1) break; else continue;} else break; }" >> $g_CFILE
                        fi
                    fi
		fi;;
	    "LET")
		Handle_Let "${1#* }";;
	    +(REM*) )
		;;
	    +(\'*) )
                ;;
            +(/\**) )
                g_COMMENT="true";;
	    "SYSTEM")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty SYSTEM at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    echo "SYSTEM (${1#* });" >> $g_CFILE
		fi;;
	    "SLEEP")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty SLEEP at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    echo "usleep(${1#* }*1000);" >> $g_CFILE
		fi;;
	    "OPEN")
		Handle_Open "${1#* }";;
	    "CLOSE")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty CLOSE at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
                    EXP=$(echo ${1#*CLOSE })
		    if [[ "$EXP" = +(FILE *) ]]
		    then
                        EXP=${EXP#* }
                        while [[ -n ${EXP} ]]
                        do
                            TOKEN=$(Mini_Parser "${EXP}")
			    echo "fclose(${TOKEN});" >> $g_CFILE
                            EXP="${EXP:${#TOKEN}+1}"
                        done
		    elif [[ "$EXP" = +(DIRECTORY *) ]]
		    then
                        EXP=${EXP#* }
                        while [[ -n ${EXP} ]]
                        do
                            TOKEN=$(Mini_Parser "${EXP}")
			    echo "closedir(${TOKEN});" >> $g_CFILE
                            EXP="${EXP:${#TOKEN}+1}"
                        done
		    elif [[ "$EXP" = +(MEMORY *) ]]
		    then
                        EXP=${EXP#* }
                        while [[ -n ${EXP} ]]
                        do
                            TOKEN=$(Mini_Parser "${EXP}")
			    echo "${TOKEN} = NULL;" >> $g_CFILE
                            EXP="${EXP:${#TOKEN}+1}"
                        done
		    elif [[ "$EXP" = +(NETWORK *) || "$1" = +(SERVER *) || "$1" = +(UDP *) || "${1}" = +(DEVICE *) ]]
		    then
                        EXP=${EXP#* }
                        while [[ -n ${EXP} ]]
                        do
                            TOKEN=$(Mini_Parser "${EXP}")
			    echo "close(${TOKEN});" >> $g_CFILE
                            EXP="${EXP:${#TOKEN}+1}"
                        done
		    else
			echo -e "\nSyntax error: erronuous CLOSE argument at line $g_COUNTER in file '$g_CURFILE'!"
			exit 1
		    fi
		fi;;
	    "REWIND")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty REWIND at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    echo "rewind(${1#* });" >> $g_CFILE
		fi;;
	    "MEMREWIND")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty MEMREWIND at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    echo "${1#* } = (char*)__b2c_mem_${1#* };" >> $g_CFILE
		fi;;
	    "SEEK")
		Handle_Seek "${1#* }";;
	    "READLN")
		Handle_Readln "${1#* }";;
	    "WRITELN")
		Handle_Writeln "${1#* }";;
	    "GETBYTE")
		Handle_Getbyte "${1#* }";;
	    "PUTBYTE")
		Handle_Putbyte "${1#* }";;
	    "GETFILE")
		Handle_Getfile "${1#* }";;
	    "GETLINE")
		Handle_Getline "${1#* }";;
	    "PUTLINE")
		Handle_Putline "${1#* }";;
	    "END")
		if [[ "${1#* }" = +(*IF*) ]]
		then
		    echo "}" >> $g_CFILE
		elif [[ "${1#* }" = +(*RECORD*) ]]
		then
		    if [[ -n $g_FUNCNAME ]]
		    then
			echo "};" >> $g_CFILE
			echo "struct $g_RECORDNAME $g_RECORDVAR = { 0 } ;" >> $g_CFILE
		    else
			echo "};" >> $g_HFILE
			echo "struct $g_RECORDNAME $g_RECORDVAR = { 0 } ;" >> $g_HFILE
                        echo $g_RECORDEND_HEADER >> $g_HFILE
		    fi
		    echo $g_RECORDEND_BODY >> $g_CFILE
		    g_RECORDNAME=
		    g_RECORDVAR=
		    g_RECORDEND_BODY=
                    g_RECORDEND_HEADER=
		    # Restore function name if GLOBAL was used
		    if [[ -n $g_RECORDCACHE ]]
		    then
			g_FUNCNAME=$g_RECORDCACHE
			g_RECORDCACHE=
		    fi
		elif [[ "${1#* }" = +(*FUNCTION*) ]]
		then
		    Handle_Endfunction
		elif [[ "${1#* }" = +(*SUB*) ]]
		then
		    Handle_Endsub
		elif [[ "${1#* }" = +(*WITH*) ]]
		then
		    g_WITHVAR=
		elif [[ "${1#* }" = +(*SELECT*) ]]
		then
		    if [[ $g_SELECTVAR_CTR -eq 0 ]]
		    then
			echo -e "\nSyntax error: invalid END SELECT at line $g_COUNTER in file '$g_CURFILE'!"
			exit 1
		    else
			echo "}" >> $g_CFILE
			g_SELECTVAR[$g_SELECTVAR_CTR]=
			g_IN_CASE[$g_SELECTVAR_CTR]=
			g_CASE_FALL=
			((g_SELECTVAR_CTR-=1))
		    fi
		elif [[ "${1#* }" != "END" ]]
		then
		    echo "exit(${1#* });" >> $g_CFILE
		else
		    echo "exit(EXIT_SUCCESS);" >> $g_CFILE
		fi;;
	    "SUB")
		Handle_SubFunc "${1#* }";;
	    "ENDSUB")
		Handle_Endsub;;
	    "ENDWITH")
		g_WITHVAR=;;
	    "ENDSELECT")
		if [[ $g_SELECTVAR_CTR -eq 0 ]]
		then
		    echo -e "\nSyntax error: invalid END SELECT at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    echo "}" >> $g_CFILE
		    g_SELECTVAR[$g_SELECTVAR_CTR]=
		    g_IN_CASE[$g_SELECTVAR_CTR]=
		    g_CASE_FALL=
		    ((g_SELECTVAR_CTR-=1))
		fi;;
	    "CALL")
		Handle_Call "${1#* }";;
	    "FUNCTION")
		Handle_SubFunc "${1#* }";;
	    "ENDFUNCTION")
		Handle_Endfunction;;
	    "RETURN")
		Handle_Return "${1#* }";;
	    "IMPORT")
		Handle_Import "${1#* }";;
	    "DECLARE")
		Handle_Declare "${1#* }";;
	    "GLOBAL")
		Handle_Declare "${1#* }";;
	    "LOCAL")
		Handle_Local "${1#* }";;
	    "DATA")
		Handle_Data "${1#* }";;
	    "RESTORE")
                if [[ "${1%% *}" = "${1#* }" ]]
                then
		    echo "__b2c__floatarray_ptr = 0;" >> $g_CFILE
		    echo "__b2c__stringarray_ptr = 0;" >> $g_CFILE
                else
                    echo "__b2c__data_jump_flag = 1; if(!setjmp(__b2c__data_jump)) goto ${1#* };" >> $g_CFILE
		    echo "__b2c__floatarray_ptr = __b2c__label_floatarray_${1#* };" >> $g_CFILE
		    echo "__b2c__stringarray_ptr = __b2c__label_stringarray_${1#* };" >> $g_CFILE
                fi;;
	    "READ")
		Handle_Read "${1#* }";;
	    "PUSH")
		Handle_Push "${1#* }";;
	    "PULL")
		Handle_Pull "${1#* }";;
	    "SEED")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty SEED at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    echo "srandom((unsigned int)${1#* });" >> $g_CFILE
		fi;;
	    "DEF")
		Handle_Deffn "${1#* }";;
	    "CONST")
		Handle_Const "${1#* }";;
	    "INCLUDE")
		# Get rid of doublequotes if they are there
		INC=`echo ${1#* } | tr -d "\042"`
		# Check argument
		if [[ ! -f ${INC%%,*} || "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSystem error: missing file '${INC%%,*}' for INCLUDE at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    # Clear current terminal line
		    echo -e -n "\r\033[2K"
		    TO_PARSE=0
		    # See if there are arguments
		    if [[ ${INC} = +(*,*) ]]
		    then
			EXP=`echo ${INC#*,} | tr "," " " | tr -d "${g_STRINGSIGN}"`
			INC=${INC%%,*}
		    else
			TO_PARSE=2
		    fi
		    # Check if the C Preprocessor needs to run
		    if [[ $g_CPP -eq 1 ]]
		    then
			if [[ -n `which cpp 2>/dev/null` ]]
			then
                            echo -n "Preprocessing '${INC}'... "
                            # Change next line marker to overcome C preprocessor interpretation
                            while read -r LINE; do if [[ ${LINE} = +(\#*) ]]; then echo "${LINE}"; else echo "@${LINE}@"; fi; done < $INC > $INC.tmp
                            cpp -w -P $INC.tmp $INC.cpp
                            # Restore the next line marker
                            while read -r LINE; do LINE="${LINE:1}"; echo "${LINE%@*}"; done < $INC.cpp > $INC.bac
			    g_TMP_FILES="$g_TMP_FILES ${INC}.cpp ${INC}.tmp ${INC}.bac"
			    NEWFEED="${INC}.bac"
                            echo "done."
			else
			    echo "System error: the C Preprocessor 'cpp' not found on this system! Exiting..."
			    exit 1
			fi
		    else
			NEWFEED=${INC}
		    fi
		    # Start walking through program
		    COPY_COUNTER=$g_COUNTER
		    g_COUNTER=1
		    # Assign new file
		    COPY_CURFILE=$g_CURFILE
		    # Get rid of absolute path
		    g_CURFILE=${NEWFEED##*/}
		    while read -r LINE
		    do
			echo -e -n "\rConverting '${INC}'... ${g_COUNTER}\033[0K"
			# See if we need to enable flag
			for SYM in ${EXP}
			do
			    if [[ $TO_PARSE -eq 0 && "${LINE#* }" = +(${SYM%${g_STRINGSIGN}*}*) && "${LINE}" = +(*SUB*|*FUNCTION*) || "${LINE}" = +(*INCLUDE) ]]
			    then
				TO_PARSE=1
				break
			    fi
			done
			# Line is not empty?
			if [[ -n "$LINE" && $TO_PARSE -gt 0 ]]
			then
			    if [[ "$LINE" = +(* \\) && "$LINE" != +(REM*) && "$LINE" != +(${g_SQUOTESIGN}*) ]]
			    then
				let LEN="${#LINE}"-2
				SEQ="${LINE:0:$LEN}"
				TOTAL=$TOTAL$SEQ
                            else
				echo "/* FILE ${INC} LINE $g_COUNTER */" >> $g_CFILE
				echo "/* FILE ${INC} LINE $g_COUNTER */" >> $g_HFILE
				TOTAL="${TOTAL}${LINE}"
				if [[ "${TOTAL}" != +(REM*) && "${TOTAL}" != +(${g_SQUOTESIGN}*) ]]
				then
				    Tokenize "${TOTAL}"
				fi
				TOTAL=
			    fi
			fi
			# See if we need to stop parsing
			if [[ $TO_PARSE -eq 1 && "${LINE}" = +(*END*) && "${LINE}" = +(*SUB*|*FUNCTION*) ]]
			then
			    TO_PARSE=0
			fi
			# Increase line number
			((g_COUNTER+=1))
		    done < $NEWFEED
                    # Save total amount of lines
                    ((g_TOTAL_LINES+=$g_COUNTER-1))
		    # Restore original counter
		    g_COUNTER=$COPY_COUNTER
		    # Restore original file
		    g_CURFILE=$COPY_CURFILE
		fi;;
	    "POKE")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty POKE at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    SYM=${1#* }
		    echo "if (__b2c__trap){if(__b2c__memory__check((void*)${SYM%%,*}, sizeof(__b2c__MEMTYPE))) {ERROR=1; if(!__b2c__catch_set) RUNTIMEERROR(\"POKE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
		    echo "*(__b2c__MEMTYPE *)(${SYM%%,*}) = (__b2c__MEMTYPE)(${SYM#*,});" >> $g_CFILE
                    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
                    then
                        g_CATCH_USED=1
                    fi
		fi;;
	    "RESIZE")
	    	# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty RESIZE at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    SYM=${1#* }
                    echo "if(__b2c__trap) {if(__b2c__memory__check((void*)${SYM%%,*}, sizeof(__b2c__MEMTYPE))) {ERROR=1; if(!__b2c__catch_set) RUNTIMEERROR(\"RESIZE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
                    echo "${SYM%%,*} = (long)realloc((void*)${SYM%%,*}, sizeof(__b2c__MEMTYPE)*(${SYM##*,}+1));" >> $g_CFILE
                    echo "if(__b2c__trap) {if((void*)${SYM%%,*} == NULL) {ERROR=6; if(!__b2c__catch_set) RUNTIMEERROR(\"RESIZE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
                    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
                    then
                        g_CATCH_USED=1
                    fi
		fi;;
	    "COPY")
		Handle_Copy "${1#* }";;
	    "DELETE")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty DELETE at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    # Translate to C function
		    if [[ "${1#* }" = +(*FILE*) ]]
		    then
			echo "if (unlink(${1#*FILE })==-1){if(__b2c__trap){ERROR = 7;if(!__b2c__catch_set) RUNTIMEERROR(\"DELETE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
                        if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
                        then
                            g_CATCH_USED=1
                        fi
		    elif [[ "${1#* }" = +(*DIRECTORY*) ]]
		    then
		        echo "if (rmdir(${1#*DIRECTORY }) == -1){if(__b2c__trap){ERROR = 20;if(!__b2c__catch_set) RUNTIMEERROR(\"DELETE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
                        if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
                        then
                            g_CATCH_USED=1
                        fi
		    elif [[ "${1#* }" = +(*RECURSIVE*) ]]
		    then
			 echo "__b2c__rmrecursive(${1#*RECURSIVE });" >> $g_CFILE
		    else
			echo "\nERROR: erronuous argument for DELETE at line $g_COUNTER in file '$g_CURFILE'!"
			exit 1
		    fi
		fi;;
	    "RENAME")
		Handle_Rename "${1#* }";;
	    "MAKEDIR")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty MAKEDIR at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    # Translate to C function
		    echo "if (__b2c__makedir(${1#* }) != 0){if(__b2c__trap){ERROR = 21;if(!__b2c__catch_set) RUNTIMEERROR(\"MAKEDIR\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
                    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
                    then
                        g_CATCH_USED=1
                    fi
		fi;;
	    "CHANGEDIR")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty CHANGEDIR at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    # Translate to C function
		    echo "if (chdir(${1#* }) == -1){if(__b2c__trap) {ERROR = 22;if(!__b2c__catch_set) RUNTIMEERROR(\"CHANGEDIR\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
                    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
                    then
                        g_CATCH_USED=1
                    fi
		fi;;
	    "FREE")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty FREE at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    # Translate to C function
		    if [[ "${1}" = +(*[a-zA-Z]\(*\)) ]]
		    then
                        EXP=`echo ${1#* }`
                        # Start miniparser
                        while [[ -n ${EXP} ]]
                        do
                            TOKEN=`echo $(Mini_Parser "${EXP}")`
	                    echo "__b2c__${TOKEN%%\(*}__location = __b2c__${TOKEN%%\(*}__find(${TOKEN#*\(};" >> $g_CFILE
			    if [[ ${TOKEN%%\(*} = +(*${g_STRINGSIGN}*) ]]
			    then
			        echo "if(__b2c__${TOKEN%%\(*}__location != NULL) {free(__b2c__${TOKEN%%\(*}__location->__b2c_value); __b2c__${TOKEN%%\(*}__location->__b2c_value = NULL;}" >> $g_CFILE
			    else
			        echo "if(__b2c__${TOKEN%%\(*}__location != NULL) {__b2c__${TOKEN%%\(*}__location->__b2c_value = 0;}" >> $g_CFILE
			    fi
                            echo "__b2c__${TOKEN%%\(*}__del(__b2c__${TOKEN%%\(*}__location);" >> $g_CFILE
                            EXP="${EXP:${#TOKEN}+1}"
                        done
		    else
                        IFS=","
	                for i in ${1#* }
                        do
			    echo "if(__b2c__trap){if(__b2c__memory__check((char *)${i// /}, sizeof(__b2c__MEMTYPE)))" >> $g_CFILE
			    echo "{ERROR=1; if(!__b2c__catch_set) RUNTIMEERROR(\"FREE\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} } free((void*)${i// /});" >> $g_CFILE
                        done
                        IFS="${g_ORGIFS}"
                        if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
                        then
                            g_CATCH_USED=1
                        fi
		    fi
		fi;;
	    "GOTO")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty GOTO at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    # Translate to C label
		    echo "goto ${1#* };" >> $g_CFILE
		fi;;
	    "GOSUB")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty GOSUB at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    # Translate to C label
		    echo "__b2c__gosub_buffer_ptr++; if (__b2c__gosub_buffer_ptr >= $g_MAX_RBUFFERS) {ERROR=31; if(!__b2c__catch_set) RUNTIMEERROR(\"GOSUB\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;}" >> $g_CFILE
		    echo "if(!setjmp(__b2c__gosub_buffer[__b2c__gosub_buffer_ptr])) goto ${1#* };" >> $g_CFILE
		    echo "__b2c__gosub_buffer_ptr--; if(__b2c__gosub_buffer_ptr < -1) __b2c__gosub_buffer_ptr = -1;" >> $g_CFILE
                    if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
                    then
                        g_CATCH_USED=1
                    fi
		fi;;
	    "LABEL")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty LABEL at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    # Translate to C label
		    echo "${1#* }:" >> $g_CFILE
		    echo ";" >> $g_CFILE
                    # Needed for RESTORE
                    echo "int __b2c__label_floatarray_${1#* };" >> $g_HFILE
                    echo "__b2c__label_floatarray_${1#* } = $g_FCTR;" >> $g_CFILE
                    echo "int __b2c__label_stringarray_${1#* };" >> $g_HFILE
                    echo "__b2c__label_stringarray_${1#* } = $g_CCTR;" >> $g_CFILE
                    echo "if(__b2c__data_jump_flag){ __b2c__data_jump_flag=0; longjmp(__b2c__data_jump, 1);}" >> $g_CFILE
		fi;;
	    "TRAP")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty TRAP at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    if [[ "${1#* }" = "LOCAL" ]]
		    then
			echo "/* Error catching is enabled */" >> $g_CFILE
			echo "__b2c__trap = 1;" >> $g_CFILE
			echo "signal(SIGILL, __b2c__catch_signal);" >> $g_CFILE
			echo "signal(SIGABRT, __b2c__catch_signal);" >> $g_CFILE
			echo "signal(SIGFPE, __b2c__catch_signal);" >> $g_CFILE
			echo "signal(SIGSEGV, __b2c__catch_signal);" >> $g_CFILE
		    elif [[ "${1#* }" = "SYSTEM" ]]
		    then
			echo "/* Error catching is disabled */" >> $g_CFILE
			echo "__b2c__trap = 0;" >> $g_CFILE
			echo "signal(SIGILL, SIG_DFL);" >> $g_CFILE
			echo "signal(SIGABRT, SIG_DFL);" >> $g_CFILE
			echo "signal(SIGFPE, SIG_DFL);" >> $g_CFILE
			echo "signal(SIGSEGV, SIG_DFL);" >> $g_CFILE
		    else
			echo -e "\nSyntax error: invalid argument for TRAP at line $g_COUNTER in file '$g_CURFILE'!"
			exit 1
		    fi
		fi;;
	    "CATCH")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty CATCH at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		elif [[ "${1#* }" = +(*GOTO*) ]]
		then
		    echo "__b2c__catch_set = 1;" >> $g_CFILE
		    g_CATCHGOTO="${1##* GOTO }"
		elif [[ "${1#* }" = +(*RESET*) ]]
		then
		    echo "__b2c__catch_set = 0;" >> $g_CFILE
		    g_CATCHGOTO="__B2C__PROGRAM__EXIT"
		else
		    echo -e "\nSyntax error: CATCH without GOTO or RESET at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		fi;;
	    "RESUME")
		echo "longjmp(__b2c__jump, 1);" >> $g_CFILE;;
	    "CLEAR")
		echo "fprintf(stdout,\"\033[2J\"); fprintf(stdout,\"\033[0;0f\"); fflush(stdout);" >> $g_CFILE;;
	    "COLOR")
		Handle_Color "${1#* }";;
	    "GOTOXY")
		Handle_Gotoxy "${1#* }";;
	    "RECEIVE")
		Handle_Receive "${1#* }";;
	    "SEND")
		Handle_Send "${1#* }";;
	    "RECORD")
	    	# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty RECORD at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		elif [[ -n $g_RECORDNAME ]]
		then
		    echo -e "\nSyntax error: cannot define a record within a record!"
		    exit 1
		else
		    # Translate to C typedef struct
		    if [[ -n $g_FUNCNAME ]]
		    then
			g_RECORDNAME="RECORD_${g_FUNCNAME}_${g_COUNTER}"
			echo "struct $g_RECORDNAME{" >> $g_CFILE
		    else
			g_RECORDNAME="RECORD_${g_COUNTER}"
			echo "struct $g_RECORDNAME{" >> $g_HFILE
		    fi
		    g_RECORDVAR=${1#* }
		fi;;
	    "WITH")
	    	# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty WITH at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		elif [[ -n $g_RECORDNAME ]]
		then
		    echo -e "\nSyntax error: cannot define a WITH within a WITH!"
		    exit 1
		else
		    g_WITHVAR=${1#* }
		fi;;
	    "SPLIT")
		Handle_Split "${1#* }";;
	    "JOIN")
		Handle_Join "${1#* }";;
	    "SELECT")
	    	# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty SELECT at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    ((g_SELECTVAR_CTR+=1))
		    g_SELECTVAR[$g_SELECTVAR_CTR]=${1#* }
		    g_IN_CASE[$g_SELECTVAR_CTR]=
		    g_CASE_FALL=
		fi;;
	    "CASE")
	    	# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo "\nSyntax error: empty CASE at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    if [[ -n ${g_IN_CASE[$g_SELECTVAR_CTR]} ]]
		    then
			if [[ ${g_SELECTVAR[$g_SELECTVAR_CTR]%%\(*} = +(*${g_STRINGSIGN}*) ]]
			then
			    # Get expression without ;
			    if [[ -z ${1##*;} ]]
			    then
				let LEN="${#1}"-1; EXP="${1:0:$LEN}"
				g_CASE_FALL="|| !__b2c__strcmp(${g_SELECTVAR[$g_SELECTVAR_CTR]}, ${EXP#* }) ${g_CASE_FALL}"
			    else
				echo "} else if (!__b2c__strcmp(${g_SELECTVAR[$g_SELECTVAR_CTR]}, ${1#* }) ${g_CASE_FALL}){" >> $g_CFILE
				g_CASE_FALL=
			    fi
			else
			    # Get expression without ;
			    if [[ -z ${1##*;} ]]
			    then
				let LEN="${#1}"-1; EXP="${1:0:$LEN}"
				g_CASE_FALL="|| ${g_SELECTVAR[$g_SELECTVAR_CTR]} == (${EXP#* }) ${g_CASE_FALL}"
			    else
				echo "} else if (${g_SELECTVAR[$g_SELECTVAR_CTR]} == (${1#* }) ${g_CASE_FALL}){" >> $g_CFILE
				g_CASE_FALL=
			    fi
			fi
		    else
			if [[ ${g_SELECTVAR[$g_SELECTVAR_CTR]%%\(*} = +(*${g_STRINGSIGN}*) ]]
			then
			    # Get expression without ;
			    if [[ -z ${1##*;} ]]
			    then
				let LEN="${#1}"-1; EXP="${1:0:$LEN}"
				g_CASE_FALL="|| !__b2c__strcmp(${g_SELECTVAR[$g_SELECTVAR_CTR]}, ${EXP#* }) ${g_CASE_FALL}"
			    else
				echo "if (!__b2c__strcmp(${g_SELECTVAR[$g_SELECTVAR_CTR]}, ${1#* }) ${g_CASE_FALL}){" >> $g_CFILE
				g_IN_CASE[$g_SELECTVAR_CTR]=1
				g_CASE_FALL=
			    fi
			else
			    # Get expression without ;
			    if [[ -z ${1##*;} ]]
			    then
				let LEN="${#1}"-1; EXP="${1:0:$LEN}"
				g_CASE_FALL="|| ${g_SELECTVAR[$g_SELECTVAR_CTR]} == (${EXP#* }) ${g_CASE_FALL}"
			    else
				echo "if (${g_SELECTVAR[$g_SELECTVAR_CTR]} == (${1#* }) ${g_CASE_FALL}){" >> $g_CFILE
				g_IN_CASE[$g_SELECTVAR_CTR]=1
				g_CASE_FALL=
			    fi
			fi
		    fi
		fi;;
	    "DEFAULT")
		if [[ -n ${g_IN_CASE[$g_SELECTVAR_CTR]} ]]
		then
		    echo "} else {" >> $g_CFILE
		else
		    echo -e "\nSyntax error: cannot use DEFAULT without previous CASE at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		fi
		g_IN_CASE[$g_SELECTVAR_CTR]=
		g_CASE_FALL=;;
	    "SETENVIRON")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty SETENVIRON at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    # Resolve this with C macro
		    echo "SETENVIRON(${1#* });" >> $g_CFILE
		fi;;
	    "SORT")
		Handle_Sort "${1#* }";;
	    "STOP")
		echo "kill(getpid(), SIGSTOP);" >> $g_CFILE
		;;
	    "TRACE")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty TRACE at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    if [[ "${1#* }" = +(*MONITOR*) ]]
                    then
			g_TRACE=1
	                echo "fprintf(stderr, \"File '${g_CURFILE}' line %d: TRACE ON - press <SPACE> to execute the program step by step, <ESC> to exit.\n\", $g_COUNTER);" >> $g_CFILE
                        g_MONITOR=
                        for SYM in `echo "${1#*MONITOR }" | tr -d '\054'`
                        do
                            CHECK=$(Get_Var ${SYM} ${g_FUNCNAME})
                            if [[ -z $CHECK ]]
                            then
		                echo -e "\nSyntax error: cannot monitor undeclared variable '${SYM}' at line $g_COUNTER in file '$g_CURFILE'!"
		                exit 1
                            fi
                            if [[ "${SYM%%\(*}" = +(*${g_STRINGSIGN}*) || ${CHECK} = "char*" ]]
                            then
	                        g_MONITOR="${g_MONITOR} __b2c__assign = ${SYM}; if(__b2c__assign != NULL) fprintf(stderr, \"${SYM%%${g_STRINGSIGN}*}$ = %s\n\", __b2c__assign);"
                            else
                                if [[ "${SYM}" = +(*${g_LONGSIGN}*) ]]
                                then
	                            g_MONITOR="${g_MONITOR} fprintf(stderr, \"${SYM%%${g_LONGSIGN}*}%% = %s\n\", STR${g_STRINGSIGN}(${SYM}));"
                                elif [[ "${SYM}" = +(*${g_FLOATSIGN}*) ]]
                                then
	                            g_MONITOR="${g_MONITOR} fprintf(stderr, \"${SYM%%${g_FLOATSIGN}*}# = %s\n\", STR${g_STRINGSIGN}(${SYM}));"
                                else
	                            g_MONITOR="${g_MONITOR} fprintf(stderr, \"${SYM} = %s\n\", STR${g_STRINGSIGN}(${SYM}));"
                                fi
                            fi
                        done
		    elif [[ "${1#* }" = +(*ON*) ]]
		    then
			g_TRACE=1
	                echo "fprintf(stderr, \"File '${g_CURFILE}' line %d: TRACE ON - press <SPACE> to execute the program step by step, <ESC> to exit.\n\", $g_COUNTER);" >> $g_CFILE
		    elif [[ "${1#* }" = +(*OFF*) ]]
		    then
                        g_MONITOR=
			g_TRACE=0
		    fi
		fi;;
	    "OPTION")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty OPTION at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    if [[ "${1#* }" = +(*BASE*) ]]
		    then
			if [[ "${1##*BASE }" = +([0123456789]) ]]
			then
			    g_OPTION_BASE=${1##*BASE }
			else
			    echo -e "\nSyntax error: invalid argument to OPTION BASE at line $g_COUNTER in file '$g_CURFILE'!"
			    exit 1
			fi
		    elif [[ "${1#* }" = +(*COMPARE*) ]]
		    then
			if [[ "${1##*COMPARE }" = +([01]|TRUE|FALSE) ]]
			then
			    echo "__b2c__option_compare = ${1##*COMPARE };" >> $g_CFILE
			else
			    echo -e "\nSyntax error: invalid argument to OPTION COMPARE at line $g_COUNTER in file '$g_CURFILE'!"
			    exit 1
			fi
		    elif [[ "${1#* }" = +(*SOCKET*) ]]
		    then
			if [[ "${1##*SOCKET }" = +([0123456789]) ]]
			then
			    g_OPTION_SOCKET=${1##*SOCKET }
			else
			    echo -e "\nSyntax error: invalid argument to OPTION SOCKET at line $g_COUNTER in file '$g_CURFILE'!"
			    exit 1
			fi
                    elif [[ "${1#* }" = +(*MEMSTREAM*) ]]
		    then
			if [[ "${1##*MEMSTREAM }" = +([01]|TRUE|FALSE) ]]
			then
			    echo "__b2c__option_memstream = ${1##*MEMSTREAM };" >> $g_CFILE
			else
			    echo -e "\nSyntax error: invalid argument to OPTION MEMSTREAM at line $g_COUNTER in file '$g_CURFILE'!"
			    exit 1
			fi
                    elif [[ "${1#* }" = +(*MEMTYPE*) ]]
		    then
                        echo "#undef __b2c__MEMTYPE" >> $g_CFILE
                        echo "#define __b2c__MEMTYPE ${1##*MEMTYPE }" >> $g_CFILE
                    elif [[ "${1#* }" = +(*COLLAPSE*) ]]
		    then
			if [[ "${1##*COLLAPSE }" = +([01]|TRUE|FALSE) ]]
			then
			    echo "__b2c__collapse = ${1##*COLLAPSE };" >> $g_CFILE
			else
			    echo -e "\nSyntax error: invalid argument to OPTION COLLAPSE at line $g_COUNTER in file '$g_CURFILE'!"
			    exit 1
			fi
                    elif [[ "${1#* }" = +(*DEVICE*) ]]
		    then
			echo "__b2c__option_open = (${1##*DEVICE });" >> $g_CFILE
                    elif [[ "${1#* }" = +(*STARTPOINT*) ]]
		    then
			if [[ "${1##*STARTPOINT }" = +([01]|TRUE|FALSE) ]]
			then
			    echo "__b2c__option_startpoint = ${1##*STARTPOINT };" >> $g_CFILE
			else
			    echo -e "\nSyntax error: invalid argument to OPTION STARTPOINT at line $g_COUNTER in file '$g_CURFILE'!"
			    exit 1
			fi
                    elif [[ "${1#* }" = +(*INTERNATIONAL*) ]]
		    then
			if [[ "${1##*INTERNATIONAL }" = +(1|TRUE) ]]
			then
			    echo "#include <libintl.h>" >> $g_HFILE
			    echo "#include <locale.h>" >> $g_HFILE
			    echo "setlocale(LC_ALL, \"\");" >> $g_CFILE
			    echo "if(bindtextdomain(\"${g_SOURCEFILE%.*}\",\"/usr/share/locale\")==NULL){if(__b2c__trap){ERROR = 6;if(!__b2c__catch_set) RUNTIMEERROR(\"OPTION INTERNATIONAL\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
			    echo "if(textdomain(\"${g_SOURCEFILE%.*}\")==NULL){if(__b2c__trap){ERROR = 6; if(!__b2c__catch_set) RUNTIMEERROR(\"OPTION INTERNATIONAL\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
                            if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
                            then
                                g_CATCH_USED=1
                            fi
			else
			    echo -e "\nSyntax error: invalid argument to OPTION INTERNATIONAL at line $g_COUNTER in file '$g_CURFILE'!"
			    exit 1
			fi
                    elif [[ "${1#* }" = +(*NETWORK*) ]]
		    then
                        case "${1##*NETWORK }" in
                            *TCP*)
                                g_NETWORKTYPE="TCP"
                                g_SOCKTYPE="SOCK_STREAM"
                                ;;
                            *UDP*)
                                g_NETWORKTYPE="UDP"
                                g_SOCKTYPE="SOCK_DGRAM"
                                ;;
                            *BROADCAST*)
                                g_NETWORKTYPE="BROADCAST"
                                g_SOCKTYPE="SOCK_DGRAM"
                                ;;
                            *MULTICAST*)
                                g_NETWORKTYPE="MULTICAST"
                                g_SOCKTYPE="SOCK_DGRAM"
				if [[ "${1##*MULTICAST }" = +([0123456789]) ]]
				then
				    g_MULTICAST_TTL="${1##*MULTICAST }"
				fi
                                ;;
                            *SCTP*)
			        echo "#include <netinet/sctp.h>" >> $g_HFILE
			        echo "struct sctp_initmsg __b2c__initmsg;" >> $g_HFILE
                                g_NETWORKTYPE="SCTP"
                                g_SOCKTYPE="SOCK_STREAM"
                                g_LDFLAGS="${g_LDFLAGS} -lsctp"
				if [[ "${1##*SCTP }" = +([0123456789]) ]]
				then
				    g_SCTP_STREAMS="${1##*SCTP }"
				fi
                                ;;
                            *)
			        echo -n "\nSyntax error: invalid argument to OPTION SOCKET at line $g_COUNTER in file '$g_CURFILE'!"
			        exit 1
                                ;;
			esac
                    elif [[ "${1#* }" = +(*PARSE*) ]]
		    then
			if [[ "${1##*PARSE }" = +([01]|TRUE|FALSE) ]]
			then
                            g_IGNORE_PARSE="${1##*PARSE }"
			else
			    echo -e "\nSyntax error: invalid argument to OPTION PARSE at line $g_COUNTER in file '$g_CURFILE'!"
			    exit 1
                        fi
                    elif [[ "${1#* }" = +(*VARTYPE*) ]]
		    then
                        g_VARTYPE="${1##*VARTYPE }"
		    else
			echo -e "\nSyntax error: argument to OPTION at line $g_COUNTER in file '$g_CURFILE' not recognized!"
			exit 1
		    fi
		fi;;
	    "PROTO")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty PROTO at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    SYM=`echo ${1#* } | tr -d "\042"`
		    # Check if ALIAS is there
		    if [[ $SYM = +(* ALIAS *) ]]
		    then
			echo "#define ${SYM##* ALIAS } ${SYM%% ALIAS *}" >> $g_HFILE
			g_IMPORTED="${SYM##* ALIAS } $g_IMPORTED"
			g_IMPORTED="${SYM%% ALIAS *} $g_IMPORTED"
		    elif [[ $SYM = +(* TYPE *) ]]
		    then
			echo "${SYM##* TYPE } ${SYM%% TYPE *};" >> $g_HFILE
		    else
			g_IMPORTED="${SYM//,/ } $g_IMPORTED"
		    fi
		fi;;
	    "INCR")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty INCR at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
                    # Get left side
                    TOKEN=$(Mini_Parser "${1}")
                    # Get right side
                    EXP="${1:${#TOKEN}+1}"
                    if [[ ${#EXP} -eq 0 ]]
                    then
                        EXP="1"
                    fi
                    TOKEN=${TOKEN#* }
		    # Check if there is associative array assignment
		    if [[ "${TOKEN}" = +(*[a-zA-Z]\(*\)) ]]
		    then
			INC=${TOKEN#*\(}
			echo "__b2c__${TOKEN%%\(*}__location = __b2c__${TOKEN%%\(*}__add(${INC};" >> $g_CFILE
			echo "__b2c__${TOKEN%%\(*}__location->__b2c_value = ${TOKEN} + (${EXP});" >> $g_CFILE
			# Check for relations
			Relate_Recurse "${TOKEN%%\(*}" "${INC}" "${TOKEN}+(${EXP})" "-1"
		    else
                        # Regular number
                        if [[ ${EXP} = +(*[0-9]*.*[0-9]*) && -z $(Get_Var ${TOKEN} ${g_FUNCNAME}) ]] 
                        then
	                    echo "double $TOKEN;" >> $g_HFILE
                            Save_Main_Var "${TOKEN}" "double"
                        elif [[ -z $(Get_Var ${TOKEN} ${g_FUNCNAME}) ]]
	                then
                            Register_Numeric ${TOKEN}
	                fi
			echo "${TOKEN} = ${TOKEN} + (${EXP});" >> $g_CFILE
		    fi
		fi;;
	    "DECR")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty DECR at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
                    # Get left side
                    TOKEN=$(Mini_Parser "${1}")
                    # Get right side
                    EXP="${1:${#TOKEN}+1}"
                    if [[ ${#EXP} -eq 0 ]]
                    then
                        EXP="1"
                    fi
                    TOKEN=${TOKEN#* }
		    # Check if there is associative array assignment
		    if [[ "${TOKEN}" = +(*[a-zA-Z]\(*\)) ]]
		    then
			INC=${TOKEN#*\(}
			echo "__b2c__${TOKEN%%\(*}__location = __b2c__${TOKEN%%\(*}__add(${INC};" >> $g_CFILE
			echo "__b2c__${TOKEN%%\(*}__location->__b2c_value = ${TOKEN} - (${EXP});" >> $g_CFILE
			# Check for relations
			Relate_Recurse "${TOKEN%%\(*}" "${INC}" "${TOKEN}+(${EXP})" "-1"
		    else
                        # Regular number
                        if [[ ${EXP} = +(*[0-9]*.*[0-9]*) && -z $(Get_Var ${TOKEN} ${g_FUNCNAME}) ]] 
                        then
	                    echo "double $TOKEN;" >> $g_HFILE
                            Save_Main_Var "${TOKEN}" "double"
                        elif [[ -z $(Get_Var ${TOKEN} ${g_FUNCNAME}) ]]
	                then
                            Register_Numeric ${TOKEN}
	                fi
			echo "${TOKEN} = ${TOKEN} - (${EXP});" >> $g_CFILE
		    fi
		fi;;
	    "ALARM")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty ALARM at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    EXP=${1#* }
		    if [[ ${EXP} = +(*,*) ]]
		    then
			echo "signal(SIGALRM, (void*)${EXP%,*});" >> $g_CFILE
                        echo "__b2c__alarm.it_value.tv_sec = (long)(${EXP#*,})/1000; __b2c__alarm.it_value.tv_usec = ((${EXP#*,})%1000)*1000;" >> $g_CFILE
                        echo "__b2c__alarm.it_interval.tv_sec = 0; __b2c__alarm.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &__b2c__alarm, NULL);" >> $g_CFILE
		    else
			echo -e "\nSyntax error: missing argument in ALARM at line $g_COUNTER in file '$g_CURFILE'!"
			exit 1
		    fi
		fi;;
	    "CURSOR")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty CURSOR at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
                    EXP=1
		    if [[ "${1#* }" = +(*OFF*) ]]
		    then
			echo "fprintf(stdout,\"\033[?25l\"); fflush(stdout);" >> $g_CFILE
		    elif [[ "${1#* }" = +(*ON*) ]]
		    then
			echo "fprintf(stdout,\"\033[?25h\"); fflush(stdout);" >> $g_CFILE
            	    elif [[ "${1#* }" = +(*UP*) ]]
		    then
                        if [[ ${1##*UP } != +(*UP*) ]]
                        then
                            EXP=${1##*UP }
                        fi
			echo "fprintf(stdout,\"\033[%ldA\", (long)${EXP}); fflush(stdout);" >> $g_CFILE
		    elif [[ "${1#* }" = +(*DOWN*) ]]
		    then
                        if [[ ${1##*DOWN } != +(*DOWN*) ]]
                        then
                            EXP=${1##*DOWN }
                        fi
			echo "fprintf(stdout,\"\033[%ldB\", (long)${EXP}); fflush(stdout);" >> $g_CFILE
		    elif [[ "${1#* }" = +(*FORWARD*) ]]
		    then
                        if [[ ${1##*FORWARD } != +(*FORWARD*) ]]
                        then
                            EXP=${1##*FORWARD }
                        fi
			echo "fprintf(stdout,\"\033[%ldC\", (long)${EXP}); fflush(stdout);" >> $g_CFILE
		    elif [[ "${1#* }" = +(*BACK*) ]]
		    then
                        if [[ ${1##*BACK } != +(*BACK*) ]]
                        then
                            EXP=${1##*BACK }
                        fi
			echo "fprintf(stdout,\"\033[%ldD\", (long)${EXP}); fflush(stdout);" >> $g_CFILE
		    fi
		fi;;
            "SCROLL")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty SCROLL at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
                    EXP=1
		    if [[ "${1#* }" = +(*UP*) ]]
		    then
                        if [[ ${1##*UP } != +(*UP*) ]]
                        then
                            EXP=${1##*UP }
                        fi
			echo "fprintf(stdout,\"\033[%ldS\", (long)${EXP}); fflush(stdout);" >> $g_CFILE
		    elif [[ "${1#* }" = +(*DOWN*) ]]
		    then
                        if [[ ${1##*DOWN } != +(*DOWN*) ]]
                        then
                            EXP=${1##*DOWN }
                        fi
			echo "fprintf(stdout,\"\033[%ldT\", (long)${EXP}); fflush(stdout);" >> $g_CFILE
		    fi
		fi;;
	    "ALIAS")
		Handle_Alias "${1#* }";;
	    "LOOKUP")
		Handle_Lookup "${1#* }";;
	    "RELATE")
		Handle_Relate "${1#* }";;
	    "TEXTDOMAIN")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty TEXTDOMAIN at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    EXP=${1#* }
		    if [[ ${EXP} = +(*,*) ]]
		    then
			echo "if(bindtextdomain(${EXP})==NULL){if(__b2c__trap){ERROR = 6;if(!__b2c__catch_set) RUNTIMEERROR(\"TEXTDOMAIN\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
			echo "if(textdomain(${EXP%,*})==NULL){if(__b2c__trap){ERROR = 6; if(!__b2c__catch_set) RUNTIMEERROR(\"TEXTDOMAIN\", $g_COUNTER, \"$g_CURFILE\", ERROR); if(!setjmp(__b2c__jump)) goto $g_CATCHGOTO;} }" >> $g_CFILE
                        if [[ ${g_CATCHGOTO} = "__B2C__PROGRAM__EXIT" ]]
                        then
                            g_CATCH_USED=1
                        fi
		    else
			echo -e "\nSyntax error: missing argument in TEXTDOMAIN at line $g_COUNTER in file '$g_CURFILE'!"
			exit 1
		    fi
		fi;;
	    "REDIM")
		Handle_Redim "${1#* }";;
            "EXIT")
                if [[ -z $g_FUNCNAME ]]
                then
		    echo -e "\nSyntax error: EXIT not in FUNCTION or SUB at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
                fi
		# Free strings variables if there are any
		echo "${g_STRINGARRAYS}" >> $g_CFILE
		for EXP in $g_LOCALSTRINGS
		do
		    echo "if($EXP != NULL) free($EXP);" >> $g_CFILE
		done
                echo "__b2c__catch_set = __b2c__catch_set_backup;" >> $g_CFILE
		# The actual exit
                if [[ "${g_FUNCNAME}" = +(*${g_STRINGSIGN}*) ]]
                then
                    echo "return(NULL);" >> $g_CFILE
                else
                    echo "return;" >> $g_CFILE
                fi;;
	    "PRAGMA")
		# Check argument
		if [[ "${1%% *}" = "${1#* }" ]]
		then
		    echo -e "\nSyntax error: empty PRAGMA at line $g_COUNTER in file '$g_CURFILE'!"
		    exit 1
		else
		    if [[ "${1#* }" = +(*OPTIONS*) ]]
		    then
                        g_CCFLAGS="$g_CCFLAGS ${1##*OPTIONS }"
		    elif [[ "${1#* }" = +(*COMPILER*) ]]
		    then
                        g_CCNAME="${1##*COMPILER }"
	            elif [[ "${1#* }" = +(*FRAMEWORK*) ]] 
                    then
			g_LDFLAGS="$g_LDFLAGS -framework ${1##*FRAMEWORK }"
		    elif [[ "${1#* }" = +(*LDFLAGS*) ]]
		    then
                        if [[ ${1##*LDFLAGS } = +(*config*) ]]
                        then
                            EXP=`echo ${1##*LDFLAGS } |tr -d "\140"`
                            g_LDFLAGS="$g_LDFLAGS `eval ${EXP}`"
                        else
                            for EXP in ${1##*LDFLAGS }
                            do
                                if [[ $EXP = +(-*) ]]
                                then
                                    g_LDFLAGS="$g_LDFLAGS ${EXP}"
                                else
                                    g_LDFLAGS="$g_LDFLAGS -l${EXP}"
                                fi
                            done
                        fi
		    elif [[ "${1#* }" = +(*INCLUDE*) ]]
		    then
                        for EXP in ${1##*INCLUDE }
                        do
                            if [[ ${EXP:0:1} = "<" ]]
                            then
                                echo "#include ${EXP}" >> $g_HFILE
                            elif [[ ${EXP:0:1} = "/" ]]
                            then
                                echo "#include \"${EXP}\"" >> $g_HFILE
                            else
                                echo "#include \"`pwd`/${EXP}\"" >> $g_HFILE
                            fi
                        done
		    elif [[ "${1#* }" = +(*BACONLIB*) ]]
		    then
                        g_REBUILD_ARCHIVE="libbacon.a"
	                g_CCFLAGS="$g_CCFLAGS -fPIC"
		    else
			echo -e "\nSyntax error: argument to PRAGMA at line $g_COUNTER in file '$g_CURFILE' not recognized!"
			exit 1
		    fi
		fi;;
	    "SWAP")
		Handle_Swap "${1#* }";;
	    "SETSERIAL")
		Handle_Setserial "${1#* }";;
	    "ENUM")
                echo "enum {" >> $g_CFILE
		let g_USE_C=1;;
	    *)
		# Check on imported symbols first
		FOUND=0
		for SYM in $g_IMPORTED
		do
		    if [[ "$SYM" = "${1%%\(*}" || "$SYM" = "${1%% *}" ]]
		    then
			FOUND=1
			if [[ "$1" != +(*\(*\)*) ]]
			then
			    echo "$SYM();" >> $g_CFILE
			else
			    echo "$SYM(${1#*\(};" >> $g_CFILE
			fi
                        break
		    fi
		done
		# Not an imported symbol? Check if assignment
		if [[ $FOUND -eq 0 ]]
		then
		    Handle_Let "$1"
		fi;;
	esac
    fi
}

#-----------------------------------------------------------

function Pre_Tokenize_Functions
{
    typeset DATA IS_ESCAPED IS_STRING TOKEN CHAR ARG
    typeset -i LEN

    # Initialize miniparser, convert spaces
    DATA="${1// /${g_PARSEVAR}}"

    # Check if one of these conversion time functions are there
    if [[ ${DATA} = +(*TYPEOF\$*) || ${DATA} = +(*INTL\$*) || ${DATA} = +(*NNTL\$*) || ${DATA} = +(*IIF\(*) || ${DATA} = +(*IIF\$\(*) ]]
    then

        IS_ESCAPED=0
        IS_STRING=0
        TOKEN=
        LEN=${#DATA}

        until [[ $LEN -eq 0 ]]
        do
            CHAR="${DATA:0:7}"
	    if [[ "${CHAR}" = "TYPEOF$" ]]
            then
	        if [[ $IS_STRING -eq 0 ]]
	        then
                    ARG=${DATA%%\)*}
                    let LEN=${#DATA}-${#ARG}-1
		    TOKEN="${TOKEN}\"$(Get_Var ${ARG##*\(} ${g_FUNCNAME})\""
                    if [[ ${LEN} -eq 0 ]]
                    then
                        break
                    fi
	            DATA="${DATA: -$LEN}"
                fi
            fi
            CHAR="${DATA:0:5}"
	    if [[ "${CHAR}" = "INTL$" ]]
            then
	        if [[ $IS_STRING -eq 0 ]]
	        then
                    let LEN=${#DATA}-5
	            DATA="${DATA: -$LEN}"
		    TOKEN="${TOKEN}gettext"
                fi
	    elif [[ "${CHAR}" = "NNTL$" ]]
            then
	        if [[ $IS_STRING -eq 0 ]]
	        then
                    let LEN=${#DATA}-5
	            DATA="${DATA: -$LEN}"
		    TOKEN="${TOKEN}ngettext"
                fi
            elif [[ "${CHAR}" = "IIF\$(" ]]
            then
	        if [[ $IS_STRING -eq 0 ]]
	        then
                    ARG=${DATA#*\(}
                    INTOKEN=$(Mini_Parser "${ARG}")
                    Parse_Equation "${INTOKEN}"
		    TOKEN="${TOKEN}IIF\$(${g_EQUATION}"
                    let LEN=${#DATA}-${#INTOKEN}-5
	            DATA="${DATA: -$LEN}"
                fi
            fi
            CHAR="${DATA:0:4}"
	    if [[ "${CHAR}" = "IIF(" ]]
            then
	        if [[ $IS_STRING -eq 0 ]]
	        then
                    ARG=${DATA#*\(}
                    INTOKEN=$(Mini_Parser "${ARG}")
                    Parse_Equation "${INTOKEN}"
		    TOKEN="${TOKEN}IIF(${g_EQUATION}"
                    let LEN=${#DATA}-${#INTOKEN}-4
	            DATA="${DATA: -$LEN}"
                fi
            fi
	    CHAR="${DATA:0:1}"
	    case $CHAR in
	        \\)
		    if [[ $IS_ESCAPED -eq 0 ]]
		    then
		        IS_ESCAPED=1
		    else
		        IS_ESCAPED=0
		    fi;;
	        \")
		    if [[ $IS_ESCAPED -eq 0 ]]
		    then
		        if [[ $IS_STRING -eq 0 ]]
		        then
			    IS_STRING=1
		        else
			    IS_STRING=0
		        fi
		    fi
		    IS_ESCAPED=0;;
            esac
	    TOKEN="${TOKEN}${CHAR}"
	    let LEN=${#DATA}-1
	    DATA="${DATA: -$LEN}"
        done
        echo "${TOKEN}"
    else
        echo "${DATA}"
    fi
}

#-----------------------------------------------------------

function Tokenize
{
    typeset CHAR IS_STATEMENT TOKEN DATA LEN LINE INLEN INCHAR INTOKEN ITEM1 ITEM2 RESULT ARG
    typeset -i DIRECT INSPAC BRACKET ISQUOTE IS_STRING INSTR IS_ESCAPED INESCAPED SFUNC SFTOT IN_FUNC

    # In TRACE MODE show linenr and code
    if [[ $g_TRACE -eq 1 ]]
    then
        if [[ ${1} != +(FUNCTION*) && ${1} != +(SUB*) && ${1} != +(ELIF*) && ${1} != +(ELSE*) ]]
        then
	    echo "if(__b2c__getch() == 27) {fprintf(stderr, \"TRACE OFF - exiting trace mode.\n\"); exit(EXIT_SUCCESS);}" >> $g_CFILE
	    LINE=`echo "${1}" | tr "\042" "\047"`
	    LINE="${LINE//\\/\\\\}"
	    echo "fprintf(stderr, \"File '${g_CURFILE}' line %d: ${g_TRACE_PREFIX}${LINE//%/%%}\n\", $g_COUNTER);" >> $g_CFILE
            if [[ -n $g_MONITOR ]]
            then
                echo ${g_MONITOR} >> $g_CFILE
            fi
            g_TRACE_PREFIX=
        fi
    fi

    # Initialize miniparser, convert spaces
    DATA=$(Pre_Tokenize_Functions "${1}")

    SFTOT=0
    SFUNC=0
    IN_FUNC=0

    while true
    do
        IS_ESCAPED=0
        IS_STRING=0
        IS_STATEMENT=""
        TOKEN=
        LEN=${#DATA}

        until [[ $LEN -eq 0 ]]
        do
	    CHAR="${DATA:0:1}"
	    case $CHAR in
	        :)
		    if [[ $IS_STRING -eq 0 && $g_USE_C -eq 0 && $g_USE_H -eq 0 && $IN_FUNC -eq 0 ]]
		    then
                        # If we are in a string function increase line counter
                        if [[ ${g_FUNCNAME} = +(*${g_STRINGSIGN}*) && $SFTOT -gt 0 ]]
                        then
                            ((g_STRING_LINE+=1))
                        fi
                        # Determine amount of string funcs
                        if [[ $SFTOT -gt $g_STRING_FUNC ]]
                        then
                            g_STRING_FUNC=$SFTOT
                        fi
		        Parse_Line "${TOKEN}"
		        CHAR=
		        TOKEN=
		        IS_STATEMENT=""
                        SFUNC=0
                        SFTOT=0
		    fi;;
	        ${g_TAB})
		    if [[ $IS_STRING -eq 0 ]]
		    then
		        TOKEN="${TOKEN} "
                    else
		        TOKEN="${TOKEN}${g_TAB}"
                    fi
		    CHAR=
		    IS_ESCAPED=0
		    ;;
	        $)
		    if [[ $IS_STRING -eq 0 || ${1} = +(*IMPORT*FROM*TYPE*) ]]
		    then
		        TOKEN="${TOKEN}${g_STRINGSIGN}"
		        CHAR=
		        IS_ESCAPED=0
                        let SFUNC=1
		    fi;;
                \()
                    if [[ ${IS_STRING} -eq 0 && $g_USE_C -eq 0 && $g_USE_H -eq 0 ]]
                    then
                        ((IN_FUNC+=1))
                        if [[ ${SFUNC} -gt 0 ]]
                        then
                            let SFUNC=0
                            ((SFTOT+=1))
                        fi
                    fi;;
                \))
                    if [[ ${IS_STRING} -eq 0 && $g_USE_C -eq 0 && $g_USE_H -eq 0 ]]
                    then
                        ((IN_FUNC-=1))
                    fi;;
                \?)
                    if [[ ${IS_STRING} -eq 0 && $g_USE_C -eq 0 && $g_USE_H -eq 0 && $IN_FUNC -eq 0 ]]
                    then
                        CHAR="PRINT "
                    fi;;
                \[)
                    if [[ ${IS_STRING} -eq 0 && "${DATA:0:2}" != "[]" && "${DATA:0:7}" != "[(long)" ]]
                    then
                        CHAR="[(long)"
                    fi;;
	        %)
		    if [[ $IS_STRING -eq 0 && ${TOKEN: -1} != " " ]]
		    then
		        TOKEN="${TOKEN}${g_LONGSIGN}"
		        CHAR=
		        IS_ESCAPED=0
		    fi;;
	        \#)
		    if [[ $IS_STRING -eq 0 && ${TOKEN: -1} != " " && ${#TOKEN} -gt 0 ]]
		    then
		        TOKEN="${TOKEN}${g_FLOATSIGN}"
		        CHAR=
		        IS_ESCAPED=0
		    fi;;
	        \\)
		    if [[ $IS_ESCAPED -eq 0 ]]
		    then
		        IS_ESCAPED=1
		    else
		        IS_ESCAPED=0
		    fi;;
	        \")
		    if [[ $IS_ESCAPED -eq 0 ]]
		    then
		        if [[ $IS_STRING -eq 0 ]]
		        then
			    IS_STRING=1
		        else
			    IS_STRING=0
		        fi
		    fi
		    IS_ESCAPED=0;;
                \&)
		    if [[ $IS_STRING -eq 0 && $g_USE_C -eq 0 && $g_USE_H -eq 0 ]]
		    then
                        # ITEMIZER1: Get item on the left side
                        INTOKEN=$(echo ${TOKEN// /${g_PARSEVAR}})
                        INLEN=${#INTOKEN}
                        ITEM1=""
                        BRACKET=0
                        INSPAC=0
                        INSTR=0
                        DIRECT=0
                        ISQUOTE=0
                        until [[ $INLEN -eq 0 ]]
                        do
                            INCHAR="${INTOKEN: -1}"
                            case ${INCHAR} in
                                \)|\])
                                    ISQUOTE=0
                                    DIRECT=1
                                    if [[ ${INSTR} -eq 0 ]]
                                    then
                                        ((BRACKET+=1))
                                    fi;;
                                \(|\[)
                                    ISQUOTE=0
                                    DIRECT=1
                                    if [[ ${INSTR} -eq 0 ]]
                                    then
                                        ((BRACKET-=1))
                                        if [[ ${BRACKET} -lt 0 ]]
                                        then
                                            break
                                        fi
                                    fi;;
                                =)
                                    ISQUOTE=0
                                    if [[ ${INSTR} -eq 0 ]]
                                    then
                                        break
                                    fi;;
                                ,)
                                    ISQUOTE=0
                                    if [[ ${INSTR} -eq 0 && ${BRACKET} -eq 0 ]]
                                    then
                                        break
                                    fi;;
                    	        \\)
		                    if [[ $ISQUOTE -eq 1 ]]
		                    then
		                        INSTR=1
		                    fi
                                    ISQUOTE=0;;
	                        \")
                                    ISQUOTE=1
                                    DIRECT=1
		                    if [[ $INSTR -eq 0 ]]
		                    then
			                INSTR=1
		                    else
			                INSTR=0
		                    fi;;
                                [A-Za-z])
                                    ISQUOTE=0
                                    DIRECT=1
                                    if [[ ${INSTR} -eq 0 && ${BRACKET} -eq 0 ]]
                                    then
                                        if [[ $INSPAC -gt 0 ]]
                                        then
                                            break
                                        fi
                                    fi;;
                                ${g_PARSEVAR})
                                    ISQUOTE=0
                                    if [[ ${INSTR} -eq 0 && ${BRACKET} -eq 0 ]]
                                    then
                                        if [[ ${DIRECT} -gt 0 ]]
                                        then
                                            INSPAC=1
                                        fi
                                    fi;;
                                :)
                                    if [[ ${BRACKET} -eq 0 ]]
                                    then
                                        ISQUOTE=0
                                        if [[ ${INSTR} -eq 0 ]]
                                        then
                                            break
                                        fi
                                    fi;;
                            esac
	                    if [[ "${INCHAR}" = "${g_PARSEVAR}" ]]
	                    then
	                        ITEM1=" ${ITEM1}"
                            else
	                        ITEM1="${INCHAR}${ITEM1}"
                            fi
                            let INLEN=${#INTOKEN}-1
                            INTOKEN="${INTOKEN:0:$INLEN}"
                        done
                        # If ITEM is a string element continue
                        if [[ ${ITEM1%%\(*} = +(*${g_STRINGSIGN}*) || "${ITEM1%%\(*}" = +(*${g_DQUOTESIGN}*) || $(echo ${ITEM1}) = +(*${g_STRINGSIGN}) ]]
                        then
		            CHAR=""
                            TOKEN=$(echo ${INTOKEN// /${g_PARSEVAR}})
                            # ITEMIZER2: Get item on the right side
                            ((LEN-=1))
                            INTOKEN="${DATA: -$LEN}"
                            INLEN=${#INTOKEN}
                            ITEM2=""
                            BRACKET=0
                            INSTR=0
                            INESCAPED=0
			    INSPAC=0
			    DIRECT=0
                            SFUNC=0
                            until [[ $INLEN -eq 0 ]]
                            do
                                INCHAR="${INTOKEN:0:1}"
                                case $INCHAR in
                                    \()
					DIRECT=1
                                        if [[ ${INSTR} -eq 0 ]]
                                        then
                                            ((BRACKET+=1))
                                        fi
                                        if [[ ${SFUNC} -gt 0 ]]
                                        then
                                            let SFUNC=0
                                            ((SFTOT+=1))
                                        fi;;
                                    \))
					DIRECT=1
                                        if [[ ${INSTR} -eq 0 ]]
                                        then
                                            ((BRACKET-=1))
                                            if [[ ${BRACKET} -lt 0 ]]
                                            then
                                                break
                                            fi
                                        fi;;
                                    ,)
                                        if [[ ${INSTR} -eq 0 && ${BRACKET} -eq 0 ]]
                                        then
                                            break
                                        fi;;
                                    \&)
                                        if [[ ${INSTR} -eq 0 && ${BRACKET} -eq 0 ]]
                                        then
			                    INSPAC=0
			                    DIRECT=0
                                            INCHAR=","
                                        fi;;
            	                    \\)
		                        if [[ $INESCAPED -eq 0 ]]
		                        then
		                            INESCAPED=1
		                        else
		                            INESCAPED=0
		                        fi;;
	                            \")
					DIRECT=1
		                        if [[ $INESCAPED -eq 0 ]]
		                        then
		                            if [[ $INSTR -eq 0 ]]
		                            then
			                        INSTR=1
		                            else
			                        INSTR=0
		                            fi
                                        fi
                                        INESCAPED=0;;
				    [A-Za-z])
					DIRECT=1
					if [[ ${INSTR} -eq 0 && ${BRACKET} -eq 0 ]]
					then
					    if [[ $INSPAC -gt 0 ]]
					    then
						break
					    fi
					fi;;
				    ${g_PARSEVAR})
					if [[ ${INSTR} -eq 0 && ${BRACKET} -eq 0 ]]
					then
					    if [[ ${DIRECT} -gt 0 ]]
					    then
						INSPAC=1
					    fi
					fi;;
                                    :|\;)
                                        if [[ ${INSTR} -eq 0 && ${BRACKET} -eq 0 ]]
                                        then
                                            break
                                        fi;;
                                esac
	                        if [[ "${INCHAR}" = "${g_PARSEVAR}" ]]
	                        then
	                            ITEM2="${ITEM2} "
                                elif [[ "${INCHAR}" = "$" ]]
                                then
		                    if [[ $INSTR -eq 0 || ${1} = +(*IMPORT*FROM*TYPE*) ]]
		                    then
	                                ITEM2="${ITEM2}${g_STRINGSIGN}"
                                        let SFUNC=1
                                    else
	                                ITEM2="${ITEM2}$"
                                    fi
                                else
	                            ITEM2="${ITEM2}${INCHAR}"
                                fi
                                let INLEN=${#INTOKEN}-1
                                INTOKEN="${INTOKEN: -$INLEN}"
                            done
                            ((INLEN+=1))
		            DATA="${DATA: -$INLEN}"
                            TOKEN="${TOKEN} CONCAT${g_STRINGSIGN}(${ITEM1},${ITEM2}) "
                            ((SFTOT+=1))
                        fi
                    fi
		    IS_ESCAPED=0;;
                [A-Za-z=])
		    if [[ $IS_STRING -eq 0 ]]
		    then
		        IS_STATEMENT=" "
		    fi
		    IS_ESCAPED=0;;
	        *)
		    IS_ESCAPED=0;;
	    esac
	    # Convert back to space
	    if [[ "${CHAR}" = "${g_PARSEVAR}" ]]
	    then
	        TOKEN="${TOKEN}${IS_STATEMENT}"
            elif [[ -n ${CHAR} ]]
            then
	        TOKEN="${TOKEN}${CHAR}"
	    fi
	    let LEN=${#DATA}-1
	    DATA="${DATA: -$LEN}"
        done

        # Check if all nested '&' have been parsed
        if [[ "${TOKEN}" = "${RESULT}" || ${1} != +(*\&*) ]]
        then
            break
        fi
        RESULT=${TOKEN}
        DATA=$(echo ${TOKEN// /${g_PARSEVAR}})
    done
    # If we are in a string function increase line counter
    if [[ ${g_FUNCNAME} = +(*${g_STRINGSIGN}*) && $SFTOT -gt 0 ]]
    then
        ((g_STRING_LINE+=1))
    fi
    # Determine amount of string funcs
    if [[ $SFTOT -gt $g_STRING_FUNC ]]
    then
        g_STRING_FUNC=$SFTOT
    fi
    Parse_Line "${TOKEN}"
}

#-----------------------------------------------------------

function Parse_Chunk
{
    typeset CHAR IS_ESCAPED IS_STRING TOKEN DATA LEN TERM EQ IS_EQUATION

    IS_ESCAPED=0
    IS_STRING=0
    IS_EQUATION=0
    TOKEN=
    EQ="!"

    # Initialize miniparser, convert spaces
    DATA=$(echo ${1// /${g_PARSEVAR}})
    LEN=${#DATA}

    until [[ $LEN -eq 0 ]]
    do
        CHAR="${DATA:0:2}"
	case $CHAR in
            "==")
                if [[ $IS_STRING -eq 0 ]]
                then
	            DATA="= ${DATA:2}"
                fi;;
            "<>")
                if [[ $IS_STRING -eq 0 ]]
                then
	            DATA="!=${DATA:2}"
                fi;;
        esac
	CHAR="${DATA:0:1}"
	case $CHAR in
	    =)
		if [[ $IS_STRING -eq 0 ]]
		then
                    if [[ "${1%%\(*}" = +(*${g_STRINGSIGN}*) || "${1%%\(*}" = +(*${g_DQUOTESIGN}*) ]]
                    then
                        TERM="${TOKEN}"
                        TOKEN=
                    elif [[ $IS_EQUATION -eq 0 ]]
                    then
		        TOKEN="${TOKEN}=="
                    else
		        TOKEN="${TOKEN}="
                        IS_EQUATION=0
                    fi
		    IS_ESCAPED=0
                else
		    TOKEN="${TOKEN}="
		fi;;
	    !)
		if [[ $IS_STRING -eq 0 ]]
		then
                    if [[ "${1%%\(*}" = +(*${g_STRINGSIGN}*) || "${1%%\(*}" = +(*${g_DQUOTESIGN}*) ]]
                    then
                        EQ=""
                    elif [[ $IS_EQUATION -eq 0 ]]
                    then
                        TOKEN="${TOKEN}!="
		        IS_ESCAPED=0
                        let LEN=${#DATA}-1
                        DATA="${DATA: -$LEN}"
                    else
                        TOKEN="${TOKEN}!"
                        IS_EQUATION=0
                    fi
                else
                    TOKEN="${TOKEN}!"
		fi;;
            \<)
                IS_EQUATION=1
                TOKEN="${TOKEN}<";;
            \>)
                IS_EQUATION=1
                TOKEN="${TOKEN}>";;
            \#)
                IS_EQUATION=1
                TOKEN="${TOKEN}#";;
	    \\)
		if [[ $IS_ESCAPED -eq 0 ]]
		then
		    IS_ESCAPED=1
		else
		    IS_ESCAPED=0
		fi
                TOKEN="${TOKEN}\\";;
	    \")
		if [[ $IS_ESCAPED -eq 0 ]]
		then
		    if [[ $IS_STRING -eq 0 ]]
		    then
			IS_STRING=1
		    else
			IS_STRING=0
		    fi
		fi
		IS_ESCAPED=0
                TOKEN="${TOKEN}\"";;
	    *)
                # Convert back to space
	        if [[ "${CHAR}" = "${g_PARSEVAR}" ]]
	        then
	            TOKEN="${TOKEN} "
                else
	            TOKEN="${TOKEN}${CHAR}"
	        fi
		IS_ESCAPED=0;;
	esac
	let LEN=${#DATA}-1
	DATA="${DATA: -$LEN}"
    done

    if [[ "${1%%\(*}" = +(*${g_STRINGSIGN}*) || "${1%%\(*}" = +(*${g_DQUOTESIGN}*) ]]
    then
        TOKEN="((__b2c__option_compare == 0) ? ${EQ}__b2c__strcmp(${TERM}, $TOKEN) : ${EQ}__b2c__strcasecmp(${TERM}, $TOKEN))"
    fi

    g_EQUATION="${g_EQUATION} ${TOKEN} ${2}"
}

#-----------------------------------------------------------

function Parse_Equation
{
    typeset CHAR IS_ESCAPED IS_STRING TOKEN DATA LEN
    typeset AND OR

    g_EQUATION=
    IS_ESCAPED=0
    IS_STRING=0
    TOKEN=

    AND="${g_PARSEVAR}AND${g_PARSEVAR}"
    OR="${g_PARSEVAR}OR${g_PARSEVAR}"

    # Initialize miniparser, convert spaces
    DATA=$(echo ${1// /${g_PARSEVAR}})
    LEN=${#DATA}

    until [[ $LEN -eq 0 ]]
    do
        CHAR="${DATA:0:5}"
	if [[ "${CHAR}" = "${AND}" ]]
        then
	    if [[ $IS_STRING -eq 0 ]]
	    then
		Parse_Chunk "${TOKEN}" " AND "
                let LEN=${#DATA}-4
	        DATA="${DATA: -$LEN}"
		CHAR=
		TOKEN=
            fi
        fi
        CHAR="${DATA:0:4}"
	if [[ "${CHAR}" = "${OR}" ]]
        then
	    if [[ $IS_STRING -eq 0 ]]
	    then
		Parse_Chunk "${TOKEN}" " OR "
                let LEN=${#DATA}-3
	        DATA="${DATA: -$LEN}"
		CHAR=
		TOKEN=
            fi
        fi
	CHAR="${DATA:0:1}"
	case $CHAR in
	    \\)
		if [[ $IS_ESCAPED -eq 0 ]]
		then
		    IS_ESCAPED=1
		else
		    IS_ESCAPED=0
		fi;;
	    \")
		if [[ $IS_ESCAPED -eq 0 ]]
		then
		    if [[ $IS_STRING -eq 0 ]]
		    then
			IS_STRING=1
		    else
			IS_STRING=0
		    fi
		fi
		IS_ESCAPED=0;;
	    *)
		IS_ESCAPED=0;;
	esac
	# Convert back to space
	if [[ "${CHAR}" = "${g_PARSEVAR}" ]]
	then
	    TOKEN="${TOKEN} "
        else
	    TOKEN="${TOKEN}${CHAR}"
	fi
	let LEN=${#DATA}-1
	DATA="${DATA: -$LEN}"
    done
    Parse_Chunk "${TOKEN}"
}

#-----------------------------------------------------------
#
# Main program
#
#-----------------------------------------------------------

# Default BACON settings
let g_MAX_DIGITS=32

# This is the size for static buffers like fgets, read etc.
let g_BUFFER_SIZE=512

# Maximum RETURN buffers
let g_MAX_RBUFFERS=32

# Defaults for parameters
g_CCNAME=
g_TEMPDIR=
g_INCFILES=
g_CCFLAGS=
g_BINEXT=
g_REBUILD_ARCHIVE=
g_ARNAME="ar -r"
g_RANLIB=

g_CCNAME_TMP=
g_TEMPDIR_TMP=
g_INCFILES_TMP=
g_LDFLAGS_TMP=
g_CCFLAGS_TMP=

let g_NO_COMPILE=0
let g_TMP_PRESERVE=0
let g_NO_QUESTION=0
let g_CPP=0
let g_XGETTEXT=0
let g_SAVE_CONFIG=0
let g_DEBUG=0

let g_USE_C=0
let g_USE_H=0
let g_MAX_BACKLOG=5

g_INCLUDE_FILES=
let g_TRACE=0
let g_OPTION_BASE=0
let g_OPTION_SOCKET=5

# Some global declarations
g_ALL_MAIN_VARS=
g_ALL_FUNC_VARS=
g_CURFILE=
g_FUNCNAME=
g_FUNCTYPE=
g_PROTOTYPE=
g_TMP_FILES=
g_LOCALSTRINGS=
g_STRINGARRAYS=
g_STRINGARGS=
g_DYNAMICARRAYS=
g_STATICARRAYS=
g_RECORDCACHE=
let g_LOOPCTR=0
typeset -a g_LOOPVAR
typeset -a g_LOOPSTEP
g_ERRORTXT=
g_EQUATION=
g_COMMENT="false"
g_TRACE_PREFIX=
g_IGNORE_PARSE="1"
g_VARTYPE="long"
g_OBJ_FILES=
g_MAKE_LINE=
g_MONITOR=
let g_STRING_FUNC=1
let g_STRING_LINE=0

# Always create a final label
g_CATCHGOTO="__B2C__PROGRAM__EXIT"
g_CATCH_USED=0

# Records
g_RECORDNAME=
g_RECORDVAR=
g_WITHVAR=
g_RECORDEND_BODY=
g_RECORDEND_HEADER=

# Socket defaults
g_SOCKTYPE="SOCK_STREAM"
g_NETWORKTYPE="TCP"
g_MULTICAST_TTL=1
g_SCTP_STREAMS=1

# Select/Case
typeset -a g_SELECTVAR
typeset -a g_IN_CASE
g_SELECTVAR_CTR=0

# Relate
typeset -a g_RELATE
g_RELATE_CTR=0

g_FCTR=0
g_CCTR=0

# Timer related
ttime=0

# Read any configfile values
if [[ ! -d $HOME/.bacon ]]
then
    mkdir $HOME/.bacon
fi

if [[ -f $HOME/.bacon/bacon.cfg ]]
then
    while read -r LINE
    do
	case ${LINE%% *} in
	    ccname) g_CCNAME_TMP=${LINE#ccname}; g_CCNAME_TMP=${g_CCNAME_TMP##*( )};;
	    tempdir) g_TEMPDIR_TMP=${LINE#tempdir}; g_TEMPDIR_TMP=${g_TEMPDIR_TMP##*( )};;
	    incfiles) g_INCFILES_TMP=${LINE#incfiles};;
	    ldflags) g_LDFLAGS_TMP=${LINE#ldflags};;
	    ccflags) g_CCFLAGS_TMP=${LINE#ccflags};;
	    lowercase) g_LOWERCASE_TMP=${LINE#lowercase};;
	esac
    done < $HOME/.bacon/bacon.cfg
fi

# Get arguments
while getopts ":c:d:i:l:o:b:r:axnjfpvwyz@" OPT
do
    case $OPT in
	c) g_CCNAME=$OPTARG;;
	d) if [[ ! -d $OPTARG ]]
	   then
		mkdir -p $OPTARG
	   fi
	   g_TEMPDIR=$OPTARG;;
	i) if [[ ! -f $OPTARG && ! -f "/usr/include/$OPTARG" && ! -f "/usr/local/include/$OPTARG" ]]
	   then
		echo -e "System error: included C header file from -i option not found!"
		exit 1
	   fi
	   if [[ ! -f "/usr/include/$OPTARG" && ! -f "/usr/local/include/$OPTARG" ]]
	   then
		if [[ ${OPTARG:0:1} != "/" ]]
                then
		    g_INCFILES="$g_INCFILES `pwd`/${OPTARG}"
                else
		    g_INCFILES="$g_INCFILES ${OPTARG}"
		fi
	   else
		g_INCFILES="$g_INCFILES <${OPTARG}>"
	   fi;;
	l) if [[ $OPTARG = +(* *) || $OPTARG = +(-*) ]]
           then
               g_LDFLAGS="$g_LDFLAGS $OPTARG"
           else
	       g_LDFLAGS="$g_LDFLAGS -l$OPTARG"
           fi;;
	o) g_CCFLAGS="$g_CCFLAGS $OPTARG";;
	n) g_NO_COMPILE=1;;
	a) g_CCFLAGS="$g_CCFLAGS -fPIC"
           g_REBUILD_ARCHIVE="libbacon.a";;
        b) g_ARNAME="$OPTARG";;
        r) g_RANLIB="$OPTARG";;
	j) g_CPP=1;;
	f) g_LDFLAGS="$g_LDFLAGS -shared -rdynamic"
	   g_CCFLAGS="$g_CCFLAGS -fPIC"
	   g_BINEXT=".so";; 
	p) g_TMP_PRESERVE=1;;
	x) g_XGETTEXT=1;;
	y) g_NO_QUESTION=1;;
	v) echo
	   echo "BaCon version $g_VERSION - BASH - (c) Peter van Eerten - MIT License."
	   echo
	   exit 0;; 
	w) g_SAVE_CONFIG=1;;
	z) g_LOWERCASE=1;;
	@) g_DEBUG=1;;
	\?|h) echo 
	    echo "USAGE: bacon [options] program[.bac]"
	    echo 
	    echo "OPTIONS:"
	    echo 
	    echo -e " -c <compiler>\tCompiler to use (default: cc)"
	    echo -e " -l <ldflags>\tPass libraries to linker"
	    echo -e " -o <options>\tPass compiler options"
	    echo -e " -i <include>\tAdd include file to C code"
	    echo -e " -d <tmpdir>\tTemporary directory (default: .)"
	    echo -e " -b <archiver>\tDefine archiver"
	    echo -e " -r <ranlib>\tDefine ranlib"
	    echo -e " -y \t\tAutomatically delete temporary files"
	    echo -e " -a \t\tRebuild BaCon archive"
	    echo -e " -x \t\tExtract gettext strings"
	    echo -e " -z \t\tAllow lowercase keywords"
	    echo -e " -f \t\tCreate Shared Object"
	    echo -e " -n \t\tDo not compile, only convert"
	    echo -e " -j \t\tInvoke C Preprocessor"
	    echo -e " -p \t\tPreserve temporary files"
	    echo -e " -w \t\tSave options to BaCon configfile"
	    echo -e " -v \t\tShow version"
	    echo -e " -h \t\tShow help"
	    echo 
	    exit 0;;
    esac
done

shift $(($OPTIND-1))

# See if configfile must be written
if [[ $g_SAVE_CONFIG -eq 1 ]]
then
    echo -e "ccname $g_CCNAME" > $HOME/.bacon/bacon.cfg
    echo -e "tempdir $g_TEMPDIR" >> $HOME/.bacon/bacon.cfg
    echo -e "incfiles $g_INCFILES" >> $HOME/.bacon/bacon.cfg
    echo -e "ldflags ${g_LDFLAGS##*\-lm}" >> $HOME/.bacon/bacon.cfg
    echo -e "ccflags $g_CCFLAGS" >> $HOME/.bacon/bacon.cfg
    echo -e "lowercase $g_LOWERCASE" >> $HOME/.bacon/bacon.cfg
    g_CCNAME_TMP=$g_CCNAME
    g_TEMPDIR_TMP=$g_TEMPDIR
    g_INCFILES_TMP=$g_INCFILES
    g_LDFLAGS_TMP=$g_LDFLAGS
    g_CCFLAGS_TMP=$g_CCFLAGS
    g_LOWERCASE_TMP=$g_LOWERCASE
fi

# Use the commandline or configfile settings?
if [[ -z $g_CCNAME ]]
then
    g_CCNAME="${g_CCNAME_TMP}"
    if [[ -z $g_CCNAME ]]
    then
        g_CCNAME=cc
    fi
fi
if [[ -z $g_TEMPDIR ]]
then
    g_TEMPDIR="${g_TEMPDIR_TMP}"
    if [[ -z $g_TEMPDIR ]]
    then
        g_TEMPDIR="."
    fi
fi
if [[ -z $g_INCFILES ]]
then
    g_INCFILES="${g_INCFILES_TMP}"
fi
g_LDFLAGS="${g_LDFLAGS} ${g_LDFLAGS_TMP}"
if [[ -z $g_CCFLAGS ]]
then
    g_CCFLAGS="${g_CCFLAGS_TMP}"
fi
if [[ -z $g_LOWERCASE || $g_LOWERCASE -eq 0 ]]
then
    g_LOWERCASE="${g_LOWERCASE_TMP}"
fi

# Check if a filename was entered, if so get it
if [[ $# -eq 0 ]]
then
    if [[ $g_SAVE_CONFIG -eq 0 ]]
    then
        echo -e "System error: no filename? Run with '-h' to see usage."
    fi
    exit 1
elif [[ "$@" = +(http://*) ]]
then
    if [[ -z `which telnet 2>/dev/null` ]]
    then
	echo "System error: No telnet client found! Cannot retrieve file."
	exit 1
    fi
    echo -n "Fetching file... "

    # Remove http part
    g_SOURCEFILE="${@#*http://}"

    # Get header to see if file exists, and if so, get length
    HEAD=`(echo "set crlf on"; echo "open ${g_SOURCEFILE%%/*} 80"; sleep 1;
    echo "HEAD /${g_SOURCEFILE#*/} HTTP/1.1"; echo "Host: ${g_SOURCEFILE%%/*}"; echo;
    sleep 1; echo "quit";) | telnet 2>/dev/null`

    LEN=`echo ${HEAD#*Content-Length: }`

    # No file found on server
    if [[ "${LEN%% *}" = "telnet>" || "${HEAD}" != +(*Content-Length*) ]]
    then
        echo "System error: file not found! Check URL and try again."
        exit 1
    fi

    # Get the actual contents of the file
    DOWNLOAD=`(echo "set crlf on"; echo "open ${g_SOURCEFILE%%/*} 80"; sleep 2;
    echo "GET /${g_SOURCEFILE#*/} HTTP/1.1"; echo "Host: ${g_SOURCEFILE%%/*}"; echo;
    sleep 2; echo "quit";) | telnet 2>/dev/null`

    # Set the final filename and save
    g_SOURCEFILE="${1##*/}"
    let START=${#DOWNLOAD}-${LEN%% *}
    echo "${DOWNLOAD:${START}:${#DOWNLOAD}}" > $g_SOURCEFILE

    # Check resulting filesize with HTTP header
    FILELEN=`wc -c $g_SOURCEFILE`
    let FILELEN=${FILELEN%% *}-1
    if [[ ${FILELEN} -ne ${LEN%% *} ]]
    then
        echo "System error: file could not be downloaded probably due to a timeout. Try again later."
        exit 1
    fi
    echo "done."
elif [[ "$@" != +(*.bac) ]]
then
    g_SOURCEFILE="$@.bac"
else
    g_SOURCEFILE="$@"
fi

# Check if file exists
if [[ ! -f $g_SOURCEFILE ]]
then
    echo -e "System error: file not found!"
    exit 1
fi

# Change the working directory
if [[ -d ${g_SOURCEFILE%/*} && ${g_SOURCEFILE} = +(/*) ]]
then
    cd ${g_SOURCEFILE%/*}
fi

# Now create the global filenames where to write to
g_CFILE=$g_TEMPDIR/${g_SOURCEFILE##*/}.c
g_HFILE=$g_TEMPDIR/${g_SOURCEFILE##*/}.h
g_GENERIC=$g_TEMPDIR/${g_SOURCEFILE##*/}.generic.h
STRINGARRAYFILE=$g_TEMPDIR/${g_SOURCEFILE##*/}.string.h
FLOATARRAYFILE=$g_TEMPDIR/${g_SOURCEFILE##*/}.float.h

# Add to total file list
g_TMP_FILES="$g_CFILE $g_HFILE $g_GENERIC $STRINGARRAYFILE $FLOATARRAYFILE"

# Check if previous temporary files exist
LEN=`ls $g_TEMPDIR/${g_SOURCEFILE%.bac}.*.* 2>/dev/null | wc -l`
if [[ ${g_NO_QUESTION} -eq 1 ]]
then
    rm -f $g_TEMPDIR/${g_SOURCEFILE%.bac}.*.*
else
    if [[ ${LEN} -gt 0 ]]
    then
        if [[ -n $BASH ]]
        then
            read -p "WARNING: ${LEN} temporary files found! Do you want to delete them (y/n)? " ANSWER
        else
            read ANSWER?"WARNING: ${LEN} temporary files found! Do you want to delete them (y/n)? "
        fi
        if [[ ${ANSWER} = "y" ]]
        then
            rm -f $g_TEMPDIR/${g_SOURCEFILE%.bac}.*.*
            echo "Temporary files were deleted."
        else
            echo "Exiting..."
            exit 1
        fi
    fi
fi

# Keep start time
ttime=$SECONDS

# Create C file
echo "/* Created with BASH BaCon $g_VERSION - (c) Peter van Eerten - MIT License (Expat) */" > $g_CFILE
echo "#include \"${g_SOURCEFILE##*/}.h\"" >> $g_CFILE
echo "#include \"${g_SOURCEFILE##*/}.string.h\"" >> $g_CFILE
echo "#include \"${g_SOURCEFILE##*/}.float.h\"" >> $g_CFILE
echo "int __b2c__trap = 1;" >> $g_CFILE
echo "int __b2c__catch_set_backup = 0, __b2c__catch_set = 0;" >> $g_CFILE
echo "int __b2c__option_compare = 0;" >> $g_CFILE
echo "int __b2c__option_memstream = 0;" >> $g_CFILE
echo "int __b2c__option_startpoint = 0;" >> $g_CFILE
echo "int __b2c__option_open = O_RDWR|O_NOCTTY|O_SYNC;" >> $g_CFILE
echo "int __b2c__collapse = 0;" >> $g_CFILE
echo "int __b2c__break_ctr = 0;" >> $g_CFILE
echo "int __b2c__break_flag = 0;" >> $g_CFILE
echo "char __b2c__chop_default[] = \"\r\n\t \";" >> $g_CFILE
echo "int __b2c__stringarray_ptr = 0;" >> $g_CFILE
echo "int __b2c__floatarray_ptr = 0;" >> $g_CFILE
echo "char EmptyString[1] = {\"\"};" >> $g_CFILE
echo "char* __b2c__sbuffer[__b2c_STRING_FUNC] = { NULL };" >> $g_CFILE
echo "const size_t __b2c__sbuffer_size = __b2c_STRING_FUNC;" >> $g_CFILE
echo "size_t __b2c__sbuffer_ptr = 0;" >> $g_CFILE
echo "size_t __b2c__sbuffer_length[__b2c_STRING_FUNC] = { 0 };" >> $g_CFILE
echo "char* __b2c__rbuffer[$g_MAX_RBUFFERS] = { NULL };" >> $g_CFILE
echo "size_t __b2c__rbuffer_length[$g_MAX_RBUFFERS] = { 0 };" >> $g_CFILE
echo "int __b2c__rbuffer_ptr = 0;" >> $g_CFILE
echo "jmp_buf __b2c__gosub_buffer[$g_MAX_RBUFFERS];" >> $g_CFILE
echo "int __b2c__gosub_buffer_ptr = -1;" >> $g_CFILE
echo "jmp_buf __b2c__data_jump;" >> $g_CFILE
echo "int __b2c__data_jump_flag = 0;" >> $g_CFILE
echo "char **__b2c__deltree = { NULL }; int __b2c__del_ctr = 0;" >> $g_CFILE
echo "char *__b2c__assign = NULL;" >> $g_CFILE
echo "char *__b2c__split = NULL; char *__b2c__split_tmp = NULL;" >> $g_CFILE
echo "int __b2c__yes = 1; char __b2c__ttl = 1;" >> $g_CFILE
echo "char __b2c__data_client[$g_BUFFER_SIZE] = { 0 }; char __b2c__data_server[$g_BUFFER_SIZE] = { 0 };" >> $g_CFILE
echo "int __b2c__arglen = 0;" >> $g_CFILE
echo "char **__b2c__stringstack = NULL; double *__b2c__doublestack = NULL;" >> $g_CFILE
echo "long *__b2c__longstack = NULL; int *__b2c__typestack = NULL; int __b2c__stackptr = 0;" >> $g_CFILE
echo "/* Set some BaCon reserved variables to their default value */" >> $g_CFILE
echo "int ERROR = 0;" >> $g_CFILE
echo "int RETVAL = 0;" >> $g_CFILE
echo "int REGLEN = 0;" >> $g_CFILE
echo "char VERSION${g_STRINGSIGN}[] = \"$g_VERSION\";" >> $g_CFILE
echo "/* We need to put the global definitions here because of TCC */" >> $g_CFILE
echo "jmp_buf __b2c__jump;" >> $g_CFILE
echo "struct timeval __b2c__tm; time_t __b2c__elapsed_secs; int __b2c__elapsed_usecs;" >> $g_CFILE
echo "struct itimerval __b2c__alarm;" >> $g_CFILE
echo "int __b2c__ctr;" >> $g_CFILE
echo "char __b2c__input__buffer[$g_BUFFER_SIZE];" >> $g_CFILE
echo "FILE *__b2c__inFile; FILE *__b2c__outFile; size_t __b2c__Byte; struct dirent *__b2c__dir;" >> $g_CFILE
echo "struct termios __b2c__tty;" >> $g_CFILE
echo "struct timeval __b2c__to; struct hostent *__b2c__he;  char *__b2c__host; char *__b2c__port; struct sockaddr_in *__b2c__addr, *__b2c__from; struct ip_mreq __b2c__imreq;" >> $g_CFILE
echo "int __b2c__result; int __b2c__handle;" >> $g_CFILE
echo "int __b2c__counter;" >> $g_CFILE
echo "char __b2c__warn[$g_BUFFER_SIZE];" >> $g_CFILE
echo "char *ARGUMENT${g_STRINGSIGN};" >> $g_CFILE

# Create H file
echo "/* Created with BASH BaCon $g_VERSION - (c) Peter van Eerten - MIT License (Expat) */" > $g_HFILE
echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" >> $g_HFILE

echo "char *__b2c__stringarray[] = {" > $STRINGARRAYFILE

echo "double __b2c__floatarray[] = {" > $FLOATARRAYFILE

echo "/****************************/" >> $g_CFILE
echo "/* Main program starts here */" >> $g_CFILE
echo "/****************************/" >> $g_CFILE
echo "int main(int argc, char **argv){" >> $g_CFILE

# Check version
echo "__b2c__version(\"$g_VERSION\");" >> $g_CFILE

# See if we have the detector
echo "if(argc==2 && !strcmp(argv[1], \"-bacon\")){fprintf(stderr, \"Converted by %s.\n\", COMPILED_BY_WHICH_BACON${g_STRINGSIGN}); exit(EXIT_FAILURE);}" >> $g_CFILE

# Put arguments into reserved variable ARGUMENT
echo "/* Setup the reserved variable 'ARGUMENT' */" >> $g_CFILE
echo "for(__b2c__counter=0; __b2c__counter < argc; __b2c__counter++)" >> $g_CFILE
echo "{if(strstr(argv[__b2c__counter], \" \")||strstr(argv[__b2c__counter], \"\011\")) __b2c__arglen += strlen(argv[__b2c__counter]) + 3;" >> $g_CFILE
echo "else __b2c__arglen += strlen(argv[__b2c__counter]) + 1;} __b2c__arglen++; ARGUMENT${g_STRINGSIGN} = (char*)calloc(__b2c__arglen, sizeof(char));" >> $g_CFILE
echo "for(__b2c__counter=0; __b2c__counter < argc; __b2c__counter++){if(strstr(argv[__b2c__counter], \" \")||strstr(argv[__b2c__counter], \"\011\")){" >> $g_CFILE
echo "strcat(ARGUMENT${g_STRINGSIGN}, \"\042\"); strcat(ARGUMENT${g_STRINGSIGN}, argv[__b2c__counter]); strcat(ARGUMENT${g_STRINGSIGN}, \"\042\");}" >> $g_CFILE
echo "else strcat(ARGUMENT${g_STRINGSIGN}, argv[__b2c__counter]); if(__b2c__counter != argc - 1) strcat(ARGUMENT${g_STRINGSIGN}, \" \");}" >> $g_CFILE
echo "/* By default seed random generator */" >> $g_CFILE
echo "srandom((unsigned int)time(NULL));" >> $g_CFILE
echo "/* Initialize internal stackpointer */" >> $g_CFILE
echo "__b2c__typestack = (int*)calloc(1, sizeof(int));" >> $g_CFILE
echo "__b2c__stringstack = (char**)realloc(__b2c__stringstack, sizeof(char*)); __b2c__stringstack[0] = calloc(1, sizeof(char));" >> $g_CFILE
echo "/* Determine current moment and keep it for TIMER function */" >> $g_CFILE
echo "gettimeofday(&__b2c__tm, NULL); __b2c__elapsed_usecs = __b2c__tm.tv_usec; __b2c__elapsed_secs = __b2c__tm.tv_sec;" >> $g_CFILE
echo "/* Setup error signal handling */" >> $g_CFILE
echo "signal(SIGILL, __b2c__catch_signal);" >> $g_CFILE
echo "signal(SIGABRT, __b2c__catch_signal);" >> $g_CFILE
echo "signal(SIGFPE, __b2c__catch_signal);" >> $g_CFILE
echo "signal(SIGSEGV, __b2c__catch_signal);" >> $g_CFILE
echo "/* Rest of the program */" >> $g_CFILE

# There are no imported symbols yet
g_IMPORTED=

# List all BaCon functions
DATA_1="ABS ACOS ADDRESS AND ASC ASIN ATN CEIL CMDLINE COLUMNS COS COUNT DAY DEC DEG ENDFILE EQUAL ERROR EVEN EXP FILEEXISTS FILELEN FILETIME FILETYPE FLOOR FP GETKEY GETX GETY"
DATA_2="HOUR IIF INSTR INSTRREV ISFALSE ISKEY ISTRUE LEN LOG MAXNUM MEMCHECK MEMORY MEMTELL MINUTE MOD MONTH NOT NOW ODD OR PEEK POW RAD RANDOM REGEX RND ROUND ROWS SEARCH"
DATA_3="SECOND SGN SIN SIZEOF SQR TAN TELL TIMER TIMEVALUE VAL WAIT WEEK YEAR ALARM ALIAS APPENDING ARRAY AS ASSOC BACONLIB BACK BASE BG BLACK BLUE BREAK BROADCAST BY CALL CASE"
DATA_4="CATCH CHANGEDIR CHUNK CLEAR CLOSE CMODE COLLAPSE COLOR CONST COMPARE COMPILER CONTINUE COPY CURRENT CURSOR CYAN DATA DECLARE DECR DEFAULT DEF DELETE DEVICE DIRECTORY DO"
DATA_5="DOWN DOWNTO ELIF ELSE ENDFUNCTION ENDIF END ENDSELECT ENDSUB ENDENUM ENDUSEC ENDUSEH ENDWITH ENUM EPRINT EQ EXIT FG FI FILE FN FOR FORMAT FORWARD FRAMEWORK FREE FROM"
DATA_6="FUNCTION GE GETBYTE GETFILE GETLINE GLOBAL GOSUB GOTO GOTOXY GREEN GT IF IMODE IMPORT IN INCLUDE INCR INPUT INTENSE INTERNATIONAL INVERSE IS ISNOT JOIN LABEL LDFLAGS"
DATA_7="LE LET LMODE LOCAL LOOKUP LT MAGENTA MAKEDIR MEMREWIND MEMSTREAM MEMTYPE MONITOR MULTICAST NE NETWORK NEXT NORMAL OFF OFFSET OMODE ON OPEN OPTION OPTIONS OTHER PARSE"
DATA_8="POKE PRAGMA PRINT PROTO PULL PUSH PUTBYTE PUTLINE READING READ READLN READWRITE RECEIVE RECORD RECURSIVE RED REDIM RELATE REM RENAME REPEAT RESET RESIZE RESTORE RESUME"
DATA_9="RETURN REWIND SCROLL SCTP SEED SEEK SELECT SEND SERVER SETENVIRON SETSERIAL SIZE SLEEP SOCKET SORT SPEED SPLIT START STARTPOINT STEP STOP SUB SWAP SYSTEM TCP"
DATA_10="TEXTDOMAIN THEN TO TRACE TRAP TYPE UDP UNTIL UP USEC USEH VAR VARTYPE WEND WHENCE WHILE WHITE WITH WRITELN WRITING YELLOW NUMBER STRING FLOATING"
DATA_11="CHOP$ CHR$ CONCAT$ CURDIR$ ERR$ EXEC$ EXTRACT$ FILL$ GETENVIRON$ GETPEER$ HOSTNAME$ HEX$ HOST$ IIF$ INTL$ LCASE$ LEFT$ MID$ MONTH$ NNTL$ OS$ REPLACE$ REVERSE$ RIGHT$"
DATA_12="SPC$ STR$ TAB$ TYPEOF$ UCASE$ WEEKDAY$ REALPATH$ BASENAME$ DIRNAME$ MAXRANDOM NL$ CR$ EL$ PI REGLEN RETVAL VERSION$ ARGUMENT$ TRUE FALSE"

# Allow lowercase statements and functions
if [[ $g_LOWERCASE -eq 1 ]]
then
    echo -n "Creating lowercase definitions... "
    for i in ${DATA_1} ${DATA_2} ${DATA_3} ${DATA_4} ${DATA_5} ${DATA_6} ${DATA_7} ${DATA_8} ${DATA_9} ${DATA_10} ${DATA_11} ${DATA_12}
    do
        MAPPING="$MAPPING -D`echo ${i}|tr [:upper:] [:lower:]`=${i}"
    done
    echo "done."
    g_CPP=1
fi

# Prevent filename expansion
set -f

# Check if the C Preprocessor needs to run
if [[ $g_CPP -eq 1 ]]
then
    if [[ -n `which cpp 2>/dev/null` ]]
    then
        echo -n "Preprocessing '${g_SOURCEFILE}'... "
        # Change next line marker to overcome C preprocessor interpretation
        while read -r LINE; do if [[ ${LINE} = +(\#*) ]]; then echo "${LINE}"; else echo "@${LINE}@"; fi; done < $g_SOURCEFILE > $g_SOURCEFILE.tmp
        cpp -w -P $MAPPING $g_SOURCEFILE.tmp $g_SOURCEFILE.cpp
        # Restore next line marker
        while read -r LINE; do LINE="${LINE:1}"; echo "${LINE%@*}"; done < $g_SOURCEFILE.cpp > $g_SOURCEFILE.bac
	g_TMP_FILES="$g_TMP_FILES ${g_SOURCEFILE}.cpp ${g_SOURCEFILE}.tmp ${g_SOURCEFILE}.bac"
        g_FEED="${g_SOURCEFILE}.bac"
        echo "done."
    else
        if [[ $g_LOWERCASE -eq 1 ]]
        then
	    echo -e "System error: the C Preprocessor 'cpp' not found, cannot parse lowercase! Exiting..."
        else
	    echo -e "System error: the C Preprocessor 'cpp' not found on this system! Exiting..."
        fi
	exit 1
    fi
else
    g_FEED=${g_SOURCEFILE}
fi
g_CURFILE=${g_SOURCEFILE##*/}

# Initialize
LEN=
TOTAL=
SEQ=
g_COUNTER=1
g_TOTAL_LINES=0

# Detect if this is a Windows file
if [[ `head -1 ${g_FEED}` = +(*${g_CRLF}) ]]
then
    echo "System error: Windows file detected! Remove non-Unix CR line separators first. Exiting..."
    exit 1
fi

# Start walking through program
while read -r LINE
do
    echo -e -n "\rConverting '${g_SOURCEFILE}'... ${g_COUNTER}\033[0K"
    # Line is not empty?
    if [[ -n "$LINE" ]]
    then
	if [[ "$LINE" = +(* \\) && "$LINE" != +(REM*) && "$LINE" != +(${g_SQUOTESIGN}*) ]]
	then
	    let LEN="${#LINE}"-2
	    SEQ="${LINE:0:$LEN}"
	    TOTAL="${TOTAL}${SEQ} "
        else
	    TOTAL="${TOTAL}${LINE}"
	    if [[ "${TOTAL}" != +(REM*) && "${TOTAL}" != +(${g_SQUOTESIGN}*) ]]
	    then
                echo "/* FILE $g_FEED LINE $g_COUNTER */" >> $g_CFILE
                echo "/* FILE $g_FEED LINE $g_COUNTER */" >> $g_HFILE
		Tokenize "${TOTAL}"
	    fi
	    TOTAL=
	fi
    fi
    ((g_COUNTER+=1))
done < ${g_FEED}

# Debug variables
if [[ ${g_DEBUG} -eq 1 ]]
then
    Debug_Vars
fi

# Restore filename expansion
set +f

# Finalize main C-file
if [[ $g_CATCH_USED -eq 1 ]]
then
    echo "__B2C__PROGRAM__EXIT:" >> $g_CFILE
fi
echo "return 0;" >> $g_CFILE
echo "}" >> $g_CFILE

# Finalize STRING ARRAY file for DATA
echo " \"\" };" >> $STRINGARRAYFILE

# Finalize FLOAT ARRAY file for DATA
echo " 0.0};" >> $FLOATARRAYFILE

# Create generic headerfile, functions are converted using macros
echo "/* Created with BASH BaCon $g_VERSION - (c) Peter van Eerten - MIT License (Expat) */" > $g_GENERIC
echo "#include <stdio.h>" >> $g_GENERIC
echo "#include <stdlib.h>" >> $g_GENERIC
echo "#include <stdarg.h>" >> $g_GENERIC
echo "#include <libgen.h>" >> $g_GENERIC
echo "#include <sys/time.h>" >> $g_GENERIC
echo "#include <sys/stat.h>" >> $g_GENERIC
echo "#include <sys/types.h>" >> $g_GENERIC
echo "#include <sys/wait.h>" >> $g_GENERIC
echo "#include <sys/socket.h>" >> $g_GENERIC
echo "#include <sys/utsname.h>" >> $g_GENERIC
echo "#include <sys/ioctl.h>" >> $g_GENERIC
echo "#include <dirent.h>" >> $g_GENERIC
echo "#include <setjmp.h>" >> $g_GENERIC
echo "#include <netdb.h>" >> $g_GENERIC
if [[ `uname` = +(*BSD*) ]]
then
    echo "#include <netinet/in.h>" >> $g_GENERIC
fi
echo "#include <arpa/inet.h>" >> $g_GENERIC
echo "#include <signal.h>" >> $g_GENERIC
echo "#include <regex.h>" >> $g_GENERIC
echo "#include <fcntl.h>" >> $g_GENERIC
echo "#include <math.h>" >> $g_GENERIC
echo "#include <unistd.h>" >> $g_GENERIC
echo "#include <string.h>" >> $g_GENERIC
echo "#include <ctype.h>" >> $g_GENERIC
echo "#include <dlfcn.h>" >> $g_GENERIC
echo "#include <errno.h>" >> $g_GENERIC
echo "#include <termios.h>" >> $g_GENERIC
echo "#include <time.h>" >> $g_GENERIC
# Add user include files
for i in $g_INCFILES
do
    if [[ "$i" = +(*\<*) ]]
    then
	echo "#include $i" >> $g_GENERIC
    else
	echo "#include \"$i\"" >> $g_GENERIC
    fi
done
echo "/* Undefine all symbols which happen to be BaCon keywords */" >> $g_GENERIC
for i in ${DATA_1} ${DATA_2} ${DATA_3} ${DATA_4} ${DATA_5} ${DATA_6} ${DATA_7} ${DATA_8} ${DATA_9} ${DATA_10} ${DATA_11} ${DATA_12}
do
    echo "#undef ${i}" >> $g_GENERIC
done

echo "/* Declarations for internal variables */" >> $g_GENERIC
echo "extern jmp_buf __b2c__jump;" >> $g_GENERIC
echo "extern int __b2c__trap;" >> $g_GENERIC
echo "extern int __b2c__catch_set_backup, __b2c__catch_set;" >> $g_GENERIC
echo "extern int __b2c__option_compare;" >> $g_GENERIC
echo "extern int __b2c__option_memstream;" >> $g_GENERIC
echo "extern int __b2c__option_startpoint;" >> $g_GENERIC
echo "extern int __b2c__option_open;" >> $g_GENERIC
echo "extern int __b2c__collapse;" >> $g_GENERIC
echo "extern int __b2c__break_ctr;" >> $g_GENERIC
echo "extern int __b2c__break_flag;" >> $g_GENERIC
echo "extern struct timeval __b2c__tm; extern time_t __b2c__elapsed_secs; extern int __b2c__elapsed_usecs;" >> $g_GENERIC
echo "extern struct itimerval __b2c__alarm;" >> $g_GENERIC
echo "extern char __b2c__chop_default[];" >> $g_GENERIC
echo "extern int __b2c__stringarray_ptr;" >> $g_GENERIC
echo "extern int __b2c__floatarray_ptr;" >> $g_GENERIC
echo "extern int __b2c__ctr;" >> $g_GENERIC
echo "extern char __b2c__input__buffer[$g_BUFFER_SIZE];" >> $g_GENERIC
echo "extern char EmptyString[1];" >> $g_GENERIC
# Save the max amount of parallel string buffers
echo "#define __b2c_STRING_FUNC ($g_STRING_FUNC+$g_STRING_LINE)" >> $g_GENERIC
echo "extern char* __b2c__sbuffer[__b2c_STRING_FUNC];" >> $g_GENERIC
echo "extern const size_t __b2c__sbuffer_size;" >> $g_GENERIC
echo "extern size_t __b2c__sbuffer_ptr;" >> $g_GENERIC
echo "extern size_t __b2c__sbuffer_length[__b2c_STRING_FUNC];" >> $g_GENERIC
echo "extern char* __b2c__rbuffer[$g_MAX_RBUFFERS];" >> $g_GENERIC
echo "extern size_t __b2c__rbuffer_length[$g_MAX_RBUFFERS];" >> $g_GENERIC
echo "extern int __b2c__rbuffer_ptr;" >> $g_GENERIC
echo "extern jmp_buf __b2c__gosub_buffer[$g_MAX_RBUFFERS];" >> $g_GENERIC
echo "extern int __b2c__gosub_buffer_ptr;" >> $g_GENERIC
echo "extern jmp_buf __b2c__data_jump;" >> $g_GENERIC
echo "extern int __b2c__data_jump_flag;" >> $g_GENERIC
echo "extern char **__b2c__deltree; extern int __b2c__del_ctr;" >> $g_GENERIC
echo "extern char *__b2c__assign;" >> $g_GENERIC
echo "extern char *__b2c__split; extern char *__b2c__split_tmp;" >> $g_GENERIC
echo "extern FILE *__b2c__inFile; extern FILE *__b2c__outFile; extern size_t __b2c__Byte; extern struct dirent *__b2c__dir;" >> $g_GENERIC
echo "extern struct termios __b2c__tty;" >> $g_GENERIC
echo "extern struct timeval __b2c__to; extern struct hostent *__b2c__he; extern char *__b2c__host; extern char *__b2c__port; extern struct sockaddr_in *__b2c__addr, *__b2c__from; extern struct ip_mreq __b2c__imreq;" >> $g_GENERIC
echo "extern int __b2c__yes; extern char __b2c__ttl;" >> $g_GENERIC
echo "extern int __b2c__result; extern int __b2c__handle;" >> $g_GENERIC
echo "extern char __b2c__data_client[$g_BUFFER_SIZE]; extern char __b2c__data_server[$g_BUFFER_SIZE];" >> $g_GENERIC
echo "extern int __b2c__counter;" >> $g_GENERIC
echo "extern int __b2c__arglen;" >> $g_GENERIC
echo "extern char **__b2c__stringstack; extern double *__b2c__doublestack;" >> $g_GENERIC
echo "extern long *__b2c__longstack; extern int *__b2c__typestack; extern int __b2c__stackptr;" >> $g_GENERIC
echo "extern char __b2c__warn[$g_BUFFER_SIZE];" >> $g_GENERIC
echo "extern char *__b2c__stringarray[];" >> $g_GENERIC
echo "extern double __b2c__floatarray[];" >> $g_GENERIC
echo "/* Declarations for BaCon variables */" >> $g_GENERIC
echo "extern char *ARGUMENT${g_STRINGSIGN};" >> $g_GENERIC
echo "extern int ERROR;" >> $g_GENERIC
echo "extern int RETVAL;" >> $g_GENERIC
echo "extern int REGLEN;" >> $g_GENERIC
echo "extern char VERSION${g_STRINGSIGN}[];" >> $g_GENERIC
# Prototypes for functions
echo "/* Prototypes for internal functions */" >> $g_GENERIC
echo "extern long int lrint(double __b2c__x);" >> $g_GENERIC
echo "extern double round(double __b2c__x);" >> $g_GENERIC
echo "void *__rbuf_realloc(void*, size_t);" >> $g_GENERIC
echo "void *__sbuf_realloc(void*, size_t);" >> $g_GENERIC
echo "long __sbuf_malloc_handle(size_t);" >> $g_GENERIC
echo "void __sbuf_need_realloc(long, size_t);" >> $g_GENERIC
echo "int __b2c__sortnrd(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnrd_down(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnrf(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnrf_down(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnrl(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnrl_down(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnri(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnri_down(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnrs(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnrs_down(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnrc(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortnrc_down(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortstr(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__sortstr_down(const void*, const void*);" >> $g_GENERIC
echo "int __b2c__strcasecmp(const char*, const char*);" >> $g_GENERIC
echo "int __b2c__strcmp(const char*, const char*);" >> $g_GENERIC
echo "char *__b2c__strdup(const char*);" >> $g_GENERIC
echo "/* Prototypes for BaCon functions */" >> $g_GENERIC
echo "char *ERR${g_STRINGSIGN}(int);" >> $g_GENERIC
echo "char* __b2c__asc2char(int);" >> $g_GENERIC
echo "void __b2c__catch_signal(int);" >> $g_GENERIC
echo "char* __b2c__chop(char*, ...);" >> $g_GENERIC
echo "char * __b2c__concat (char*, ...);" >> $g_GENERIC
echo "long __b2c__count(char*, unsigned char);" >> $g_GENERIC
echo "char* __b2c__curdir(void);" >> $g_GENERIC
echo "char *__b2c__datename(time_t, int);" >> $g_GENERIC
echo "char* __b2c__dec2hex(int);" >> $g_GENERIC
echo "char *__b2c__dirname(int, char*);" >> $g_GENERIC
echo "unsigned long __b2c__epoch(int, int, int, int, int, int);" >> $g_GENERIC
echo "char *__b2c__exec(char*, ...);" >> $g_GENERIC
echo "char * __b2c__extract (char*, ...);" >> $g_GENERIC
echo "long __b2c__filelen(const char*);" >> $g_GENERIC
echo "long __b2c__filetime(const char*, int);" >> $g_GENERIC
echo "long __b2c__filetype(const char*);" >> $g_GENERIC
echo "char* __b2c__fill(unsigned long, unsigned char);" >> $g_GENERIC
echo "long __b2c__getch(void);" >> $g_GENERIC
echo "char * __b2c__getenv(char*);" >> $g_GENERIC
echo "int __b2c__getopt(int, char**, char*);" >> $g_GENERIC
echo "char* __b2c__getpeer(int);" >> $g_GENERIC
echo "long __b2c__getxy(int);" >> $g_GENERIC
echo "long __b2c__hex2dec(char*);" >> $g_GENERIC
echo "char* __b2c__hostname(void);" >> $g_GENERIC
echo "long __b2c__instr(char*, ...);" >> $g_GENERIC
echo "long __b2c__instrrev (char*, ...);" >> $g_GENERIC
echo "char* __b2c__lcase(char*);" >> $g_GENERIC
echo "char* __b2c__left(char*, long);" >> $g_GENERIC
echo "int __b2c__makedir(char*);" >> $g_GENERIC
echo "int __b2c__memory__check(void*, int);" >> $g_GENERIC
echo "int __b2c__memory_err(void);" >> $g_GENERIC
echo "char* __b2c__mid(char*, ...); " >> $g_GENERIC
echo "char* __b2c__nethost(char*);" >> $g_GENERIC
echo "long __b2c__netpeek(int, int);" >> $g_GENERIC
echo "char* __b2c__os(void);" >> $g_GENERIC
echo "int __b2c__peek_check(void*, int);" >> $g_GENERIC
echo "long __b2c__regex(char*, char*);" >> $g_GENERIC
echo "char * __b2c__replace (char*, ...);" >> $g_GENERIC
echo "char* __b2c__reverse(char*);" >> $g_GENERIC
echo "char* __b2c__right(char*, long);" >> $g_GENERIC
echo "void __b2c__rmrecursive(char*);" >> $g_GENERIC
echo "long __b2c__screen(int);" >> $g_GENERIC
echo "long __b2c__search(FILE*, char*);" >> $g_GENERIC
echo "void __b2c__segv(int);" >> $g_GENERIC
echo "char* __b2c__spc(int);" >> $g_GENERIC
echo "char* __b2c__str(double);" >> $g_GENERIC
echo "char* __b2c__tab(int);" >> $g_GENERIC
echo "long __b2c__time(time_t, int);" >> $g_GENERIC
echo "unsigned long __b2c__timer(void);" >> $g_GENERIC
echo "char* __b2c__ucase(char*);" >> $g_GENERIC
echo "void __b2c__version(char*);" >> $g_GENERIC
echo "void* __b2c_Copy_String(char*,char*);" >> $g_GENERIC
echo "/* Internal macro definitions */" >> $g_GENERIC
echo "#define __b2c__MEMTYPE char" >> $g_GENERIC
if [[ -n $BASH ]]
then
    echo "#define COMPILED_BY_WHICH_BACON${g_STRINGSIGN} \"Shell Script BaCon $g_VERSION in BASH $BASH_VERSION\"" >> $g_GENERIC
elif [[ -n $ZSH_NAME ]]
then
    echo "#define COMPILED_BY_WHICH_BACON${g_STRINGSIGN} \"Shell Script BaCon $g_VERSION in ZSH $ZSH_VERSION\"" >> $g_GENERIC
else
    echo "#define COMPILED_BY_WHICH_BACON${g_STRINGSIGN} \"Shell Script BaCon $g_VERSION in KSH $KSH_VERSION\"" >> $g_GENERIC
fi
echo "#define RUNTIMEERROR(__b2c__a, __b2c__x, __b2c__y, __b2c__z) do {fprintf(stderr, \"Runtime error: statement '%s' at line %d in '%s': %s\n\", __b2c__a, __b2c__x, __b2c__y, ERR${g_STRINGSIGN}(__b2c__z)); exit(__b2c__z);} while(0)" >> $g_GENERIC
echo "#define RUNTIMEFERR(__b2c__y, __b2c__z) do {fprintf(stderr, \"Runtime error: function '%s': %s\n\", __b2c__y, ERR${g_STRINGSIGN}(__b2c__z)); exit(__b2c__z);} while(0)" >> $g_GENERIC

echo "/* BaCon functions */" >> $g_GENERIC
echo "#define ABS(__b2c__x) (((__b2c__x) < 0) ? -(__b2c__x) : (__b2c__x))" >> $g_GENERIC
echo "#define ACOS(__b2c__x) acos((double)__b2c__x)" >> $g_GENERIC
echo "#define ADDRESS(__b2c__x) (long)(&__b2c__x)" >> $g_GENERIC
echo "#define AND &&" >> $g_GENERIC
echo "#define ASC(__b2c__x) (unsigned char) *__b2c__x" >> $g_GENERIC
echo "#define ASIN(__b2c__x) asin((double)__b2c__x)" >> $g_GENERIC
echo "#define ATN(__b2c__x) atan((double)__b2c__x)" >> $g_GENERIC
echo "#define BASENAME${g_STRINGSIGN}(x) __b2c__dirname(1, x)" >> $g_GENERIC
echo "#define CEIL(x) (double)ceil(x)" >> $g_GENERIC
echo "#define CHOP${g_STRINGSIGN}(...) __b2c__chop(__VA_ARGS__, 0)" >> $g_GENERIC
echo "#define CHR${g_STRINGSIGN}(__b2c__x) __b2c__asc2char(__b2c__x)" >> $g_GENERIC
echo "#define CMDLINE(__b2c__x) __b2c__getopt(argc, argv, __b2c__x)" >> $g_GENERIC
echo "#define COLUMNS __b2c__screen(0)" >> $g_GENERIC
echo "#define CONCAT${g_STRINGSIGN}(...) __b2c__concat(__VA_ARGS__, (char*)NULL)" >> $g_GENERIC
echo "#define COS(__b2c__x) cos((double)__b2c__x)" >> $g_GENERIC
echo "#define COUNT(__b2c__x, __b2c__y) ((__b2c__x) != NULL ? __b2c__count(__b2c__x, __b2c__y) : 0)" >> $g_GENERIC
echo "#define CR${g_STRINGSIGN} \"\r\"" >> $g_GENERIC
echo "#define CURDIR${g_STRINGSIGN} __b2c__curdir()" >> $g_GENERIC
echo "#define DAY(x) __b2c__time(x, 1)" >> $g_GENERIC
echo "#define DEC(__b2c__x) __b2c__hex2dec(__b2c__x)" >> $g_GENERIC
echo "#define DEG(x) (x*180/PI)" >> $g_GENERIC
echo "#define DIRNAME${g_STRINGSIGN}(x) __b2c__dirname(2, x)" >> $g_GENERIC
echo "#define EL${g_STRINGSIGN} \"\033[0K\"" >> $g_GENERIC
echo "#define ENDFILE(__b2c__x) feof(__b2c__x)" >> $g_GENERIC
echo "#define EQ ==" >> $g_GENERIC
echo "#define EQUAL(__b2c__x, __b2c__y) ((__b2c__x) != NULL && (__b2c__y) != NULL && __b2c__option_compare == 0 ? !strcmp(__b2c__x, __b2c__y) : ((__b2c__x) != NULL && (__b2c__y) != NULL && __b2c__option_compare == 1 ? !strcasecmp(__b2c__x, __b2c__y) : 0) )" >> $g_GENERIC
echo "#define EVEN(__b2c__x) (((long)(__b2c__x) % 2 == 0) ? 1 : 0)" >> $g_GENERIC
echo "#define EXEC${g_STRINGSIGN}(...) __b2c__exec(__VA_ARGS__, (char*)NULL)" >> $g_GENERIC
echo "#define EXP(__b2c__x) exp((double)__b2c__x)" >> $g_GENERIC
echo "#define EXTRACT${g_STRINGSIGN}(...) __b2c__extract(__VA_ARGS__, -1)" >> $g_GENERIC
echo "#define FALSE 0" >> $g_GENERIC
echo "#define FILEEXISTS(__b2c__x) (__b2c__x != NULL ? !access(__b2c__x, F_OK) : 0)" >> $g_GENERIC
echo "#define FILELEN(__b2c__x) __b2c__filelen(__b2c__x)" >> $g_GENERIC
echo "#define FILETIME(__b2c__x, __b2c__y) __b2c__filetime(__b2c__x, __b2c__y)" >> $g_GENERIC
echo "#define FILETYPE(__b2c__x) __b2c__filetype(__b2c__x)" >> $g_GENERIC
echo "#define FILL${g_STRINGSIGN}(__b2c__x, __b2c__y) ((__b2c__y) >= 0 && (__b2c__y) < 256 ? __b2c__fill(__b2c__x, __b2c__y) : \"\")" >> $g_GENERIC
echo "#define FLOATING double" >> $g_GENERIC
echo "#define FLOOR(__b2c__x) (long)floor(__b2c__x)" >> $g_GENERIC
echo "#define FP(__b2c__x) (void*)(&__b2c__x)" >> $g_GENERIC
echo "#define GE >=" >> $g_GENERIC
echo "#define GETENVIRON${g_STRINGSIGN}(__b2c__x) ((__b2c__x) != NULL ? __b2c__getenv(__b2c__x) : \"null\")" >> $g_GENERIC
echo "#define GETKEY __b2c__getch()" >> $g_GENERIC
echo "#define GETPEER${g_STRINGSIGN}(__b2c__x) __b2c__getpeer(__b2c__x)" >> $g_GENERIC
echo "#define GETX __b2c__getxy(0)" >> $g_GENERIC
echo "#define GETY __b2c__getxy(1)" >> $g_GENERIC
echo "#define GT >" >> $g_GENERIC
echo "#define HEX${g_STRINGSIGN}(__b2c__x) __b2c__dec2hex(__b2c__x)" >> $g_GENERIC
echo "#define HOST${g_STRINGSIGN}(__b2c__x) __b2c__nethost(__b2c__x)" >> $g_GENERIC
echo "#define HOSTNAME${g_STRINGSIGN} __b2c__hostname()" >> $g_GENERIC
echo "#define HOUR(x) __b2c__time(x, 4)" >> $g_GENERIC
echo "#define IIF(x, y, z) (x ? y : z)" >> $g_GENERIC
echo "#define IIF${g_STRINGSIGN}(x, y, z) (x ? y : z)" >> $g_GENERIC
echo "#define INSTR(...) __b2c__instr(__VA_ARGS__, -1)" >> $g_GENERIC
echo "#define INSTRREV(...) __b2c__instrrev(__VA_ARGS__, -1)" >> $g_GENERIC
echo "#define INT(__b2c__x) lrint((double)__b2c__x)" >> $g_GENERIC
echo "#define IS ==" >> $g_GENERIC
echo "#define ISFALSE(__b2c__x) ((__b2c__x) == 0)" >> $g_GENERIC
echo "#define ISKEY(__b2c_x, ...) ( (__b2c__ ## __b2c_x ## __add_secure(0, __VA_ARGS__, NULL) == NULL) ? 0 : 1)" >> $g_GENERIC
echo "#define ISNOT !=" >> $g_GENERIC
echo "#define ISTRUE(__b2c__x) ((__b2c__x) != 0)" >> $g_GENERIC
echo "#define LCASE${g_STRINGSIGN}(__b2c__x) ((__b2c__x) != NULL ? __b2c__lcase(__b2c__x) : \"null\")" >> $g_GENERIC
echo "#define LE <=" >> $g_GENERIC
echo "#define LEFT${g_STRINGSIGN}(__b2c__x, __b2c__y) __b2c__left(__b2c__x, __b2c__y)" >> $g_GENERIC
echo "#define LEN(__b2c__x) ((__b2c__x) != NULL ? strlen(__b2c__x) : 0)" >> $g_GENERIC
echo "#define LOG(__b2c__x) log((double)__b2c__x)" >> $g_GENERIC
echo "#define LT <" >> $g_GENERIC
echo "#define MAXNUM(x) (x)POW(2, SIZEOF(x)*8)" >> $g_GENERIC
if [[ `uname` = +(*SunOS*|*OSF1*) ]]
then
    echo "#define MAXRANDOM 2147483647" >> $g_GENERIC
else
    echo "#define MAXRANDOM RAND_MAX" >> $g_GENERIC
fi
echo "#define MEMCHECK(__b2c__x) !(__b2c__memory__check((void*)__b2c__x, sizeof(__b2c__MEMTYPE)))" >> $g_GENERIC
echo "#define MEMORY(__b2c__x) (calloc(__b2c__x+__b2c__option_memstream, sizeof(__b2c__MEMTYPE)))" >> $g_GENERIC
echo "#define MEMTELL(__b2c__x) (long)__b2c__x" >> $g_GENERIC
echo "#define MID${g_STRINGSIGN}(__b2c__string, ...) __b2c__mid(__b2c__string, __VA_ARGS__, -1)" >> $g_GENERIC
echo "#define MINUTE(x) __b2c__time(x, 5)" >> $g_GENERIC
echo "#define MOD(__b2c__x, __b2c__y) ((long)(__b2c__x) % (long)(__b2c__y))" >> $g_GENERIC
echo "#define MONTH(x) __b2c__time(x, 2)" >> $g_GENERIC
echo "#define MONTH${g_STRINGSIGN}(x) __b2c__datename(x, 2)" >> $g_GENERIC
echo "#define NE !=" >> $g_GENERIC
echo "#define NL${g_STRINGSIGN} \"\n\"" >> $g_GENERIC
echo "#define NOT(__b2c__x) (!(__b2c__x))" >> $g_GENERIC
echo "#define NOW (long)time(NULL)" >> $g_GENERIC
echo "#define NUMBER long" >> $g_GENERIC
echo "#define ODD(__b2c__x) (((long)(__b2c__x) % 2 != 0) ? 1 : 0)" >> $g_GENERIC
echo "#define OR ||" >> $g_GENERIC
echo "#define OS${g_STRINGSIGN} __b2c__os()" >> $g_GENERIC
echo "#define PEEK(__b2c__x) (__b2c__peek_check((void*)__b2c__x, sizeof(__b2c__MEMTYPE)) == 0 ? *(__b2c__MEMTYPE *)(__b2c__x) : 0)" >> $g_GENERIC
echo "#define PI 3.14159265358979323846" >> $g_GENERIC
echo "#define POW(__b2c__x, __b2c__y) pow((double)__b2c__x, (double)__b2c__y)" >> $g_GENERIC
echo "#define RAD(x) (x*PI/180)" >> $g_GENERIC
echo "#define RANDOM(__b2c__x) ((__b2c__x) != 0 ? random()/(MAXRANDOM/(__b2c__x)) : 0)" >> $g_GENERIC
echo "#define REALPATH${g_STRINGSIGN}(x) __b2c__dirname(0, x)" >> $g_GENERIC
echo "#define REGEX(__b2c__x, __b2c__y) __b2c__regex(__b2c__x, __b2c__y)" >> $g_GENERIC
echo "#define REPLACE${g_STRINGSIGN}(...) __b2c__replace(__VA_ARGS__, -1)" >> $g_GENERIC
echo "#define REVERSE${g_STRINGSIGN}(__b2c__x) __b2c__reverse(__b2c__x)" >> $g_GENERIC
echo "#define RIGHT${g_STRINGSIGN}(__b2c__x, __b2c__y) __b2c__right(__b2c__x, __b2c__y)" >> $g_GENERIC
echo "#define RND random()" >> $g_GENERIC
echo "#define ROUND(__b2c__x) lrint((double)__b2c__x)" >> $g_GENERIC
echo "#define ROWS __b2c__screen(1)" >> $g_GENERIC
echo "#define SEARCH(__b2c__x, __b2c__y) __b2c__search(__b2c__x, __b2c__y)" >> $g_GENERIC
echo "#define SECOND(x) __b2c__time(x, 6)" >> $g_GENERIC
echo "#define SETENVIRON(__b2c__x, __b2c__y) if((__b2c__x) != NULL && (__b2c__y) != NULL) setenv(__b2c__x, __b2c__y, 1)" >> $g_GENERIC
echo "#define SGN(__b2c__x) ((__b2c__x) == 0 ? 0 : ((__b2c__x) < 0 ? -1 : 1))" >> $g_GENERIC
echo "#define SIN(__b2c__x) sin((double)__b2c__x)" >> $g_GENERIC
echo "#define SIZEOF(__b2c__x) sizeof(__b2c__x)" >> $g_GENERIC
echo "#define SPC${g_STRINGSIGN}(__b2c__x) ((__b2c__x) >= 0 ? __b2c__spc(__b2c__x) : \"\")" >> $g_GENERIC
echo "#define SQR(__b2c__x) sqrt((double)__b2c__x)" >> $g_GENERIC
echo "#define STR${g_STRINGSIGN}(__b2c__x) __b2c__str(__b2c__x)" >> $g_GENERIC
echo "#define STRING char*" >> $g_GENERIC
echo "#define SYSTEM(__b2c__x) do {if (__b2c__x != NULL) {RETVAL = system(__b2c__x); if(WIFEXITED(RETVAL)) RETVAL = WEXITSTATUS(RETVAL);} else RETVAL=0;} while(0)" >> $g_GENERIC
echo "#define TAB${g_STRINGSIGN}(__b2c__x) ((__b2c__x) >= 0 ? __b2c__tab(__b2c__x) : \"\")" >> $g_GENERIC
echo "#define TAN(__b2c__x) tan((double)__b2c__x)" >> $g_GENERIC
echo "#define TELL(__b2c__x) ftell(__b2c__x)" >> $g_GENERIC
echo "#define TIMER __b2c__timer()" >> $g_GENERIC
echo "#define TIMEVALUE(x,y,z,a,b,c) __b2c__epoch(x,y,z,a,b,c)" >> $g_GENERIC
echo "#define TRUE 1" >> $g_GENERIC
echo "#define UCASE${g_STRINGSIGN}(__b2c__x) ((__b2c__x) != NULL ? __b2c__ucase(__b2c__x) : \"null\")" >> $g_GENERIC
echo "#define VAL(__b2c__x) ((__b2c__x) != NULL ? atof(__b2c__x) : 0)" >> $g_GENERIC
echo "#define WAIT(__b2c__x, __b2c__y) __b2c__netpeek(__b2c__x, __b2c__y)" >> $g_GENERIC
echo "#define WEEK(x) __b2c__time(x, 7)" >> $g_GENERIC
echo "#define WEEKDAY${g_STRINGSIGN}(x) __b2c__datename(x, 1)" >> $g_GENERIC
echo "#define YEAR(x) __b2c__time(x, 3)" >> $g_GENERIC

# Generate functions
if [[ -n ${g_REBUILD_ARCHIVE} ]]
then
    g_CTEMP="$g_TEMPDIR/bacon.chop.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char* __b2c__chop (char *source, ...) { char *tmp, *string; long i, length, idx, location = 0; va_list ap; if (source == NULL || strlen (source) == 0) return (source);" >> $g_CTEMP
    echo "va_start (ap, source); string = va_arg (ap, char*); if (string == 0) string = (char *) __b2c__chop_default; else location = va_arg (ap, int); va_end (ap); length = strlen(string);" >> $g_CTEMP
    echo "if (location == 0 || location == 1) { while (*source != '\0') { for (i = 0; i < length; i++) { if (*source == *(string + i)) { source++; break; } } if (i == length) break; }" >> $g_CTEMP
    echo "if (*source == '\0') return (EmptyString); } tmp = source + strlen (source) - 1; if (location == 0 || location == 2) { while (tmp >= source && *tmp != '\0') { for (i = 0; i < length; i++){" >> $g_CTEMP
    echo "if (*tmp == *(string + i)) { tmp--; break; } } if (i == length) break; } } idx = __sbuf_malloc_handle((strlen(source) + 1) * sizeof (char));" >> $g_CTEMP
    echo "for (i = 0; i <= tmp - source; i++) __b2c__sbuffer[idx][i] = source[i]; __b2c__sbuffer[idx][i] = '\0'; return (char*)(__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.chop.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.chop.o: bacon.chop.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.chop.c"

    g_CTEMP="$g_TEMPDIR/bacon.chr.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__asc2char (int i) {long idx; idx = __sbuf_malloc_handle (2 * sizeof (char)); snprintf (__b2c__sbuffer[idx], 2, \"%c\", i); return (char*)(__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.chr.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.chr.o: bacon.chr.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.chr.c"

    g_CTEMP="$g_TEMPDIR/bacon.cmdline.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "int __b2c__getopt(int argc, char **argv, char* __b2c__str){int __b2c_opt; opterr = 0; __b2c_opt = getopt(argc, argv, __b2c__str); free(ARGUMENT${g_STRINGSIGN});" >> $g_CTEMP
    echo "if(__b2c_opt != -1) ARGUMENT${g_STRINGSIGN} = __b2c__strdup(optarg); else ARGUMENT${g_STRINGSIGN} = argv[optind]; return(__b2c_opt);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.cmdline.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.cmdline.o: bacon.cmdline.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.cmdline.c"

    g_CTEMP="$g_TEMPDIR/bacon.concat.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__concat (char *first, ...) {long length=0, new, idx; char *next; va_list ap; if (first != NULL && (length = strlen (first)) > 0) {idx = __sbuf_malloc_handle (length * sizeof (char));" >> $g_CTEMP
    echo "memcpy (__b2c__sbuffer[idx], first, (length + 1)* sizeof (char));} else { idx = __sbuf_malloc_handle (sizeof (char)); __b2c__sbuffer[idx][0] = '\0'; } va_start (ap, first);" >> $g_CTEMP
    echo " while ((next = va_arg (ap, char *)) != NULL) { new = strlen (next); __sbuf_need_realloc (idx, (length + new + 1) * sizeof (char));" >> $g_CTEMP
    echo "memcpy (__b2c__sbuffer[idx] + length * sizeof (char), next, new * sizeof (char)); length += new; } va_end (ap); __b2c__sbuffer[idx][length] = '\0'; return (char*)(__b2c__sbuffer[idx]);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.concat.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.concat.o: bacon.concat.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.concat.c"

    g_CTEMP="$g_TEMPDIR/bacon.count.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__count(char* __b2c_x, unsigned char __b2c_y){int __b2c_i, __b2c_z = 0; for(__b2c_i = 0; __b2c_x[__b2c_i] != '\0'; __b2c_i++) if(__b2c_x[__b2c_i] == __b2c_y) __b2c_z++; return __b2c_z;}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.count.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.count.o: bacon.count.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.count.c"

    g_CTEMP="$g_TEMPDIR/bacon.curdir.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__curdir (void) { long idx; idx = __sbuf_malloc_handle (${g_BUFFER_SIZE} * sizeof (char)); __b2c__sbuffer[idx] = getcwd (__b2c__sbuffer[idx], ${g_BUFFER_SIZE});" >> $g_CTEMP
    echo "__b2c__sbuffer[idx][${g_BUFFER_SIZE}-1] = '\0'; return (char*)(__b2c__sbuffer[idx]);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.curdir.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.curdir.o: bacon.curdir.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.curdir.c"

    g_CTEMP="$g_TEMPDIR/bacon.datename.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__datename (time_t now, int which) { struct tm *ts; long idx; idx = __sbuf_malloc_handle (${g_MAX_DIGITS} * sizeof (char)); ts = localtime (&now);" >> $g_CTEMP
    echo "switch (which) { case 1: strftime (__b2c__sbuffer[idx], ${g_MAX_DIGITS}, \"%A\", ts); break; case 2: strftime (__b2c__sbuffer[idx], ${g_MAX_DIGITS}, \"%B\", ts);" >> $g_CTEMP
    echo "break; } __b2c__sbuffer[idx][${g_MAX_DIGITS}-1] = '\0'; return (char*)(__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.datename.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.datename.o: bacon.datename.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.datename.c"

    g_CTEMP="$g_TEMPDIR/bacon.dec.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__hex2dec(char *__b2c__h){unsigned int __b2c__i; if(sscanf(__b2c__h, \"%X\", &__b2c__i) == EOF && __b2c__trap){ERROR = 5;" >> $g_CTEMP
    echo "RUNTIMEFERR(\"DEC\", ERROR);} return(long)(__b2c__i);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.dec.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.dec.o: bacon.dec.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.dec.c"

    g_CTEMP="$g_TEMPDIR/bacon.dirname.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "#ifndef PATH_MAX" >> $g_CTEMP
    echo "#define PATH_MAX 4096" >> $g_CTEMP
    echo "#endif" >> $g_CTEMP
    echo "char *__b2c__dirname(int x, char *y) {long idx; char *dup; idx = __sbuf_malloc_handle (PATH_MAX * sizeof (char)); dup = strdup(y); switch(x)" >> $g_CTEMP
    echo "{case 0: if ((realpath(y, __b2c__sbuffer[idx])) == NULL) { if (__b2c__trap) { ERROR = 26; RUNTIMEFERR (\"REALPATH$\", ERROR);}" >> $g_CTEMP
    echo "else strncpy (__b2c__sbuffer[idx], \"Error getting real path\", ${g_BUFFER_SIZE}); } break; case 1: if(strncpy(__b2c__sbuffer[idx], basename(dup), PATH_MAX) == NULL)" >> $g_CTEMP
    echo "{if (__b2c__trap) { ERROR = 26; RUNTIMEFERR (\"BASENAME$\", ERROR); } else strncpy (__b2c__sbuffer[idx], \"Error getting basename\", ${g_BUFFER_SIZE});}" >> $g_CTEMP
    echo "break; case 2: if (strncpy(__b2c__sbuffer[idx], dirname(dup), PATH_MAX) == NULL) {if(__b2c__trap) { ERROR = 26; RUNTIMEFERR (\"DIRNAME$\", ERROR); } else" >> $g_CTEMP
    echo "strncpy (__b2c__sbuffer[idx], \"Error getting dirname\", ${g_BUFFER_SIZE}); } break;} free(dup); __b2c__sbuffer[idx][PATH_MAX - 1] = '\0'; return (char *) (__b2c__sbuffer[idx]);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.dirname.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.dirname.o: bacon.dirname.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.dirname.c"

    g_CTEMP="$g_TEMPDIR/bacon.epoch.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "unsigned long __b2c__epoch(int __b2c__year, int __b2c__month, int __b2c__day, int __b2c__hour, int __b2c__minute, int __b2c__second){" >> $g_CTEMP
    echo "struct tm tm; time_t __b2c__t; tm.tm_year = __b2c__year - 1900; tm.tm_mon = __b2c__month - 1; tm.tm_mday = __b2c__day;" >> $g_CTEMP
    echo "tm.tm_hour = __b2c__hour; tm.tm_min = __b2c__minute; tm.tm_sec = __b2c__second;" >> $g_CTEMP
    echo "tm.tm_isdst = -1; __b2c__t = mktime(&tm); if (__b2c__t == -1) return (0); return(long) __b2c__t; }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.epoch.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.epoch.o: bacon.epoch.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.epoch.c"

    g_CTEMP="$g_TEMPDIR/bacon.error.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char *ERR${g_STRINGSIGN}(int __b2c__nr){" >> $g_CTEMP
    echo "switch(__b2c__nr){" >> $g_CTEMP
    echo "case 0: strcpy(__b2c__warn, \"Success\"); break;" >> $g_CTEMP
    echo "case 1: strcpy(__b2c__warn, \"Trying to access illegal memory: \"); strncat(__b2c__warn,strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 2: strcpy(__b2c__warn, \"Error opening file: \"); strncat(__b2c__warn,strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 3: strcpy(__b2c__warn, \"Could not open library.\"); break;" >> $g_CTEMP
    echo "case 4: strcpy(__b2c__warn, \"Symbol not found in library.\"); break;" >> $g_CTEMP
    echo "case 5: strcpy(__b2c__warn, \"Wrong hexvalue: \"); strncat(__b2c__warn, strerror(errno), $g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 6: strcpy(__b2c__warn, \"Unable to claim memory.\"); break;" >> $g_CTEMP
    echo "case 7: strcpy(__b2c__warn, \"Unable to delete file: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 8: strcpy(__b2c__warn, \"Could not open directory: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 9: strcpy(__b2c__warn, \"Unable to rename file: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 10: strcpy(__b2c__warn, \"NETWORK argument should contain colon with port number\"); break;" >> $g_CTEMP
    echo "case 11: strcpy(__b2c__warn, \"Could not resolve hostname!\"); break;" >> $g_CTEMP
    echo "case 12: strcpy(__b2c__warn, \"Socket error: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 13: strcpy(__b2c__warn, \"Unable to open address: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 14: strcpy(__b2c__warn, \"Error reading from socket: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 15: strcpy(__b2c__warn, \"Error sending to socket: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 16: strcpy(__b2c__warn, \"Error checking socket: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 17: strcpy(__b2c__warn, \"Unable to bind the specified socket address: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 18: strcpy(__b2c__warn, \"Unable to listen to socket address: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 19: strcpy(__b2c__warn, \"Cannot accept incoming connection: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 20: strcpy(__b2c__warn, \"Unable to remove directory: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 21: strcpy(__b2c__warn, \"Unable to create directory: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 22: strcpy(__b2c__warn, \"Unable to change to directory: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 23: strcpy(__b2c__warn, \"GETENVIRON argument does not exist as environment variable\"); break;" >> $g_CTEMP
    echo "case 24: strcpy(__b2c__warn, \"Unable to stat file: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 25: strcpy(__b2c__warn, \"Search contains illegal string\"); break;" >> $g_CTEMP
    echo "case 26: strcpy(__b2c__warn, \"Cannot return name: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 27: strcpy(__b2c__warn, \"Illegal regex expression\"); break;" >> $g_CTEMP
    echo "case 28: strcpy(__b2c__warn, \"Unable to create bidirectional pipes: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 29: strcpy(__b2c__warn, \"Unable to fork process: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 30: strcpy(__b2c__warn, \"Cannot read from pipe: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 31: strcpy(__b2c__warn, \"Gosub nesting too deep!\"); break;" >> $g_CTEMP
    echo "case 32: strcpy(__b2c__warn, \"Could not open device: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 33: strcpy(__b2c__warn, \"Error configuring serial port: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 34: strcpy(__b2c__warn, \"Error accessing device: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "case 35: strcpy(__b2c__warn, \"Error in INPUT: \"); strncat(__b2c__warn, strerror(errno),$g_BUFFER_SIZE-48); break;" >> $g_CTEMP
    echo "}; ERROR = 0; return(__b2c__warn);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.error.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.error.o: bacon.error.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.error.c"

    g_CTEMP="$g_TEMPDIR/bacon.exec.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__exec (char *cmd, ...) { int forking, length, result; int wpipe[2], rpipe[2]; char *str, *ans = NULL; long idx; va_list ap; va_start (ap, cmd); str = va_arg (ap, char*); va_end (ap);" >> $g_CTEMP
    echo "idx = __sbuf_malloc_handle (sizeof (char)); if (pipe (rpipe) < 0 || pipe (wpipe) < 0) { if (__b2c__trap) { ERROR = 29; RUNTIMEFERR (\"EXEC$\", ERROR); } } if ((forking = fork ()) < 0) { if (__b2c__trap) { ERROR = 29; RUNTIMEFERR (\"EXEC$\", ERROR); } }" >> $g_CTEMP
    echo "else if (forking == 0) { fflush(stdout); close (wpipe[1]); close (rpipe[0]); dup2 (wpipe[0], STDIN_FILENO); close (wpipe[0]); dup2 (rpipe[1], STDOUT_FILENO); close (rpipe[1]); forking = system (cmd); if (WIFEXITED (forking))" >> $g_CTEMP
    echo "result = WEXITSTATUS (forking); else result = 0; exit (result); } else { close (wpipe[0]); close (rpipe[1]); ans = (char*)malloc(${g_BUFFER_SIZE} * sizeof(char));" >> $g_CTEMP
    echo "length = 0; if (str != NULL) result = write (wpipe[1], str, strlen (str) + 1); do { result = read (rpipe[0], ans, ${g_BUFFER_SIZE}); if (result == -1 && __b2c__trap) { ERROR = 30; RUNTIMEFERR (\"EXEC$\", ERROR);}" >> $g_CTEMP
    echo "if (result == 0) break; __sbuf_need_realloc (idx, (length + result + 1) * sizeof (char)); if (__b2c__sbuffer[idx] == NULL && __b2c__trap) { ERROR = 6; RUNTIMEFERR (\"EXEC$\", ERROR); }" >> $g_CTEMP
    echo "memcpy(__b2c__sbuffer[idx] + length * sizeof(char), ans, result * sizeof(char)); length += result; } while (result > 0); __b2c__sbuffer[idx][length] = '\0'; close (wpipe[1]); close (rpipe[0]); free (ans);" >> $g_CTEMP
    echo "wait (&RETVAL); RETVAL = WEXITSTATUS (RETVAL); } return (char*)(__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.exec.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.exec.o: bacon.exec.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.exec.c"

    g_CTEMP="$g_TEMPDIR/bacon.extract.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__extract (char *src, ...) {int reti, flag, pos = 0; char *needle, *tmp; regex_t regex; char __b2c__buf[100]; regmatch_t where[1]; long idx; va_list __b2c__ap;" >> $g_CTEMP
    echo "va_start (__b2c__ap, src); needle = va_arg (__b2c__ap, char*); flag = va_arg (__b2c__ap, int); va_end (__b2c__ap); if (src == NULL || needle == NULL) return (char*)(src);" >> $g_CTEMP
    echo "if (strlen (src) == 0 || strlen (needle) == 0) return (char*)(src); idx = __sbuf_malloc_handle((strlen (src) + 1) * sizeof(char)); if (flag > 0) { if (__b2c__option_compare == 0)" >> $g_CTEMP
    echo "reti = regcomp (&regex, needle, REG_EXTENDED); else reti = regcomp (&regex, needle, REG_EXTENDED | REG_ICASE); if (__b2c__trap && reti) { ERROR = 27; regerror (reti, &regex, __b2c__buf, sizeof (__b2c__buf));" >> $g_CTEMP
    echo "fprintf (stderr, \"%s\n\", __b2c__buf); RUNTIMEFERR (\"EXTRACT$\", ERROR); } while ((reti = regexec (&regex, src, 1, where, 0)) == 0) { memcpy (__b2c__sbuffer[idx] + pos * sizeof (char), src, (size_t)where[0].rm_so * sizeof (char));" >> $g_CTEMP
    echo "pos += where[0].rm_so; src += (long)where[0].rm_eo; } regfree (&regex); memcpy (__b2c__sbuffer[idx] + pos * sizeof (char), src, strlen (src) * sizeof (char)); pos += strlen (src); }" >> $g_CTEMP
    echo "else { while ((tmp = strstr (src, needle)) != NULL) { __sbuf_need_realloc (idx, (pos + (tmp - src) + 1) * sizeof (char)); memcpy (__b2c__sbuffer[idx] + pos * sizeof (char), src, (size_t) (tmp - src) * sizeof (char));" >> $g_CTEMP
    echo "pos += tmp - src; src = tmp + strlen (needle) * sizeof (char); } __sbuf_need_realloc (idx, (pos + strlen (src) + 1) * sizeof (char)); memcpy (__b2c__sbuffer[idx] + pos * sizeof (char), src, strlen (src) * sizeof (char));" >> $g_CTEMP
    echo "pos += strlen (src); } __b2c__sbuffer[idx][pos] = '\0'; return (char*)(__b2c__sbuffer[idx]);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.extract.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.extract.o: bacon.extract.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.extract.c"

    g_CTEMP="$g_TEMPDIR/bacon.filelen.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__filelen(const char *__b2c__x) {struct stat __b2c__buf; if(stat(__b2c__x, &__b2c__buf) < 0 && __b2c__trap){ERROR = 24; RUNTIMEFERR(\"FILELEN\", ERROR);}" >> $g_CTEMP
    echo "if(__b2c__x == NULL || stat(__b2c__x, &__b2c__buf) < 0) return -1; else return(long)(__b2c__buf.st_size);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.filelen.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.filelen.o: bacon.filelen.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.filelen.c"

    g_CTEMP="$g_TEMPDIR/bacon.filetime.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__filetime(const char *__b2c__x, int __b2c__y) {struct stat __b2c__buf; if(stat(__b2c__x, &__b2c__buf) < 0 && __b2c__trap){ERROR = 24; RUNTIMEFERR(\"FILETIME\", ERROR);}" >> $g_CTEMP
    echo "if(__b2c__x == NULL || stat(__b2c__x, &__b2c__buf) < 0 || __b2c__y < 0 || __b2c__y > 2) return -1; switch(__b2c__y) {case 0: return(long)(__b2c__buf.st_atime); break;" >> $g_CTEMP
    echo "case 1: return(long)(__b2c__buf.st_mtime); break;} return(long)(__b2c__buf.st_ctime);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.filetime.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.filetime.o: bacon.filetime.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.filetime.c"

    g_CTEMP="$g_TEMPDIR/bacon.filetype.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__filetype(const char *__b2c__x) {long __b2c_fs = 0; struct stat __b2c__buf; if(__b2c__x == NULL) return 0; if(lstat(__b2c__x, &__b2c__buf) < 0 && __b2c__trap)" >> $g_CTEMP
    echo "{ERROR = 24; RUNTIMEFERR(\"FILETYPE\", ERROR);}" >> $g_CTEMP
    echo "if (S_ISREG(__b2c__buf.st_mode)) __b2c_fs = 1; if (S_ISDIR(__b2c__buf.st_mode)) __b2c_fs = 2;" >> $g_CTEMP
    echo "if (S_ISCHR(__b2c__buf.st_mode)) __b2c_fs = 3; if (S_ISBLK(__b2c__buf.st_mode)) __b2c_fs = 4; if (S_ISFIFO(__b2c__buf.st_mode)) __b2c_fs = 5;" >> $g_CTEMP
    echo "if (S_ISLNK(__b2c__buf.st_mode)) __b2c_fs = 6; if (S_ISSOCK(__b2c__buf.st_mode)) __b2c_fs = 7; return __b2c_fs;}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.filetype.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.filetype.o: bacon.filetype.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.filetype.c"

    g_CTEMP="$g_TEMPDIR/bacon.fill.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__fill (unsigned long amount, unsigned char txt) { long idx; idx = __sbuf_malloc_handle ((amount + 1) * sizeof (char));" >> $g_CTEMP
    echo "memset (__b2c__sbuffer[idx], txt, amount); __b2c__sbuffer[idx][amount] = '\0'; return (char*)(__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.fill.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.fill.o: bacon.fill.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.fill.c"

    g_CTEMP="$g_TEMPDIR/bacon.getenviron.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__getenv (char *env) {char *tmp; long idx; idx = __sbuf_malloc_handle (${g_BUFFER_SIZE} * sizeof (char)); tmp = getenv (env); if (tmp == NULL) return (EmptyString);" >> $g_CTEMP
    echo "else strncpy (__b2c__sbuffer[idx], tmp, ${g_BUFFER_SIZE}); __b2c__sbuffer[idx][$g_BUFFER_SIZE - 1] = '\0'; return (char*)(__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.getenviron.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.getenviron.o: bacon.getenviron.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.getenviron.c"

    g_CTEMP="$g_TEMPDIR/bacon.getkey.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__getch(){long __b2c__ch; struct termios __b2c__oldt, __b2c__newt; tcgetattr(STDIN_FILENO, &__b2c__oldt);" >> $g_CTEMP
    echo "__b2c__newt = __b2c__oldt; __b2c__newt.c_lflag &= ~(ICANON | ECHO); __b2c__newt.c_cc[VMIN]=1; __b2c__newt.c_cc[VTIME]=0; tcsetattr(STDIN_FILENO, TCSANOW, &__b2c__newt);" >> $g_CTEMP
    echo "__b2c__ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &__b2c__oldt); return __b2c__ch;} " >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.getkey.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.getkey.o: bacon.getkey.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.getkey.c"

    if [[ `uname` = "OSF1" ]]
    then
        LEN="int"
    else
        LEN="unsigned int"
    fi
    g_CTEMP="$g_TEMPDIR/bacon.getpeer.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__getpeer (int remote) { struct sockaddr_in *peer; ${LEN} length = sizeof (peer); char port[6]; long idx; idx = __sbuf_malloc_handle (${g_BUFFER_SIZE} * sizeof (char)); peer = calloc (1, sizeof (*peer));" >> $g_CTEMP
    echo "if (getpeername (remote, (struct sockaddr *) peer, &length) < 0) { if (__b2c__trap) { ERROR = 16; RUNTIMEFERR (\"GETPEER$\", ERROR); } else strncpy (__b2c__sbuffer[idx], \"Peer not found\", ${g_BUFFER_SIZE}); }" >> $g_CTEMP
    echo "else { strncpy (__b2c__sbuffer[idx], inet_ntoa (peer->sin_addr),  ${g_BUFFER_SIZE} - 7); strcat (__b2c__sbuffer[idx], \":\"); snprintf (port, 6, \"%d\", ntohs (peer->sin_port)); strcat (__b2c__sbuffer[idx], port); }" >> $g_CTEMP
    echo "free (peer); __b2c__sbuffer[idx][ ${g_BUFFER_SIZE} - 1] = '\0'; return (char*)(__b2c__sbuffer[idx]);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.getpeer.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.getpeer.o: bacon.getpeer.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.getpeer.c"

    g_CTEMP="$g_TEMPDIR/bacon.getxy.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__getxy(int __b2c__type){char __b2c__asw[$g_BUFFER_SIZE]; struct termios __b2c__old, __b2c__new; int __b2c__len, __b2c__x = 0, __b2c__y = 0;" >> $g_CTEMP
    echo "tcgetattr(STDIN_FILENO, &__b2c__old); __b2c__new = __b2c__old;__b2c__new.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &__b2c__new);" >> $g_CTEMP
    echo "if(write(STDOUT_FILENO, \"\033[6n\", strlen(\"\033[6n\"))>=0){__b2c__len = read(STDIN_FILENO, __b2c__asw, $g_BUFFER_SIZE);__b2c__asw[__b2c__len] = '\0'; " >> $g_CTEMP
    echo "tcsetattr(STDIN_FILENO, TCSANOW, &__b2c__old); sscanf(__b2c__asw, \"\033[%d;%dR\", &__b2c__y, &__b2c__x);} if (!__b2c__type) return(long)__b2c__x; return(long)__b2c__y;}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.getxy.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.getxy.o: bacon.getxy.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.getxy.c"

    g_CTEMP="$g_TEMPDIR/bacon.hex.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__dec2hex (int nr) { long idx; idx = __sbuf_malloc_handle (${g_MAX_DIGITS} * sizeof (char)); snprintf (__b2c__sbuffer[idx], ${g_MAX_DIGITS}, \"%X\", nr);" >> $g_CTEMP
    echo "__b2c__sbuffer[idx][${g_MAX_DIGITS} - 1] = '\0'; return (char*)(__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.hex.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.hex.o: bacon.hex.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.hex.c"

    g_CTEMP="$g_TEMPDIR/bacon.host.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__nethost (char *host) {int y, flag = 0; struct in_addr address; struct sockaddr_in *addrin; struct hostent *he = NULL; long idx; idx = __sbuf_malloc_handle (${g_BUFFER_SIZE} * sizeof (char));" >> $g_CTEMP
    echo "for(y = 0; host[y] != '\0'; y++) { if(isalpha (*(host + y))) { flag = 1; break; } } if(flag) he = gethostbyname (host); else { if(inet_aton (host, &address)) he = gethostbyaddr ((void *)&address, sizeof(struct in_addr), AF_INET); }" >> $g_CTEMP
    echo "if(he == NULL || he->h_addr == NULL || he->h_name == NULL) { if(__b2c__trap) { ERROR = 11; RUNTIMEFERR (\"HOST$\", ERROR); } else strncpy(__b2c__sbuffer[idx], \"Host not found\", ${g_BUFFER_SIZE}); } else { if (flag)" >> $g_CTEMP
    echo "{ addrin = calloc (1, sizeof (*addrin)); addrin->sin_addr = *((struct in_addr *) he->h_addr); strncpy(__b2c__sbuffer[idx], inet_ntoa (addrin->sin_addr), ${g_BUFFER_SIZE}); free (addrin); } else strncpy(__b2c__sbuffer[idx], he->h_name, ${g_BUFFER_SIZE}); }" >> $g_CTEMP
    echo "__b2c__sbuffer[idx][${g_BUFFER_SIZE} - 1] = '\0'; return (char*)(__b2c__sbuffer[idx]);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.host.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.host.o: bacon.host.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.host.c"

    g_CTEMP="$g_TEMPDIR/bacon.hostname.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__hostname (void) { long idx; idx = __sbuf_malloc_handle (${g_BUFFER_SIZE} * sizeof (char)); if(gethostname(__b2c__sbuffer[idx], ${g_BUFFER_SIZE}))" >> $g_CTEMP
    echo "{ if (__b2c__trap) { ERROR = 26; RUNTIMEFERR (\"HOSTNAME$\", ERROR); } else strncpy (__b2c__sbuffer[idx], \"Error getting hostname\", ${g_BUFFER_SIZE}); } __b2c__sbuffer[idx][${g_BUFFER_SIZE}-1] = '\0'; return (char*)(__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.hostname.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.hostname.o: bacon.hostname.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.hostname.c"

    g_CTEMP="$g_TEMPDIR/bacon.instr.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__instr(char *__b2c__first, ...){char *__b2c__tmp, *__b2c__res; int __b2c__pos; va_list __b2c__ap; if(__b2c__first == NULL) return (0); va_start(__b2c__ap, __b2c__first);" >> $g_CTEMP
    echo "__b2c__tmp = va_arg(__b2c__ap, char *); if(__b2c__tmp == NULL) return (0);__b2c__pos = va_arg(__b2c__ap, int);" >> $g_CTEMP
    echo "if(__b2c__pos <= 0) __b2c__pos = 1; va_end(__b2c__ap); __b2c__res = strstr(__b2c__first + __b2c__pos - 1, __b2c__tmp);" >> $g_CTEMP
    echo "if(__b2c__res == NULL) return (0); return (long)(__b2c__res - __b2c__first + 1);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.instr.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.instr.o: bacon.instr.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.instr.c"

    g_CTEMP="$g_TEMPDIR/bacon.instrrev.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__instrrev (char *__b2c__first, ...){char *__b2c__tmp, *__b2c__res = NULL,  *__b2c__found = NULL; long __b2c__pos, __b2c__l; va_list __b2c__ap;if (__b2c__first == NULL) return (0);" >> $g_CTEMP
    echo "va_start (__b2c__ap, __b2c__first); __b2c__tmp = va_arg (__b2c__ap, char *); if (__b2c__tmp == NULL) return (0); __b2c__pos = va_arg (__b2c__ap, int); if (__b2c__pos < 0) __b2c__pos = 0;" >> $g_CTEMP
    echo "va_end (__b2c__ap); __b2c__l = strlen(__b2c__first); __b2c__found = __b2c__first; do {__b2c__res = strstr (__b2c__found, __b2c__tmp); if(__b2c__res != NULL && __b2c__res <= __b2c__first + __b2c__l - __b2c__pos)" >> $g_CTEMP
    echo "{__b2c__found = __b2c__res + 1; continue;}if(__b2c__res > __b2c__first + __b2c__l - __b2c__pos) __b2c__res = NULL;} while (__b2c__res != NULL); if (__b2c__option_startpoint){if(__b2c__l - (__b2c__found - __b2c__first)+1 > __b2c__l) return 0;" >> $g_CTEMP
    echo "return (long)(__b2c__l - (__b2c__found - __b2c__first)+1);} return (long)(__b2c__found - __b2c__first);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.instrrev.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.instrrev.o: bacon.instrrev.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.instrrev.c"

    g_CTEMP="$g_TEMPDIR/bacon.lcase.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__lcase (char *src) {long i, idx; idx = __sbuf_malloc_handle ((strlen (src) + 1) * sizeof (char)); for (i = 0; src[i] != '\0'; i++)" >> $g_CTEMP
    echo "{ __b2c__sbuffer[idx][i] = tolower(src[i]); } __b2c__sbuffer[idx][i] = '\0'; return (char *) (__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.lcase.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.lcase.o: bacon.lcase.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.lcase.c"

    g_CTEMP="$g_TEMPDIR/bacon.left.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__left (char *src, long n) { long length, idx; if (src != NULL) length = strlen (src); if (src == NULL || n > length || n < 0) return (src); idx = __sbuf_malloc_handle( (n + 1) * sizeof (char) );" >> $g_CTEMP
    echo "memcpy (__b2c__sbuffer[idx], src, n * sizeof (char)); __b2c__sbuffer[idx][n] = '\0'; return (char *)(__b2c__sbuffer[idx]);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.left.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.left.o: bacon.left.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.left.c"

    g_CTEMP="$g_TEMPDIR/bacon.makedir.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "int __b2c__makedir(char* __b2c__in){char *__b2c__i, *__b2c__dir; if(__b2c__in == NULL || strlen(__b2c__in)==0) return 0; if(*__b2c__in != '/'){__b2c__dir = calloc(strlen(__b2c__in)+3, sizeof (char));" >> $g_CTEMP
    echo "strncpy(__b2c__dir, \"./\", 2); __b2c__dir = strcat(__b2c__dir, __b2c__in);} else __b2c__dir = __b2c__strdup(__b2c__in); __b2c__i = __b2c__dir; do { __b2c__i++; while(*__b2c__i != '/' && *__b2c__i != '\0') __b2c__i++;" >> $g_CTEMP
    echo "if(*__b2c__i == '/') {*__b2c__i = '\0'; mkdir(__b2c__dir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); *__b2c__i = '/';} else if (*__b2c__i == '\0') mkdir(__b2c__dir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);" >> $g_CTEMP
    echo "if(errno != EEXIST && errno != 0) {free(__b2c__dir); return errno;} } while (*__b2c__i != '\0'); free(__b2c__dir); return 0;}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.makedir.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.makedir.o: bacon.makedir.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.makedir.c"

    g_CTEMP="$g_TEMPDIR/bacon.malloc.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "void *__rbuf_realloc(void *__b2c__ptr, size_t __b2c__size){if(__b2c__rbuffer_length[__b2c__rbuffer_ptr] < __b2c__size)" >> $g_CTEMP
    echo "{__b2c__rbuffer_length[__b2c__rbuffer_ptr] = (size_t)__b2c__size*8; return(realloc(__b2c__ptr, __b2c__rbuffer_length[__b2c__rbuffer_ptr]));} return(__b2c__ptr);}" >> $g_CTEMP
    echo "void __sbuf_need_realloc (long idx, size_t size) { if (__b2c__sbuffer_length[idx] <= size) { __b2c__sbuffer_length[idx] = (size_t)size * 4;" >> $g_CTEMP
    echo "__b2c__sbuffer[idx] = realloc (__b2c__sbuffer[idx], __b2c__sbuffer_length[idx]);} }" >> $g_CTEMP
    echo "long __sbuf_malloc_handle (size_t size) {__b2c__sbuffer_ptr++; if(__b2c__sbuffer_ptr>=__b2c__sbuffer_size) __b2c__sbuffer_ptr=0; __sbuf_need_realloc (__b2c__sbuffer_ptr, size); return(__b2c__sbuffer_ptr); }" >> $g_CTEMP
    echo "char *__b2c__strdup(const char *__b2c__s){if(__b2c__s == NULL) return(NULL); return(strdup(__b2c__s));}" >> $g_CTEMP
    echo "int __b2c__strcmp(const char *__b2c__s1, const char *__b2c__s2){if(__b2c__s1 == NULL && __b2c__s2 == NULL) return 0;" >> $g_CTEMP
    echo "if(__b2c__s1 == NULL)return(-1); if(__b2c__s2 == NULL)return(1); return(strcmp(__b2c__s1, __b2c__s2));}" >> $g_CTEMP
    echo "int __b2c__strcasecmp(const char *__b2c__s1, const char *__b2c__s2){if(__b2c__s1 == NULL && __b2c__s2 == NULL) return 0;" >> $g_CTEMP
    echo "if(__b2c__s1 == NULL)return(-1); if(__b2c__s2 == NULL)return(1); return(strcasecmp(__b2c__s1, __b2c__s2));}" >> $g_CTEMP
    echo "void* __b2c_Copy_String(char* x, char* y){long xlen, ylen; if(x==NULL && y==NULL) return(NULL); if(y==NULL){free(x); return(NULL);} else ylen=strlen(y);" >> $g_CTEMP
    echo "if(x==NULL) xlen=-1; else xlen = strlen(x); if(xlen < ylen) x=realloc(x, ylen+1); return(memmove(x, y, ylen+1));}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.malloc.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.malloc.o: bacon.malloc.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.malloc.c"

    g_CTEMP="$g_TEMPDIR/bacon.memcheck.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "void __b2c__catch_signal(int __b2c__sig){" >> $g_CTEMP
    echo "switch (__b2c__sig) {case SIGABRT: fprintf(stderr, \"ERROR: signal ABORT received - internal error. Try to compile the program with TRAP LOCAL to find the cause.\n\"); break;" >> $g_CTEMP
    echo "case SIGFPE: fprintf(stderr, \"ERROR: signal for FPE received - division by zero? Examine the calculations in the program.\n\"); break;" >> $g_CTEMP
    echo "case SIGSEGV: fprintf(stderr, \"ERROR: signal for SEGMENTATION FAULT received - memory invalid or array out of bounds? Try to compile the program with TRAP LOCAL to find the cause.\n\"); break;" >> $g_CTEMP
    echo "case SIGILL: fprintf(stderr, \"ERROR: signal for ILLEGAL INSTRUCTION received - executing the program on other hardware? Try to recompile the program from scratch.\n\"); break;} exit(__b2c__sig);}" >> $g_CTEMP
    echo "void __b2c__segv(int __b2c__sig){longjmp(__b2c__jump, 1);}" >> $g_CTEMP
    echo "int __b2c__memory__check(void* __b2c__x, int __b2c__size){int __b2c__i, __b2c__illegal = 0; signal(SIGSEGV, __b2c__segv);" >> $g_CTEMP
    echo "if(!setjmp(__b2c__jump)) {for(__b2c__i = 0; __b2c__i < __b2c__size; __b2c__i++) if((volatile char)*((char*)__b2c__x+__b2c__i)) continue;} else __b2c__illegal = 1;" >> $g_CTEMP
    echo "if(__b2c__trap) signal(SIGSEGV, __b2c__catch_signal); else signal(SIGSEGV, SIG_DFL); return(__b2c__illegal);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.memcheck.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.memcheck.o: bacon.memcheck.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.memcheck.c"

    g_CTEMP="$g_TEMPDIR/bacon.memory.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "int __b2c__memory_err(void) {ERROR = 6; RUNTIMEFERR(\"MEMORY\", ERROR); return(0);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.memory.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.memory.o: bacon.memory.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.memory.c"

    g_CTEMP="$g_TEMPDIR/bacon.mid.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char *__b2c__mid(char *src, ...){long idx; int pos, length, src_len; va_list ap; if (src == NULL) return(EmptyString); src_len = strlen(src); va_start (ap, src);" >> $g_CTEMP
    echo "pos = va_arg(ap, int); if(pos < 0) pos=src_len+1+pos; if(pos > src_len || pos <= 0) return (EmptyString); length = va_arg (ap, long); if(length < 0 || pos + length > src_len) length=src_len-pos+1;" >> $g_CTEMP
    echo "idx = __sbuf_malloc_handle((length + 1) * sizeof (char)); memcpy(__b2c__sbuffer[idx], src+(pos-1)*sizeof(char), length*sizeof(char)); __b2c__sbuffer[idx][length] = '\0'; va_end (ap); return (char *) (__b2c__sbuffer[idx]);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.mid.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.mid.o: bacon.mid.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.mid.c"

    g_CTEMP="$g_TEMPDIR/bacon.os.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__os (void) { struct utsname buf; long idx; idx = __sbuf_malloc_handle (${g_BUFFER_SIZE}*sizeof (char));" >> $g_CTEMP
    echo "if (uname (&buf) < 0 && __b2c__trap) { ERROR = 26; RUNTIMEFERR (\"OS$\", ERROR); } strcpy (__b2c__sbuffer[idx], buf.sysname);" >> $g_CTEMP
    echo "strcat (__b2c__sbuffer[idx], \" \"); strcat (__b2c__sbuffer[idx], buf.machine); return (char*)(__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.os.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.os.o: bacon.os.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.os.c"

    g_CTEMP="$g_TEMPDIR/bacon.peek.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "int __b2c__peek_check(void* __b2c__x, int __b2c__size) {if(__b2c__trap) {if(__b2c__memory__check(__b2c__x, __b2c__size)) {ERROR=1; RUNTIMEFERR(\"PEEK\", ERROR);} } return(0); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.peek.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.peek.o: bacon.peek.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.peek.c"

    g_CTEMP="$g_TEMPDIR/bacon.regex.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__regex(char* __b2c__x, char* __b2c__y){regex_t __b2c__reg; int __b2c__reti; char __b2c__buf[100]; regmatch_t __b2c__where[1]; if(__b2c__x == NULL || __b2c__y == NULL) return(0); if(__b2c__option_compare == 0) __b2c__reti = regcomp(&__b2c__reg, __b2c__y, REG_EXTENDED);" >> $g_CTEMP
    echo "else  __b2c__reti = regcomp(&__b2c__reg, __b2c__y, REG_EXTENDED|REG_ICASE); if(__b2c__trap && __b2c__reti){ERROR=27; regerror(__b2c__reti, &__b2c__reg, __b2c__buf, sizeof(__b2c__buf)); fprintf(stderr, \"%s\n\", __b2c__buf);" >> $g_CTEMP
    echo "RUNTIMEFERR(\"REGEX\", ERROR);} __b2c__reti = regexec(&__b2c__reg, __b2c__x, 1, __b2c__where, 0);" >> $g_CTEMP
    echo "regfree(&__b2c__reg); if( !__b2c__reti ) {REGLEN = __b2c__where[0].rm_eo - __b2c__where[0].rm_so; return (__b2c__where[0].rm_so+1);} else {REGLEN = 0; return (0);} }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.regex.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.regex.o: bacon.regex.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.regex.c"

    g_CTEMP="$g_TEMPDIR/bacon.remove.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "void __b2c__rmrecursive(char *dir){DIR *mydir; char *path, *item = NULL; struct stat buf = { 0 }; struct dirent *next = { NULL }; mydir = opendir(dir); if(mydir == NULL) {if(__b2c__trap) {ERROR = 8; RUNTIMEFERR(\"DELETE RECURSIVE\", ERROR);} }" >> $g_CTEMP
    echo "while (1) { if (item != NULL) free(item); next = readdir(mydir); if(next != NULL) { item = calloc((strlen (next->d_name) + 1), sizeof(char));" >> $g_CTEMP
    echo "strcpy(item, next->d_name); } else { break; } if (!strcmp (item, \".\") || !strcmp(item, \"..\") ) continue; path = calloc(strlen(dir)+strlen(item)+2, sizeof(char));" >> $g_CTEMP
    echo "strcpy(path, dir); strcat(path, \"/\"); strcat(path, item); lstat(path, &buf); if(S_ISDIR (buf.st_mode)) { __b2c__rmrecursive(path); } else { if(remove(path) < 0)" >> $g_CTEMP
    echo "{ if(__b2c__trap) { ERROR = 7; RUNTIMEFERR(\"DELETE RECURSIVE\", ERROR); } } } if(path != NULL) free(path); } closedir(mydir); if(remove(dir) < 0)" >> $g_CTEMP
    echo "{ if(__b2c__trap) { ERROR = 7; RUNTIMEFERR(\"DELETE RECURSIVE\", ERROR); } } }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.remove.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.remove.o: bacon.remove.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.remove.c"

    g_CTEMP="$g_TEMPDIR/bacon.replace.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__replace (char *haystack, ...) { char *tmp, *needle, *replace; long replen, hstlen, ndllen, length = 0; regex_t regex; int i, reti, flag = 0; long idx; char buf[100];" >> $g_CTEMP
    echo "regmatch_t where[1]; va_list ap; va_start (ap, haystack); needle = va_arg (ap, char *); replace = va_arg (ap, char *); flag = va_arg (ap, int); va_end (ap);" >> $g_CTEMP
    echo "if(haystack == NULL || needle == NULL || replace == NULL) return (char *) (haystack); ndllen = strlen (needle); hstlen = strlen (haystack); if (hstlen == 0 || ndllen == 0) return (char *) (haystack);" >> $g_CTEMP
    echo "if(flag == 2) { idx = __sbuf_malloc_handle(hstlen+1); strncpy(__b2c__sbuffer[idx], haystack, hstlen); for (i = 0; i < hstlen; i++) {if((tmp = strchr(needle, __b2c__sbuffer[idx][i])) != NULL)" >> $g_CTEMP
    echo "__b2c__sbuffer[idx][i] = replace[tmp-needle]; } __b2c__sbuffer[idx][i] = '\0'; return (char *) (__b2c__sbuffer[idx]); } idx = __sbuf_malloc_handle (sizeof (char)); __b2c__sbuffer[idx][0] = '\0';" >> $g_CTEMP
    echo "replen = strlen (replace); if (flag == 1) { if (__b2c__option_compare == 0) reti = regcomp (&regex, needle, REG_EXTENDED); else reti = regcomp (&regex, needle, REG_EXTENDED | REG_ICASE); if (__b2c__trap && reti)" >> $g_CTEMP
    echo "{ERROR = 27; regerror (reti, &regex, buf, sizeof (buf)); fprintf (stderr, \"%s\n\", buf); RUNTIMEFERR (\"REPLACE$\", ERROR); } while ((reti = regexec (&regex, haystack, 1, where, 0)) == 0) {" >> $g_CTEMP
    echo "__sbuf_need_realloc (idx, (length + where[0].rm_so + replen + 1) * sizeof (char)); memcpy (__b2c__sbuffer[idx] + length * sizeof (char), haystack, (size_t) where[0].rm_so * sizeof (char)); length += where[0].rm_so;" >> $g_CTEMP
    echo "memcpy (__b2c__sbuffer[idx] + length * sizeof (char), replace, replen * sizeof (char)); length += replen; haystack += (long) where[0].rm_eo; } regfree (&regex); } else { while ((tmp = strstr (haystack, needle)) != NULL)" >> $g_CTEMP
    echo "{__sbuf_need_realloc (idx, (length + (tmp - haystack) + replen + 1) * sizeof (char)); memcpy (__b2c__sbuffer[idx] + length * sizeof (char), haystack, (size_t) (tmp - haystack) * sizeof (char)); length += tmp - haystack;" >> $g_CTEMP
    echo "memcpy (__b2c__sbuffer[idx] + length * sizeof (char), replace, replen * sizeof (char)); length += replen; haystack = tmp + ndllen; } } hstlen = strlen (haystack); __sbuf_need_realloc (idx, (length + hstlen + 1) * sizeof (char));" >> $g_CTEMP
    echo " memcpy (__b2c__sbuffer[idx] + length * sizeof (char), haystack, hstlen * sizeof (char)); length += hstlen; __b2c__sbuffer[idx][length] = '\0'; return (char *) (__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.replace.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.replace.o: bacon.replace.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.replace.c"

    g_CTEMP="$g_TEMPDIR/bacon.reverse.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__reverse (char *src) { long i, length, idx; if (src == NULL) return (EmptyString); length = strlen (src); idx = __sbuf_malloc_handle ((length + 1) * sizeof (char));" >> $g_CTEMP
    echo " for (i = 0; i < length; i++) { __b2c__sbuffer[idx][i] = src[length - i - 1]; }  __b2c__sbuffer[idx][i] = '\0'; return (char*)(__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.reverse.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.reverse.o: bacon.reverse.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.reverse.c"

    g_CTEMP="$g_TEMPDIR/bacon.right.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__right (char *src, long n) { long length, idx; if (src != NULL) length = strlen (src); if (src == NULL || n > length || n < 0) return (src); idx=__sbuf_malloc_handle ( (n + 1) * sizeof (char));" >> $g_CTEMP
    echo "memcpy (__b2c__sbuffer[idx], src + (length - n) * sizeof (char), n * sizeof (char)); __b2c__sbuffer[idx][n] = '\0'; return (char *) (__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.right.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.right.o: bacon.right.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.right.c"

    g_CTEMP="$g_TEMPDIR/bacon.screen.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__screen(int __b2c__type){long __b2c__x; struct winsize __b2c_tmp; ioctl(STDOUT_FILENO, TIOCGWINSZ, &__b2c_tmp);" >> $g_CTEMP
    echo "if(__b2c__type) __b2c__x = __b2c_tmp.ws_row; else __b2c__x = __b2c_tmp.ws_col; return(__b2c__x); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.screen.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.screen.o: bacon.screen.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.screen.c"

    g_CTEMP="$g_TEMPDIR/bacon.search.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__search(FILE* __b2c__x, char* __b2c__y){long __b2c__off, __b2c__pos; char* __b2c__ptr;" >> $g_CTEMP
    echo "if(__b2c__x == NULL && __b2c__trap){ERROR = 2; RUNTIMEFERR(\"SEARCH\", ERROR);}" >> $g_CTEMP
    echo "if(__b2c__y == NULL && __b2c__trap){ERROR = 25; RUNTIMEFERR(\"SEARCH\", ERROR);}" >> $g_CTEMP
    echo "__b2c__pos = ftell(__b2c__x); __b2c__ptr = (char*)malloc((strlen(__b2c__y)+1)*sizeof(char)); __b2c__off = 0; do {" >> $g_CTEMP
    echo "fseek(__b2c__x, __b2c__off, SEEK_SET);memset(__b2c__ptr, 0, sizeof(char)*(strlen(__b2c__y)+1));" >> $g_CTEMP
    echo "if(fread(__b2c__ptr, sizeof(char), strlen(__b2c__y), __b2c__x) <=0) if(__b2c__trap){ERROR = 2; RUNTIMEFERR(\"SEARCH\", ERROR);} __b2c__off+=1;" >> $g_CTEMP
    echo "} while(!feof(__b2c__x) && strncmp(__b2c__ptr, __b2c__y, strlen(__b2c__y)));" >> $g_CTEMP
    echo "if(strncmp(__b2c__ptr, __b2c__y, strlen(__b2c__y))) __b2c__off = 0; fseek(__b2c__x, __b2c__pos, SEEK_SET); free(__b2c__ptr); return (--__b2c__off);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.search.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.search.o: bacon.search.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.search.c"

    g_CTEMP="$g_TEMPDIR/bacon.sort.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "int __b2c__sortnrd(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(double*)__b2c__a==*(double*)__b2c__b) return 0; else if (*(double*)__b2c__a < *(double*)__b2c__b) return -1; else return 1;}" >> $g_CTEMP
    echo "int __b2c__sortnrd_down(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(double*)__b2c__a==*(double*)__b2c__b) return 0; else if (*(double*)__b2c__a < *(double*)__b2c__b) return 1; else return -1;}" >> $g_CTEMP
    echo "int __b2c__sortnrf(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(float*)__b2c__a==*(float*)__b2c__b) return 0; else if (*(float*)__b2c__a < *(float*)__b2c__b) return -1; else return 1;}" >> $g_CTEMP
    echo "int __b2c__sortnrf_down(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(float*)__b2c__a==*(float*)__b2c__b) return 0; else if (*(float*)__b2c__a < *(float*)__b2c__b) return 1; else return -1;}" >> $g_CTEMP
    echo "int __b2c__sortnrl(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(long*)__b2c__a==*(long*)__b2c__b) return 0; else if (*(long*)__b2c__a < *(long*)__b2c__b) return -1; else return 1;}" >> $g_CTEMP
    echo "int __b2c__sortnrl_down(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(long*)__b2c__a==*(long*)__b2c__b) return 0; else if (*(long*)__b2c__a < *(long*)__b2c__b) return 1; else return -1;}" >> $g_CTEMP
    echo "int __b2c__sortnri(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(int*)__b2c__a==*(int*)__b2c__b) return 0; else if (*(int*)__b2c__a < *(int*)__b2c__b) return -1; else return 1;}" >> $g_CTEMP
    echo "int __b2c__sortnri_down(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(int*)__b2c__a==*(int*)__b2c__b) return 0; else if (*(int*)__b2c__a < *(int*)__b2c__b) return 1; else return -1;}" >> $g_CTEMP
    echo "int __b2c__sortnrs(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(short*)__b2c__a==*(short*)__b2c__b) return 0; else if (*(short*)__b2c__a < *(short*)__b2c__b) return -1; else return 1;}" >> $g_CTEMP
    echo "int __b2c__sortnrs_down(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(short*)__b2c__a==*(short*)__b2c__b) return 0; else if (*(short*)__b2c__a < *(short*)__b2c__b) return 1; else return -1;}" >> $g_CTEMP
    echo "int __b2c__sortnrc(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(char*)__b2c__a==*(char*)__b2c__b) return 0; else if (*(char*)__b2c__a < *(char*)__b2c__b) return -1; else return 1;}" >> $g_CTEMP
    echo "int __b2c__sortnrc_down(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if (*(char*)__b2c__a==*(char*)__b2c__b) return 0; else if (*(char*)__b2c__a < *(char*)__b2c__b) return 1; else return -1;}" >> $g_CTEMP
    echo "int __b2c__sortstr(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if(*(char **)__b2c__a == NULL) return -1; if(*(char **)__b2c__b == NULL) return 1; return strcmp(*(char **)__b2c__a, *(char **)__b2c__b);}" >> $g_CTEMP
    echo "int __b2c__sortstr_down(const void *__b2c__a, const void *__b2c__b)" >> $g_CTEMP
    echo "{if(*(char **)__b2c__a == NULL) return -1; if(*(char **)__b2c__b == NULL) return 1; return strcmp(*(char **)__b2c__b, *(char **)__b2c__a);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.sort.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.sort.o: bacon.sort.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.sort.c"

    g_CTEMP="$g_TEMPDIR/bacon.spc.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__spc (int amount) { long idx; idx = __sbuf_malloc_handle ((amount + 1) * sizeof (char)); memset (__b2c__sbuffer[idx], 32, amount);" >> $g_CTEMP
    echo "__b2c__sbuffer[idx][amount] = '\0'; return (char *) (__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.spc.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.spc.o: bacon.spc.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.spc.c"

    g_CTEMP="$g_TEMPDIR/bacon.str.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__str (double nr) { long idx; idx = __sbuf_malloc_handle (${g_MAX_DIGITS} * sizeof (char)); if (floor (nr) == nr) snprintf(__b2c__sbuffer[idx], ${g_MAX_DIGITS}, \"%ld\", (long)nr);" >> $g_CTEMP
    echo "else snprintf (__b2c__sbuffer[idx], ${g_MAX_DIGITS}, \"%g\", (double) nr); __b2c__sbuffer[idx][${g_MAX_DIGITS}-1] = '\0'; return(char*)(__b2c__sbuffer[idx]);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.str.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.str.o: bacon.str.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.str.c"

    g_CTEMP="$g_TEMPDIR/bacon.tab.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__tab (int amount) { long idx; idx = __sbuf_malloc_handle ((amount + 1 )* sizeof (char) ); memset (__b2c__sbuffer[idx], 9, amount);" >> $g_CTEMP
    echo "__b2c__sbuffer[idx][amount] = '\0'; return (char *) (__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.tab.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.tab.o: bacon.tab.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.tab.c"

    g_CTEMP="$g_TEMPDIR/bacon.time.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__time (time_t now, int which){ long result; char *buffer; struct tm *ts; buffer = calloc(${g_MAX_DIGITS}, sizeof (char)); ts = localtime (&now); switch (which) {" >> $g_CTEMP
    echo "case 1: strftime (buffer, ${g_MAX_DIGITS}, \"%d\", ts); break; case 2: strftime (buffer, ${g_MAX_DIGITS}, \"%m\", ts); break; case 3: strftime (buffer, ${g_MAX_DIGITS}, \"%Y\", ts); break;" >> $g_CTEMP
    echo "case 4: strftime (buffer, ${g_MAX_DIGITS}, \"%H\", ts); break; case 5: strftime (buffer, ${g_MAX_DIGITS}, \"%M\", ts); break; case 6: strftime (buffer, ${g_MAX_DIGITS}, \"%S\", ts); break;" >> $g_CTEMP
    echo "case 7: strftime (buffer, ${g_MAX_DIGITS}, \"%W\", ts); break; } result = atol(buffer); free(buffer); return(result); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.time.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.time.o: bacon.time.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.time.c"

    g_CTEMP="$g_TEMPDIR/bacon.timer.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "unsigned long __b2c__timer(){struct timeval __b2c__time; gettimeofday(&__b2c__time, NULL); if(difftime(__b2c__time.tv_sec, __b2c__elapsed_secs) < 1) return(unsigned long)((__b2c__time.tv_usec-__b2c__elapsed_usecs)/1000);" >> $g_CTEMP
    echo "else return(unsigned long)((difftime(__b2c__time.tv_sec, __b2c__elapsed_secs)-1)*1000+((1000000-__b2c__elapsed_usecs)+__b2c__time.tv_usec)/1000);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.timer.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.timer.o: bacon.timer.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.timer.c"

    g_CTEMP="$g_TEMPDIR/bacon.ucase.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "char * __b2c__ucase (char *src) { long i, idx; idx = __sbuf_malloc_handle ((strlen (src) + 1) * sizeof (char)); for (i = 0; src[i] != '\0'; i++)" >> $g_CTEMP
    echo "{__b2c__sbuffer[idx][i] = toupper(src[i]); } __b2c__sbuffer[idx][i] = '\0'; return (char *) (__b2c__sbuffer[idx]); }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.ucase.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.ucase.o: bacon.ucase.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.ucase.c"

    g_CTEMP="$g_TEMPDIR/bacon.version.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "void __b2c__version(char* __b2c__in){if(strcmp(\"${g_VERSION}\", __b2c__in)) {printf(\"System error: this BaCon binary was compiled with a previous BaCon archive and therefore may not function correctly.\n\");" >> $g_CTEMP
    echo "printf(\"Recompile your program using the '-a' flag.\n\"); exit(EXIT_FAILURE);} }" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.version.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.version.o: bacon.version.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.version.c"

    g_CTEMP="$g_TEMPDIR/bacon.wait.c"
    g_TMP_FILES="$g_TMP_FILES $g_CTEMP"
    echo "#include \"${g_SOURCEFILE##*/}.generic.h\"" > $g_CTEMP
    echo "long __b2c__netpeek(int __b2c__fd, int __b2c__usec){fd_set __b2c__rfds; struct timeval __b2c__tv; long __b2c__retval; struct termios __b2c__oldt, __b2c__newt;" >> $g_CTEMP
    echo "if(__b2c__fd == STDIN_FILENO){tcgetattr(STDIN_FILENO, &__b2c__oldt); __b2c__newt = __b2c__oldt; __b2c__newt.c_lflag &= ~(ICANON | ECHO); __b2c__newt.c_cc[VMIN]=1; __b2c__newt.c_cc[VTIME]=0; tcsetattr(STDIN_FILENO, TCSANOW, &__b2c__newt);}" >> $g_CTEMP
    echo "FD_ZERO(&__b2c__rfds); FD_SET(__b2c__fd, &__b2c__rfds);__b2c__tv.tv_usec = (__b2c__usec%1000)*1000; __b2c__tv.tv_sec = __b2c__usec/1000;" >> $g_CTEMP
    echo "__b2c__retval = select(__b2c__fd + 1, &__b2c__rfds, NULL, NULL, &__b2c__tv); if (__b2c__retval == -1 && __b2c__trap) {ERROR = 16; RUNTIMEFERR(\"WAIT\", ERROR);}" >> $g_CTEMP
    echo "if(__b2c__fd == STDIN_FILENO){if(__b2c__retval) if(read(__b2c__fd, &__b2c__retval, 1)==0) __b2c__retval=0; tcsetattr(STDIN_FILENO, TCSANOW, &__b2c__oldt);} return(__b2c__retval);}" >> $g_CTEMP
    g_OBJ_FILES="$g_OBJ_FILES bacon.wait.o"
    g_MAKE_LINE="$g_MAKE_LINE\nbacon.wait.o: bacon.wait.c\n\t$g_CCNAME $g_CCFLAGS -c bacon.wait.c"

    g_LDFLAGS="-L. ${g_LDFLAGS}"
fi

# Include functions and subs
for i in $g_INCLUDE_FILES
do
    echo "#include \"${i}\"" >> $g_HFILE
done

((g_TOTAL_LINES+=$g_COUNTER-1))
ttime=$(($SECONDS-$ttime))
echo -e "\rConverting '${g_SOURCEFILE}'... done, ${g_TOTAL_LINES} lines were processed in ${ttime} seconds.\033[0K"

# Indentation only when files are preserved
if [[ $g_TMP_PRESERVE -eq 1 ]]
then
    if [[ -n `which indent 2>/dev/null` ]]
    then
	echo -n "Applying indentation... "
	for i in $g_TMP_FILES
	do
	    if [[ $i != +(*.cpp) && $i != +(*.tmp) && $i != +(*.bac) ]]
	    then
		if [[ `uname` = "Darwin" || `uname` = +(*BSD*) ]]
		then
		    mv ${i} "${i}.BAK"
		    indent "${i}.BAK" ${i}
		    rm "${i}.BAK"
		else
		    indent $i
		    rm $i~
		fi
	    fi
	done
	echo "done."
    else
	echo "WARNING: 'indent' not found on this system!"
	echo "Generated source code cannot be beautified."
    fi
fi

# Check if we need to run xgettext
if [[ ${g_XGETTEXT} -eq 1 ]]
then
    if [[ -n `which xgettext 2>/dev/null` ]]
    then
	echo -n "Executing xgettext... "
	xgettext -d ${g_SOURCEFILE%.*} -s -o ${g_SOURCEFILE%.*}.pot $g_TMP_FILES
	if [[ ! -f "${g_SOURCEFILE%.*}.pot" ]]
	then
	    echo "WARNING: catalog file not created!"
	else
	    echo "done."
	fi
    else
	echo "WARNING: 'xgettext' not found on this system!"
    fi
fi

# Creation of the Makefile
echo -e "# Created with BASH BaCon $g_VERSION - (c) Peter van Eerten - MIT License (Expat)\n" > $g_TEMPDIR/Makefile
echo -e "${g_SOURCEFILE%.*}$g_BINEXT: ${g_SOURCEFILE##*/}.o ${g_REBUILD_ARCHIVE}" >> $g_TEMPDIR/Makefile
echo -e "\t$g_CCNAME -o ${g_SOURCEFILE%.*}$g_BINEXT ${g_SOURCEFILE##*/}.o $g_LDFLAGS" >> $g_TEMPDIR/Makefile
echo -e "${g_SOURCEFILE##*/}.o: ${g_SOURCEFILE##*/}.c" >> $g_TEMPDIR/Makefile
echo -e "\t$g_CCNAME $g_CCFLAGS -c ${g_SOURCEFILE##*/}.c" >> $g_TEMPDIR/Makefile
if [[ -n ${g_REBUILD_ARCHIVE} && $g_NO_COMPILE -eq 0 ]]
then
    echo -e "New BaCon archive requested! Creating..."
    rm -f $g_TEMPDIR/${g_REBUILD_ARCHIVE}
    echo -e "\n${g_REBUILD_ARCHIVE}: ${g_OBJ_FILES}" >> $g_TEMPDIR/Makefile
    echo -e "\t${g_ARNAME} ${g_REBUILD_ARCHIVE} ${g_OBJ_FILES} >/dev/null 2>&1" >> $g_TEMPDIR/Makefile
    if [[ -n ${g_RANLIB} ]]
    then
        echo -e "\t${g_RANLIB} ${g_REBUILD_ARCHIVE}" >> $g_TEMPDIR/Makefile
    fi
    echo -e "${g_MAKE_LINE}" >> $g_TEMPDIR/Makefile
fi
echo -e "\n.PHONY: clean" >> $g_TEMPDIR/Makefile
echo -e "clean:" >> $g_TEMPDIR/Makefile
echo -e "\trm -f *.o *.c ${g_SOURCEFILE%.*}$g_BINEXT ${g_SOURCEFILE%.bac}.*.* ${g_REBUILD_ARCHIVE} Makefile" >> $g_TEMPDIR/Makefile
g_TMP_FILES="$g_TMP_FILES $g_TEMPDIR/Makefile"

# Start compilation
if [[ $g_NO_COMPILE -eq 0 ]]
then
    if [[ -z `which $g_CCNAME 2>/dev/null` ]]
    then
	echo "WARNING: '$g_CCNAME' not found on this system!"
	echo "Generated source code cannot be compiled."
	exit 0
    fi
    echo -n "Compiling '${g_SOURCEFILE}'... "

    # Make sure GCC uses English localization
    export LANG="C"

    # Using 'cd' here to be compatible with older make's
    cd $g_TEMPDIR
    make 2>${g_SOURCEFILE##*/}.log

    # Go back to working directory
    cd - >/dev/null

    g_TMP_FILES="$g_TMP_FILES $g_TEMPDIR/${g_SOURCEFILE##*/}.log $g_TEMPDIR/${g_SOURCEFILE##*/}.o"

    if [[ -z `cat $g_TEMPDIR/${g_SOURCEFILE##*/}.log` ]]
    then
	echo "Done, program '${g_SOURCEFILE%.*}$g_BINEXT' ready."
    else
	# Only print first error
	echo -e "Compiler error:"
	while read -r g_ERROR
	do
            if [[ ( ${g_ERROR} != +(*from *) || ${g_ERROR} = +(*error:*from*) ) && ${g_ERROR} = +(*[0-9]*) && ${g_ERROR} = +(*: error:*) && $g_ERROR != +(*-----*) ]]
	    then
		g_ERRORTXT="Cause:\n\t${g_ERROR##*error:}"
		g_FILE_LINE=${g_ERROR%%error:*}
		break
	    elif [[ ( ${g_ERROR} != +(*from *) || ${g_ERROR} = +(*Error:*from*) ) && ${g_ERROR} = +(*[0-9]*) && ${g_ERROR} = +(*: Error:*) && $g_ERROR != +(*-----*) ]]
	    then
		g_ERRORTXT="Cause:\n\t${g_ERROR##*:}"
		g_FILE_LINE=${g_ERROR##*Error: }
		break
	    elif [[ ( ${g_ERROR} != +(*from *) || ${g_ERROR} = +(*warning:*from*) ) && ${g_ERROR} = +(*[0-9]*) && ${g_ERROR} = +(*: warning:*) && $g_ERROR != +(*-----*) ]]
	    then
		g_ERRORTXT="Cause:\n\t${g_ERROR##*warning:}"
		g_FILE_LINE=${g_ERROR%%warning:*}
		break
	    elif [[ ( ${g_ERROR} != +(*from *) || ${g_ERROR} = +(*:*from*) ) && ${g_ERROR} = +(*[0-9]:*) && $g_ERROR != +(*-----*) ]]
	    then
		g_ERRORTXT="Cause:\n\t${g_ERROR##*:}"
		g_FILE_LINE=${g_ERROR%:*}
		break
	    fi
	done < $g_TEMPDIR/${g_SOURCEFILE##*/}.log

	# Restore $-symbol if there is any
	if [[ $g_ERRORTXT = +(*${g_STRINGSIGN}*) ]]
	then
	    LEN=${#g_STRINGSIGN}
	    POS=0
	    until [[ $POS -eq ${#g_ERRORTXT} ]]
	    do
		SUBSTR="${g_ERRORTXT:${POS}:${LEN}}"
		if [[ $SUBSTR = $g_STRINGSIGN ]]
		then
		    SUBSTR="${g_ERRORTXT:0:${POS}}$"
		    ((POS+=${LEN}))
		    g_ERRORTXT="${SUBSTR}${g_ERRORTXT:${POS}:${#g_ERRORTXT}}"
		    break
		fi
		((POS+=1))
	    done
	fi

	# Get the file where the error is
	g_FILE=$g_TEMPDIR/${g_FILE_LINE%%:*}
	# Tru64Unix helper
	g_FILE=${g_FILE%%,*}

	# Non-gcc or parse problem (file does not exist)
	if [[ -z $g_ERROR || $g_CCFLAGS = +(*Wall*) || ! -f $g_FILE ]]
	then
	    echo
	    cat $g_TEMPDIR/${g_SOURCEFILE##*/}.log
	    echo
	else
	    # Get the erroneous line
	    if [[ ${g_FILE_LINE#*:} = +(*line*) ]]
	    then
		g_LINE=${g_FILE_LINE#*line}
	    else
		g_LINE=${g_FILE_LINE#*:}
	    fi
            # If no line number was found
            if [[ $g_LINE = +(*[a-zA-Z]*) ]]
            then
                g_LINE=1
            fi
            # Initiate error file name and error line in C code
	    g_FEED=${g_FILE_LINE%%:*}
	    g_CURLINE=${g_LINE%%:*}
	    # Remove everything behind last colon
	    g_LINE=${g_LINE%%:*}
	    g_COUNTER=1
	    while read -r LINE
	    do
		if [[ $LINE = +(*LINE *) && $LINE = +(*FILE *) ]]
		then
		    g_CURLINE=${LINE##*LINE }
		    g_FEED=${LINE##*FILE }
		    g_FEED=${g_FEED%% LINE*}
		fi
                if [[ $g_FEED != +(*.bac) ]]
                then
                    g_FEED="${g_TEMPDIR}/${g_FEED}"
                fi
		if [[ ${g_COUNTER} -eq ${g_LINE} ]]
		then
		    COUNTER=1
		    while read -r LINE
		    do
			if [[ $COUNTER -eq ${g_CURLINE%% *} ]]
			then
			    echo -e "\nDescription:\n\t file '$g_FEED' line $COUNTER: ${LINE}"
			    echo -e "$g_ERRORTXT\n"
			    break
			fi
			((COUNTER+=1))
		    done < $g_FEED
		    break
		fi
		((g_COUNTER+=1))
	    done < ${g_FILE}
	fi
	# Preserve temp files
	g_TMP_PRESERVE=1
    fi
fi

# Cleanup
if [[ $g_TMP_PRESERVE -eq 0 ]]
then
    for i in $g_TMP_FILES
    do
	if [[ -f $i ]]
	then
	    rm $i
	else
	    echo -e "\nWarning: duplicate SUB or FUNCTION found! Temporary file $i already deleted."
	fi
    done
    if [[ -n $g_REBUILD_ARCHIVE ]]
    then
        rm -f $g_TEMPDIR/bacon.*.o
    fi
fi

exit 0
