/* 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" ) /* defines whether or not to synchronize tokens wiht os environment vars * will not sync non stringable tokens */ var SyncTablesWithOSEnviron = false /* mapping of key to token. */ type VarTable *map[string]*Token /* 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 != "" { t := &Token{inner: e} if StrIsNumber(e) { t.Tag = NUMBER } else { t.Tag = STRING } SetVar(arg, t, vt) return t } return nil } return val } /* 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) { 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) } } /* 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 } /* if SyncTablesWithOSEnviron is true * function will put ever environment variable into VarTable */ 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") } } } /* 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) }