/* 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 . */ 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 func SetVar(variable string, value *Token, vt VarTable) { (*vt)[variable] = value if SyncTablesWithOSEnviron && (value.Tag == NUMBER || value.Tag == STRING) { token := value.Inner.(string) 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) { 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 } 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") } } }