...

Source file src/os/env.go

Documentation: os

		 1  // Copyright 2010 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  // General environment variables.
		 6  
		 7  package os
		 8  
		 9  import (
		10  	"internal/testlog"
		11  	"syscall"
		12  )
		13  
		14  // Expand replaces ${var} or $var in the string based on the mapping function.
		15  // For example, os.ExpandEnv(s) is equivalent to os.Expand(s, os.Getenv).
		16  func Expand(s string, mapping func(string) string) string {
		17  	var buf []byte
		18  	// ${} is all ASCII, so bytes are fine for this operation.
		19  	i := 0
		20  	for j := 0; j < len(s); j++ {
		21  		if s[j] == '$' && j+1 < len(s) {
		22  			if buf == nil {
		23  				buf = make([]byte, 0, 2*len(s))
		24  			}
		25  			buf = append(buf, s[i:j]...)
		26  			name, w := getShellName(s[j+1:])
		27  			if name == "" && w > 0 {
		28  				// Encountered invalid syntax; eat the
		29  				// characters.
		30  			} else if name == "" {
		31  				// Valid syntax, but $ was not followed by a
		32  				// name. Leave the dollar character untouched.
		33  				buf = append(buf, s[j])
		34  			} else {
		35  				buf = append(buf, mapping(name)...)
		36  			}
		37  			j += w
		38  			i = j + 1
		39  		}
		40  	}
		41  	if buf == nil {
		42  		return s
		43  	}
		44  	return string(buf) + s[i:]
		45  }
		46  
		47  // ExpandEnv replaces ${var} or $var in the string according to the values
		48  // of the current environment variables. References to undefined
		49  // variables are replaced by the empty string.
		50  func ExpandEnv(s string) string {
		51  	return Expand(s, Getenv)
		52  }
		53  
		54  // isShellSpecialVar reports whether the character identifies a special
		55  // shell variable such as $*.
		56  func isShellSpecialVar(c uint8) bool {
		57  	switch c {
		58  	case '*', '#', '$', '@', '!', '?', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		59  		return true
		60  	}
		61  	return false
		62  }
		63  
		64  // isAlphaNum reports whether the byte is an ASCII letter, number, or underscore
		65  func isAlphaNum(c uint8) bool {
		66  	return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
		67  }
		68  
		69  // getShellName returns the name that begins the string and the number of bytes
		70  // consumed to extract it. If the name is enclosed in {}, it's part of a ${}
		71  // expansion and two more bytes are needed than the length of the name.
		72  func getShellName(s string) (string, int) {
		73  	switch {
		74  	case s[0] == '{':
		75  		if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' {
		76  			return s[1:2], 3
		77  		}
		78  		// Scan to closing brace
		79  		for i := 1; i < len(s); i++ {
		80  			if s[i] == '}' {
		81  				if i == 1 {
		82  					return "", 2 // Bad syntax; eat "${}"
		83  				}
		84  				return s[1:i], i + 1
		85  			}
		86  		}
		87  		return "", 1 // Bad syntax; eat "${"
		88  	case isShellSpecialVar(s[0]):
		89  		return s[0:1], 1
		90  	}
		91  	// Scan alphanumerics.
		92  	var i int
		93  	for i = 0; i < len(s) && isAlphaNum(s[i]); i++ {
		94  	}
		95  	return s[:i], i
		96  }
		97  
		98  // Getenv retrieves the value of the environment variable named by the key.
		99  // It returns the value, which will be empty if the variable is not present.
	 100  // To distinguish between an empty value and an unset value, use LookupEnv.
	 101  func Getenv(key string) string {
	 102  	testlog.Getenv(key)
	 103  	v, _ := syscall.Getenv(key)
	 104  	return v
	 105  }
	 106  
	 107  // LookupEnv retrieves the value of the environment variable named
	 108  // by the key. If the variable is present in the environment the
	 109  // value (which may be empty) is returned and the boolean is true.
	 110  // Otherwise the returned value will be empty and the boolean will
	 111  // be false.
	 112  func LookupEnv(key string) (string, bool) {
	 113  	testlog.Getenv(key)
	 114  	return syscall.Getenv(key)
	 115  }
	 116  
	 117  // Setenv sets the value of the environment variable named by the key.
	 118  // It returns an error, if any.
	 119  func Setenv(key, value string) error {
	 120  	err := syscall.Setenv(key, value)
	 121  	if err != nil {
	 122  		return NewSyscallError("setenv", err)
	 123  	}
	 124  	return nil
	 125  }
	 126  
	 127  // Unsetenv unsets a single environment variable.
	 128  func Unsetenv(key string) error {
	 129  	return syscall.Unsetenv(key)
	 130  }
	 131  
	 132  // Clearenv deletes all environment variables.
	 133  func Clearenv() {
	 134  	syscall.Clearenv()
	 135  }
	 136  
	 137  // Environ returns a copy of strings representing the environment,
	 138  // in the form "key=value".
	 139  func Environ() []string {
	 140  	return syscall.Environ()
	 141  }
	 142  

View as plain text