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 }