123 lines
3.3 KiB
Go
123 lines
3.3 KiB
Go
/* SHS: Syntactically Homogeneous Shell
|
|
* Copyright (C) 2019 Aidan Hahn
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package ast
|
|
|
|
import (
|
|
"os"
|
|
"fmt"
|
|
"math"
|
|
"strconv"
|
|
"strings"
|
|
"gitlab.com/whom/shs/log"
|
|
)
|
|
|
|
// Trigger this if you are using this for a shell
|
|
var SyncTablesWithOSEnviron = false
|
|
|
|
type VarTable *map[string]*Token
|
|
|
|
func GetVar(arg string, vt VarTable) *Token {
|
|
val, ok := (*vt)[arg]
|
|
if !ok {
|
|
if !SyncTablesWithOSEnviron {
|
|
return nil
|
|
}
|
|
|
|
e := os.Getenv(arg)
|
|
if e != "" {
|
|
t := &Token{inner: e}
|
|
if StrIsNumber(e) {
|
|
t.Tag = NUMBER
|
|
} else {
|
|
t.Tag = STRING
|
|
}
|
|
|
|
SetVar(arg, t, vt)
|
|
return t
|
|
}
|
|
return nil
|
|
}
|
|
return val
|
|
}
|
|
|
|
// TODO: this could be much more optimal
|
|
// probably a stdlib thing
|
|
func SetVar(variable string, value *Token, vt VarTable) {
|
|
(*vt)[variable] = value
|
|
if SyncTablesWithOSEnviron &&
|
|
(value.Tag == NUMBER || value.Tag == STRING) {
|
|
token := value.Value()
|
|
if value.Tag == NUMBER {
|
|
// make sure its an int
|
|
a, err := strconv.ParseFloat(token, 64)
|
|
if err == nil && math.Mod(a, 1.0) == 0 {
|
|
token = fmt.Sprintf("%d", int(a))
|
|
}
|
|
}
|
|
os.Setenv(variable, token)
|
|
}
|
|
}
|
|
|
|
// Library represents variables defined in inner scope
|
|
// It is assumed library is ordered from innermost scope to outermost scope
|
|
func GetVarFromTables(arg string, library []VarTable) *Token {
|
|
var res *Token
|
|
res = nil
|
|
for i := 0; i < len(library); i += 1 {
|
|
res = GetVar(arg, library[i])
|
|
if res != nil {
|
|
// TODO: Log scope res was found in?
|
|
break
|
|
}
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func InitVarTable(table VarTable) {
|
|
if !SyncTablesWithOSEnviron {
|
|
return
|
|
}
|
|
|
|
for _, val := range os.Environ() {
|
|
variable := strings.Split(val, "=")
|
|
t := &Token{inner: variable[1]}
|
|
if StrIsNumber(variable[1]) {
|
|
t.Tag = NUMBER
|
|
} else {
|
|
t.Tag = STRING
|
|
}
|
|
|
|
if variable[0] == "HOME" {
|
|
SetVar("~", t, table)
|
|
}
|
|
SetVar(variable[0], t, table)
|
|
}
|
|
}
|
|
|
|
// Dont do this on var tables youve already called InitVarTable on.... please....
|
|
// This will pull currently contained variables OUT of the operating env
|
|
func DeleteVarTable(table VarTable) {
|
|
for key, _ := range (*table) {
|
|
// from what I can tell, theres not much we can do if this fails
|
|
err := os.Unsetenv(key)
|
|
if err != nil {
|
|
log.Log(log.DEBUG, "Failed to remove " + key + " from env: " + err.Error(), "vartable")
|
|
}
|
|
}
|
|
}
|