...

Source file src/os/env.go

     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