github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/android/util.go (about)

     1  // Copyright 2015 Google Inc. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package android
    16  
    17  import (
    18  	"runtime"
    19  	"sort"
    20  	"strings"
    21  )
    22  
    23  func JoinWithPrefix(strs []string, prefix string) string {
    24  	if len(strs) == 0 {
    25  		return ""
    26  	}
    27  
    28  	if len(strs) == 1 {
    29  		return prefix + strs[0]
    30  	}
    31  
    32  	n := len(" ") * (len(strs) - 1)
    33  	for _, s := range strs {
    34  		n += len(prefix) + len(s)
    35  	}
    36  
    37  	ret := make([]byte, 0, n)
    38  	for i, s := range strs {
    39  		if i != 0 {
    40  			ret = append(ret, ' ')
    41  		}
    42  		ret = append(ret, prefix...)
    43  		ret = append(ret, s...)
    44  	}
    45  	return string(ret)
    46  }
    47  
    48  func sortedKeys(m map[string][]string) []string {
    49  	s := make([]string, 0, len(m))
    50  	for k := range m {
    51  		s = append(s, k)
    52  	}
    53  	sort.Strings(s)
    54  	return s
    55  }
    56  
    57  func IndexList(s string, list []string) int {
    58  	for i, l := range list {
    59  		if l == s {
    60  			return i
    61  		}
    62  	}
    63  
    64  	return -1
    65  }
    66  
    67  func InList(s string, list []string) bool {
    68  	return IndexList(s, list) != -1
    69  }
    70  
    71  func PrefixInList(s string, list []string) bool {
    72  	for _, prefix := range list {
    73  		if strings.HasPrefix(s, prefix) {
    74  			return true
    75  		}
    76  	}
    77  	return false
    78  }
    79  
    80  func FilterList(list []string, filter []string) (remainder []string, filtered []string) {
    81  	for _, l := range list {
    82  		if InList(l, filter) {
    83  			filtered = append(filtered, l)
    84  		} else {
    85  			remainder = append(remainder, l)
    86  		}
    87  	}
    88  
    89  	return
    90  }
    91  
    92  func RemoveListFromList(list []string, filter_out []string) (result []string) {
    93  	result = make([]string, 0, len(list))
    94  	for _, l := range list {
    95  		if !InList(l, filter_out) {
    96  			result = append(result, l)
    97  		}
    98  	}
    99  	return
   100  }
   101  
   102  func RemoveFromList(s string, list []string) (bool, []string) {
   103  	i := IndexList(s, list)
   104  	if i == -1 {
   105  		return false, list
   106  	}
   107  
   108  	result := make([]string, 0, len(list)-1)
   109  	result = append(result, list[:i]...)
   110  	for _, l := range list[i+1:] {
   111  		if l != s {
   112  			result = append(result, l)
   113  		}
   114  	}
   115  	return true, result
   116  }
   117  
   118  // FirstUniqueStrings returns all unique elements of a slice of strings, keeping the first copy of
   119  // each.  It modifies the slice contents in place, and returns a subslice of the original slice.
   120  func FirstUniqueStrings(list []string) []string {
   121  	k := 0
   122  outer:
   123  	for i := 0; i < len(list); i++ {
   124  		for j := 0; j < k; j++ {
   125  			if list[i] == list[j] {
   126  				continue outer
   127  			}
   128  		}
   129  		list[k] = list[i]
   130  		k++
   131  	}
   132  	return list[:k]
   133  }
   134  
   135  // LastUniqueStrings returns all unique elements of a slice of strings, keeping the last copy of
   136  // each.  It modifies the slice contents in place, and returns a subslice of the original slice.
   137  func LastUniqueStrings(list []string) []string {
   138  	totalSkip := 0
   139  	for i := len(list) - 1; i >= totalSkip; i-- {
   140  		skip := 0
   141  		for j := i - 1; j >= totalSkip; j-- {
   142  			if list[i] == list[j] {
   143  				skip++
   144  			} else {
   145  				list[j+skip] = list[j]
   146  			}
   147  		}
   148  		totalSkip += skip
   149  	}
   150  	return list[totalSkip:]
   151  }
   152  
   153  // checkCalledFromInit panics if a Go package's init function is not on the
   154  // call stack.
   155  func checkCalledFromInit() {
   156  	for skip := 3; ; skip++ {
   157  		_, funcName, ok := callerName(skip)
   158  		if !ok {
   159  			panic("not called from an init func")
   160  		}
   161  
   162  		if funcName == "init" || strings.HasPrefix(funcName, "init·") {
   163  			return
   164  		}
   165  	}
   166  }
   167  
   168  // callerName returns the package path and function name of the calling
   169  // function.  The skip argument has the same meaning as the skip argument of
   170  // runtime.Callers.
   171  func callerName(skip int) (pkgPath, funcName string, ok bool) {
   172  	var pc [1]uintptr
   173  	n := runtime.Callers(skip+1, pc[:])
   174  	if n != 1 {
   175  		return "", "", false
   176  	}
   177  
   178  	f := runtime.FuncForPC(pc[0])
   179  	fullName := f.Name()
   180  
   181  	lastDotIndex := strings.LastIndex(fullName, ".")
   182  	if lastDotIndex == -1 {
   183  		panic("unable to distinguish function name from package")
   184  	}
   185  
   186  	if fullName[lastDotIndex-1] == ')' {
   187  		// The caller is a method on some type, so it's name looks like
   188  		// "pkg/path.(type).method".  We need to go back one dot farther to get
   189  		// to the package name.
   190  		lastDotIndex = strings.LastIndex(fullName[:lastDotIndex], ".")
   191  	}
   192  
   193  	pkgPath = fullName[:lastDotIndex]
   194  	funcName = fullName[lastDotIndex+1:]
   195  	ok = true
   196  	return
   197  }
   198  
   199  func GetNumericSdkVersion(v string) string {
   200  	if strings.Contains(v, "system_") {
   201  		return strings.Replace(v, "system_", "", 1)
   202  	}
   203  	return v
   204  }