SHS/ast/var_table.go

148 lines
3.9 KiB
Go
Raw Normal View History

2019-11-29 12:57:03 -08:00
/* 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
2019-11-28 01:04:51 -08:00
import (
"os"
"fmt"
"math"
"strconv"
"strings"
2020-06-28 13:47:44 -07:00
"gitlab.com/whom/shs/log"
)
2020-07-18 14:40:35 -07:00
/* defines whether or not to synchronize tokens wiht os environment vars
* will not sync non stringable tokens
*/
var SyncTablesWithOSEnviron = false
2020-07-18 14:40:35 -07:00
/* mapping of key to token.
*/
type VarTable *map[string]*Token
2019-11-28 01:04:51 -08:00
2020-07-18 14:40:35 -07:00
/* retrieve the token cooresponding to a given key
* if SyncTablesWithOSEnviron is true and no token exists for a key
* os Environment variables will be searched for the key
*/
func GetVar(arg string, vt VarTable) *Token {
val, ok := (*vt)[arg]
if !ok {
if !SyncTablesWithOSEnviron {
return nil
}
e := os.Getenv(arg)
if e != "" {
2020-06-29 00:06:53 -07:00
t := &Token{inner: e}
if StrIsNumber(e) {
t.Tag = NUMBER
} else {
t.Tag = STRING
}
SetVar(arg, t, vt)
return t
}
return nil
}
return val
}
2019-11-28 01:04:51 -08:00
2020-07-18 14:40:35 -07:00
/* adds a key->token mapping to the table
* if SyncTablesWithOSEnviron is true, will also add value to os environment
* will not do so for non stringable tokens
*/
func SetVar(variable string, value *Token, vt VarTable) {
(*vt)[variable] = value
if SyncTablesWithOSEnviron &&
(value.Tag == NUMBER || value.Tag == STRING) {
2020-06-29 00:06:53 -07:00
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)
}
}
2020-07-18 10:44:34 -07:00
/* lists all vars in tables
*/
func ListVars(vt VarTable) []string {
keys := make([]string, len(*vt))
i := 0
for k := range *vt {
keys[i] = k
}
return keys
}
2020-07-18 14:40:35 -07:00
/* if SyncTablesWithOSEnviron is true
* function will put ever environment variable into VarTable
*/
func InitVarTable(table VarTable) {
2020-06-30 20:27:12 -07:00
if !SyncTablesWithOSEnviron {
return
}
for _, val := range os.Environ() {
variable := strings.Split(val, "=")
2020-06-29 00:06:53 -07:00
t := &Token{inner: variable[1]}
if StrIsNumber(variable[1]) {
t.Tag = NUMBER
} else {
t.Tag = STRING
}
2020-06-30 20:27:12 -07:00
if variable[0] == "HOME" {
SetVar("~", t, table)
2020-06-30 20:27:12 -07:00
}
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")
}
}
}
2020-07-19 15:11:35 -07:00
2020-07-18 14:40:35 -07:00
/* removes var from vartable
* if SyncTablesWithOSENviron is true, also unsets environment variable
*/
func RemoveVar(arg string, table VarTable) {
if SyncTablesWithOSEnviron {
err := os.Unsetenv(arg)
if err != nil {
log.Log(log.DEBUG,
"Failed to remove "+arg+" from env: "+err.Error(),
"vartable")
}
}
delete(*table, arg)
}