github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/os/env.go (about)

     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  	buf := make([]byte, 0, 2*len(s))
    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  			buf = append(buf, s[i:j]...)
    23  			name, w := getShellName(s[j+1:])
    24  			buf = append(buf, mapping(name)...)
    25  			j += w
    26  			i = j + 1
    27  		}
    28  	}
    29  	return string(buf) + s[i:]
    30  }
    31  
    32  // ExpandEnv replaces ${var} or $var in the string according to the values
    33  // of the current environment variables. References to undefined
    34  // variables are replaced by the empty string.
    35  func ExpandEnv(s string) string {
    36  	return Expand(s, Getenv)
    37  }
    38  
    39  // isShellSpecialVar reports whether the character identifies a special
    40  // shell variable such as $*.
    41  func isShellSpecialVar(c uint8) bool {
    42  	switch c {
    43  	case '*', '#', '$', '@', '!', '?', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
    44  		return true
    45  	}
    46  	return false
    47  }
    48  
    49  // isAlphaNum reports whether the byte is an ASCII letter, number, or underscore
    50  func isAlphaNum(c uint8) bool {
    51  	return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
    52  }
    53  
    54  // getShellName returns the name that begins the string and the number of bytes
    55  // consumed to extract it. If the name is enclosed in {}, it's part of a ${}
    56  // expansion and two more bytes are needed than the length of the name.
    57  func getShellName(s string) (string, int) {
    58  	switch {
    59  	case s[0] == '{':
    60  		if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' {
    61  			return s[1:2], 3
    62  		}
    63  		// Scan to closing brace
    64  		for i := 1; i < len(s); i++ {
    65  			if s[i] == '}' {
    66  				return s[1:i], i + 1
    67  			}
    68  		}
    69  		return "", 1 // Bad syntax; just eat the brace.
    70  	case isShellSpecialVar(s[0]):
    71  		return s[0:1], 1
    72  	}
    73  	// Scan alphanumerics.
    74  	var i int
    75  	for i = 0; i < len(s) && isAlphaNum(s[i]); i++ {
    76  	}
    77  	return s[:i], i
    78  }
    79  
    80  // Getenv retrieves the value of the environment variable named by the key.
    81  // It returns the value, which will be empty if the variable is not present.
    82  // To distinguish between an empty value and an unset value, use LookupEnv.
    83  func Getenv(key string) string {
    84  	testlog.Getenv(key)
    85  	v, _ := syscall.Getenv(key)
    86  	return v
    87  }
    88  
    89  // LookupEnv retrieves the value of the environment variable named
    90  // by the key. If the variable is present in the environment the
    91  // value (which may be empty) is returned and the boolean is true.
    92  // Otherwise the returned value will be empty and the boolean will
    93  // be false.
    94  func LookupEnv(key string) (string, bool) {
    95  	testlog.Getenv(key)
    96  	return syscall.Getenv(key)
    97  }
    98  
    99  // Setenv sets the value of the environment variable named by the key.
   100  // It returns an error, if any.
   101  func Setenv(key, value string) error {
   102  	err := syscall.Setenv(key, value)
   103  	if err != nil {
   104  		return NewSyscallError("setenv", err)
   105  	}
   106  	return nil
   107  }
   108  
   109  // Unsetenv unsets a single environment variable.
   110  func Unsetenv(key string) error {
   111  	return syscall.Unsetenv(key)
   112  }
   113  
   114  // Clearenv deletes all environment variables.
   115  func Clearenv() {
   116  	syscall.Clearenv()
   117  }
   118  
   119  // Environ returns a copy of strings representing the environment,
   120  // in the form "key=value".
   121  func Environ() []string {
   122  	return syscall.Environ()
   123  }