modernc.org/99c@v1.0.1-0.20181109153923-a9e8197063d9/libtool.go (about)

     1  // Copyright 2017 The 99c 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  package main
     6  
     7  import (
     8  	"bufio"
     9  	"fmt"
    10  	"io"
    11  	"os"
    12  	"strconv"
    13  	"strings"
    14  )
    15  
    16  var (
    17  	libToolConfigs = map[string]libToolConfig{}
    18  )
    19  
    20  type libToolConfig map[string]interface{}
    21  
    22  func newLibToolConfig(r io.Reader) (libToolConfig, error) {
    23  	s := bufio.NewScanner(r)
    24  	c := libToolConfig{}
    25  	for s.Scan() {
    26  		l := strings.TrimSpace(s.Text())
    27  		if l == "" || strings.HasPrefix(l, "#") {
    28  			continue
    29  		}
    30  
    31  		a := strings.SplitN(l, "=", 2)
    32  		if len(a) != 2 {
    33  			return nil, fmt.Errorf("invalid libtool config line: %s", l)
    34  		}
    35  
    36  		nm := strings.TrimSpace(a[0])
    37  		val := strings.TrimSpace(a[1])
    38  		if _, ok := c[nm]; ok {
    39  			return nil, fmt.Errorf("duplicate libtool config item: %s", l)
    40  		}
    41  
    42  		if strings.HasPrefix(val, "'") {
    43  			if !strings.HasSuffix(val, "'") {
    44  				return nil, fmt.Errorf("invalid libtool config value: %s", l)
    45  			}
    46  
    47  			c[nm] = val[1 : len(val)-1]
    48  			continue
    49  		}
    50  
    51  		if val == "yes" {
    52  			c[nm] = true
    53  			continue
    54  		}
    55  
    56  		if val == "no" {
    57  			c[nm] = false
    58  			continue
    59  		}
    60  
    61  		n, err := strconv.ParseUint(val, 10, 31)
    62  		if err == nil {
    63  			c[nm] = int(n)
    64  			continue
    65  		}
    66  
    67  		return nil, fmt.Errorf("invalid libtool config line: %s", l)
    68  	}
    69  	if err := s.Err(); err != nil {
    70  		return nil, err
    71  	}
    72  
    73  	return c, nil
    74  }
    75  
    76  func newLibToolConfigFile(fn string) (libToolConfig, error) {
    77  	if x, ok := libToolConfigs[fn]; ok {
    78  		return x, nil
    79  	}
    80  
    81  	f, err := os.Open(fn)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  
    86  	defer f.Close()
    87  
    88  	c, err := newLibToolConfig(f)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	libToolConfigs[fn] = c
    94  	return c, nil
    95  }
    96  
    97  func (c libToolConfig) dependencyLibs() ([]string, error) {
    98  	var r []string
    99  	rq, ok := c["dependency_libs"]
   100  	if !ok {
   101  		return nil, nil
   102  	}
   103  
   104  	s, ok := rq.(string)
   105  	if !ok {
   106  		return nil, fmt.Errorf("invalid dependency_libs value: %T(%#v)", rq, rq)
   107  	}
   108  
   109  	s = strings.TrimSpace(s)
   110  	a := strings.Split(s, " ")
   111  	for _, v := range a {
   112  		v = strings.TrimSpace(v)
   113  		if v == "" {
   114  			continue
   115  		}
   116  
   117  		if v == "-l" || !strings.HasPrefix(v, "-l") {
   118  			return nil, fmt.Errorf("invalid dependency_libs value: %v", s)
   119  		}
   120  
   121  		r = append(r, v[2:])
   122  	}
   123  	return r, nil
   124  }