|  | // Copyright 2010 The Go Authors.  All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | // General environment variables. | 
|  |  | 
|  | package os | 
|  |  | 
|  | import "syscall" | 
|  |  | 
|  | // Expand replaces ${var} or $var in the string based on the mapping function. | 
|  | // For example, os.ExpandEnv(s) is equivalent to os.Expand(s, os.Getenv). | 
|  | func Expand(s string, mapping func(string) string) string { | 
|  | buf := make([]byte, 0, 2*len(s)) | 
|  | // ${} is all ASCII, so bytes are fine for this operation. | 
|  | i := 0 | 
|  | for j := 0; j < len(s); j++ { | 
|  | if s[j] == '$' && j+1 < len(s) { | 
|  | buf = append(buf, s[i:j]...) | 
|  | name, w := getShellName(s[j+1:]) | 
|  | buf = append(buf, mapping(name)...) | 
|  | j += w | 
|  | i = j + 1 | 
|  | } | 
|  | } | 
|  | return string(buf) + s[i:] | 
|  | } | 
|  |  | 
|  | // ExpandEnv replaces ${var} or $var in the string according to the values | 
|  | // of the current environment variables.  References to undefined | 
|  | // variables are replaced by the empty string. | 
|  | func ExpandEnv(s string) string { | 
|  | return Expand(s, Getenv) | 
|  | } | 
|  |  | 
|  | // isSpellSpecialVar reports whether the character identifies a special | 
|  | // shell variable such as $*. | 
|  | func isShellSpecialVar(c uint8) bool { | 
|  | switch c { | 
|  | case '*', '#', '$', '@', '!', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': | 
|  | return true | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | // isAlphaNum reports whether the byte is an ASCII letter, number, or underscore | 
|  | func isAlphaNum(c uint8) bool { | 
|  | return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' | 
|  | } | 
|  |  | 
|  | // getName returns the name that begins the string and the number of bytes | 
|  | // consumed to extract it.  If the name is enclosed in {}, it's part of a ${} | 
|  | // expansion and two more bytes are needed than the length of the name. | 
|  | func getShellName(s string) (string, int) { | 
|  | switch { | 
|  | case s[0] == '{': | 
|  | if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' { | 
|  | return s[1:2], 3 | 
|  | } | 
|  | // Scan to closing brace | 
|  | for i := 1; i < len(s); i++ { | 
|  | if s[i] == '}' { | 
|  | return s[1:i], i + 1 | 
|  | } | 
|  | } | 
|  | return "", 1 // Bad syntax; just eat the brace. | 
|  | case isShellSpecialVar(s[0]): | 
|  | return s[0:1], 1 | 
|  | } | 
|  | // Scan alphanumerics. | 
|  | var i int | 
|  | for i = 0; i < len(s) && isAlphaNum(s[i]); i++ { | 
|  | } | 
|  | return s[:i], i | 
|  | } | 
|  |  | 
|  | // Getenv retrieves the value of the environment variable named by the key. | 
|  | // It returns the value, which will be empty if the variable is not present. | 
|  | func Getenv(key string) string { | 
|  | v, _ := syscall.Getenv(key) | 
|  | return v | 
|  | } | 
|  |  | 
|  | // Setenv sets the value of the environment variable named by the key. | 
|  | // It returns an error, if any. | 
|  | func Setenv(key, value string) error { | 
|  | err := syscall.Setenv(key, value) | 
|  | if err != nil { | 
|  | return NewSyscallError("setenv", err) | 
|  | } | 
|  | return nil | 
|  | } | 
|  |  | 
|  | // Unsetenv unsets a single environment variable. | 
|  | func Unsetenv(key string) error { | 
|  | return syscall.Unsetenv(key) | 
|  | } | 
|  |  | 
|  | // Clearenv deletes all environment variables. | 
|  | func Clearenv() { | 
|  | syscall.Clearenv() | 
|  | } | 
|  |  | 
|  | // Environ returns a copy of strings representing the environment, | 
|  | // in the form "key=value". | 
|  | func Environ() []string { | 
|  | return syscall.Environ() | 
|  | } |