github.com/hirochachacha/plua@v0.0.0-20170217012138-c82f520cc725/stdlib/os/os.go (about)

     1  package os
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/exec"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/hirochachacha/plua/object"
    12  	"github.com/hirochachacha/plua/object/fnutil"
    13  )
    14  
    15  var (
    16  	startTime = time.Now()
    17  )
    18  
    19  func clock(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
    20  	endTime := time.Now()
    21  	diffSecond := float64(endTime.Unix()-startTime.Unix()) / 1000
    22  
    23  	return []object.Value{object.Number(diffSecond)}, nil
    24  }
    25  
    26  // date([format [, time]])
    27  func date(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
    28  	ap := fnutil.NewArgParser(th, args)
    29  
    30  	format, err := ap.OptGoString(0, "%c")
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  
    35  	sec, err := ap.OptGoInt64(1, time.Now().Unix())
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	t := time.Unix(sec, 0)
    41  
    42  	if len(format) == 0 {
    43  		return []object.Value{object.String("")}, nil
    44  	}
    45  
    46  	if format[0] == '!' {
    47  		format = format[1:]
    48  	} else {
    49  		t = t.Local()
    50  	}
    51  
    52  	if format == "*t" {
    53  		tab := th.NewTableSize(0, 8)
    54  
    55  		updateTable(th, tab, t)
    56  
    57  		return []object.Value{tab}, nil
    58  	}
    59  
    60  	s, err := dateFormat(th, format, t)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	return []object.Value{object.String(s)}, nil
    66  }
    67  
    68  func difftime(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
    69  	ap := fnutil.NewArgParser(th, args)
    70  
    71  	t2, err := ap.ToGoInt64(0)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	t1, err := ap.ToGoInt64(1)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  
    81  	return []object.Value{object.Integer(t2 - t1)}, nil
    82  }
    83  
    84  func execute(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
    85  	if len(args) == 0 {
    86  		return []object.Value{object.True}, nil
    87  	}
    88  
    89  	ap := fnutil.NewArgParser(th, args)
    90  
    91  	prog, err := ap.ToGoString(0)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	progArgs := strings.Fields(prog)
    97  
    98  	cmd := exec.Command(progArgs[0], progArgs[1:]...)
    99  	cmd.Stdin = os.Stdin
   100  	cmd.Stdout = os.Stdout
   101  	cmd.Stderr = os.Stderr
   102  
   103  	return execResult(th, cmd.Run())
   104  }
   105  
   106  // close is not supportted.
   107  // exit([code [, close]])
   108  func exit(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
   109  	if len(args) == 0 {
   110  		os.Exit(0)
   111  	}
   112  
   113  	ap := fnutil.NewArgParser(th, args)
   114  
   115  	i, err := ap.ToGoInt(0)
   116  	if err == nil {
   117  		os.Exit(i)
   118  	}
   119  
   120  	val, _ := ap.Get(0)
   121  
   122  	if b, ok := val.(object.Boolean); ok {
   123  		if b {
   124  			os.Exit(1)
   125  		}
   126  
   127  		os.Exit(0)
   128  	}
   129  
   130  	return nil, ap.TypeError(0, "integer or boolean")
   131  }
   132  
   133  // getenv(varname)
   134  func getenv(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
   135  	ap := fnutil.NewArgParser(th, args)
   136  
   137  	key, err := ap.ToGoString(0)
   138  	if err != nil {
   139  		return nil, err
   140  	}
   141  
   142  	val := os.Getenv(key)
   143  
   144  	if val == "" {
   145  		return []object.Value{nil}, nil
   146  	}
   147  
   148  	return []object.Value{object.String(val)}, nil
   149  }
   150  
   151  // remove(filename)
   152  func remove(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
   153  	ap := fnutil.NewArgParser(th, args)
   154  
   155  	name, err := ap.ToGoString(0)
   156  	if err != nil {
   157  		return nil, err
   158  	}
   159  
   160  	return fileResult(th, os.Remove(name))
   161  }
   162  
   163  // rename(oldname, newname)
   164  func rename(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
   165  	ap := fnutil.NewArgParser(th, args)
   166  
   167  	old, err := ap.ToGoString(0)
   168  	if err != nil {
   169  		return nil, err
   170  	}
   171  
   172  	_new, err := ap.ToGoString(1)
   173  	if err != nil {
   174  		return nil, err
   175  	}
   176  
   177  	return fileResult(th, os.Rename(old, _new))
   178  }
   179  
   180  // setlocale(locale [, category])
   181  func setlocale(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
   182  	return nil, object.NewRuntimeError("not implemented")
   183  }
   184  
   185  func getGoInt(th object.Thread, tab object.Table, key string) (int, *object.RuntimeError) {
   186  	val := tab.Get(object.String(key))
   187  	if val == nil {
   188  		return 0, object.NewRuntimeError(fmt.Sprintf("field '%s' missing in date table", key))
   189  	}
   190  	if i, ok := object.ToGoInt(val); ok {
   191  		return i, nil
   192  	}
   193  	return 0, object.NewRuntimeError(fmt.Sprintf("field '%s' is not an integer", key))
   194  }
   195  
   196  func _time(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
   197  	if len(args) == 0 || args[0] == nil {
   198  		return []object.Value{object.Integer(time.Now().Unix())}, nil
   199  	}
   200  
   201  	ap := fnutil.NewArgParser(th, args)
   202  
   203  	tab, err := ap.ToTable(0)
   204  	if err != nil {
   205  		return nil, err
   206  	}
   207  
   208  	day, err := getGoInt(th, tab, "day")
   209  	if err != nil {
   210  		return nil, err
   211  	}
   212  	month, err := getGoInt(th, tab, "month")
   213  	if err != nil {
   214  		return nil, err
   215  	}
   216  	year, err := getGoInt(th, tab, "year")
   217  	if err != nil {
   218  		return nil, err
   219  	}
   220  	sec, _ := getGoInt(th, tab, "sec")
   221  	min, _ := getGoInt(th, tab, "min")
   222  	hour := 12
   223  	if val := tab.Get(object.String("hour")); val != nil {
   224  		i, ok := object.ToGoInt(val)
   225  		if !ok {
   226  			return nil, object.NewRuntimeError(fmt.Sprintf("field '%s' is not an integer", "hour"))
   227  		}
   228  		hour = i
   229  	}
   230  
   231  	var unix int64
   232  	if sec < 0 {
   233  		t := time.Date(year, time.Month(month), day, hour, min, 0, 0, time.Local)
   234  
   235  		t = t.Add(time.Duration(sec) * time.Second)
   236  
   237  		updateTable(th, tab, t)
   238  
   239  		unix = t.Unix()
   240  	} else {
   241  		unix = time.Date(year, time.Month(month), day, hour, min, sec, 0, time.Local).Unix()
   242  	}
   243  
   244  	return []object.Value{object.Integer(unix)}, nil
   245  }
   246  
   247  func tmpname(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
   248  	f, err := ioutil.TempFile("", "plua")
   249  	if err != nil {
   250  		return nil, object.NewRuntimeError(err.Error())
   251  	}
   252  
   253  	err = f.Close()
   254  	if err != nil {
   255  		return nil, object.NewRuntimeError(err.Error())
   256  	}
   257  
   258  	err = os.Remove(f.Name())
   259  	if err != nil {
   260  		return nil, object.NewRuntimeError(err.Error())
   261  	}
   262  
   263  	return []object.Value{object.String(f.Name())}, nil
   264  }
   265  
   266  func Open(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
   267  	m := th.NewTableSize(0, 11)
   268  
   269  	m.Set(object.String("clock"), object.GoFunction(clock))
   270  	m.Set(object.String("date"), object.GoFunction(date))
   271  	m.Set(object.String("difftime"), object.GoFunction(difftime))
   272  	m.Set(object.String("execute"), object.GoFunction(execute))
   273  	m.Set(object.String("exit"), object.GoFunction(exit))
   274  	m.Set(object.String("getenv"), object.GoFunction(getenv))
   275  	m.Set(object.String("remove"), object.GoFunction(remove))
   276  	m.Set(object.String("rename"), object.GoFunction(rename))
   277  	m.Set(object.String("setlocale"), object.GoFunction(setlocale))
   278  	m.Set(object.String("time"), object.GoFunction(_time))
   279  	m.Set(object.String("tmpname"), object.GoFunction(tmpname))
   280  
   281  	return []object.Value{m}, nil
   282  }