OLD | NEW |
1 // Copyright 2013 The Go Authors. All rights reserved. | 1 // Copyright 2013 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // +build ignore | 5 // +build ignore |
6 | 6 |
7 /* | 7 /* |
8 mksyscall_windows generates windows system call bodies | 8 mksyscall_windows generates windows system call bodies |
9 | 9 |
10 It parses all files specified on command line containing function | 10 It parses all files specified on command line containing function |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 func trim(s string) string { | 62 func trim(s string) string { |
63 return strings.Trim(s, " \t") | 63 return strings.Trim(s, " \t") |
64 } | 64 } |
65 | 65 |
66 var packageName string | 66 var packageName string |
67 | 67 |
68 func packagename() string { | 68 func packagename() string { |
69 return packageName | 69 return packageName |
70 } | 70 } |
71 | 71 |
72 func syscalldot() string { | 72 func windowsdot() string { |
73 » if packageName == "syscall" { | 73 » if packageName == "windows" { |
74 return "" | 74 return "" |
75 } | 75 } |
76 » return "syscall." | 76 » return "windows." |
77 } | 77 } |
78 | 78 |
79 // Param is function parameter | 79 // Param is function parameter |
80 type Param struct { | 80 type Param struct { |
81 Name string | 81 Name string |
82 Type string | 82 Type string |
83 fn *Fn | 83 fn *Fn |
84 tmpVarIdx int | 84 tmpVarIdx int |
85 } | 85 } |
86 | 86 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 if e1 != 0 { | 258 if e1 != 0 { |
259 err = error(e1) | 259 err = error(e1) |
260 } else { | 260 } else { |
261 err = %sEINVAL | 261 err = %sEINVAL |
262 } | 262 } |
263 }` | 263 }` |
264 cond := retvar + " == 0" | 264 cond := retvar + " == 0" |
265 if r.FailCond != "" { | 265 if r.FailCond != "" { |
266 cond = strings.Replace(r.FailCond, "failretval", retvar, 1) | 266 cond = strings.Replace(r.FailCond, "failretval", retvar, 1) |
267 } | 267 } |
268 » return fmt.Sprintf(code, cond, syscalldot()) | 268 » return fmt.Sprintf(code, cond, windowsdot()) |
269 } | 269 } |
270 | 270 |
271 // SetErrorCode returns source code that sets return parameters. | 271 // SetErrorCode returns source code that sets return parameters. |
272 func (r *Rets) SetErrorCode() string { | 272 func (r *Rets) SetErrorCode() string { |
273 const code = `if r0 != 0 { | 273 const code = `if r0 != 0 { |
274 %s = %sErrno(r0) | 274 %s = %sErrno(r0) |
275 }` | 275 }` |
276 if r.Name == "" && !r.ReturnsError { | 276 if r.Name == "" && !r.ReturnsError { |
277 return "" | 277 return "" |
278 } | 278 } |
279 if r.Name == "" { | 279 if r.Name == "" { |
280 return r.useLongHandleErrorCode("r1") | 280 return r.useLongHandleErrorCode("r1") |
281 } | 281 } |
282 if r.Type == "error" { | 282 if r.Type == "error" { |
283 » » return fmt.Sprintf(code, r.Name, syscalldot()) | 283 » » return fmt.Sprintf(code, r.Name, windowsdot()) |
284 } | 284 } |
285 s := "" | 285 s := "" |
286 switch { | 286 switch { |
287 case r.Type[0] == '*': | 287 case r.Type[0] == '*': |
288 s = fmt.Sprintf("%s = (%s)(unsafe.Pointer(r0))", r.Name, r.Type) | 288 s = fmt.Sprintf("%s = (%s)(unsafe.Pointer(r0))", r.Name, r.Type) |
289 case r.Type == "bool": | 289 case r.Type == "bool": |
290 s = fmt.Sprintf("%s = r0 != 0", r.Name) | 290 s = fmt.Sprintf("%s = r0 != 0", r.Name) |
291 default: | 291 default: |
292 s = fmt.Sprintf("%s = %s(r0)", r.Name, r.Type) | 292 s = fmt.Sprintf("%s = %s(r0)", r.Name, r.Type) |
293 } | 293 } |
294 if !r.ReturnsError { | 294 if !r.ReturnsError { |
295 return s | 295 return s |
296 } | 296 } |
297 return s + "\n\t" + r.useLongHandleErrorCode(r.Name) | 297 return s + "\n\t" + r.useLongHandleErrorCode(r.Name) |
298 } | 298 } |
299 | 299 |
300 // Fn describes syscall function. | 300 // Fn describes a syscall function. |
301 type Fn struct { | 301 type Fn struct { |
302 Name string | 302 Name string |
303 Params []*Param | 303 Params []*Param |
304 Rets *Rets | 304 Rets *Rets |
305 PrintTrace bool | 305 PrintTrace bool |
306 dllname string | 306 dllname string |
307 dllfuncname string | 307 dllfuncname string |
308 src string | 308 src string |
309 // TODO: get rid of this field and just use parameter index instead | 309 // TODO: get rid of this field and just use parameter index instead |
310 curTmpVarIdx int // insure tmp variables have uniq names | 310 curTmpVarIdx int // insure tmp variables have uniq names |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 return 15 | 486 return 15 |
487 default: | 487 default: |
488 panic("too many arguments to system call") | 488 panic("too many arguments to system call") |
489 } | 489 } |
490 } | 490 } |
491 | 491 |
492 // Syscall determines which SyscallX function to use for function f. | 492 // Syscall determines which SyscallX function to use for function f. |
493 func (f *Fn) Syscall() string { | 493 func (f *Fn) Syscall() string { |
494 c := f.SyscallParamCount() | 494 c := f.SyscallParamCount() |
495 if c == 3 { | 495 if c == 3 { |
496 » » return syscalldot() + "Syscall" | 496 » » return windowsdot() + "Syscall" |
497 } | 497 } |
498 » return syscalldot() + "Syscall" + strconv.Itoa(c) | 498 » return windowsdot() + "Syscall" + strconv.Itoa(c) |
499 } | 499 } |
500 | 500 |
501 // SyscallParamList returns source code for SyscallX parameters for function f. | 501 // SyscallParamList returns source code for SyscallX parameters for function f. |
502 func (f *Fn) SyscallParamList() string { | 502 func (f *Fn) SyscallParamList() string { |
503 a := make([]string, 0) | 503 a := make([]string, 0) |
504 for _, p := range f.Params { | 504 for _, p := range f.Params { |
505 a = append(a, p.SyscallArgList()...) | 505 a = append(a, p.SyscallArgList()...) |
506 } | 506 } |
507 for len(a) < f.SyscallParamCount() { | 507 for len(a) < f.SyscallParamCount() { |
508 a = append(a, "0") | 508 a = append(a, "0") |
509 } | 509 } |
510 return strings.Join(a, ", ") | 510 return strings.Join(a, ", ") |
511 } | 511 } |
512 | 512 |
513 // IsUTF16 is true, if f is W (utf16) function. It is false | 513 // IsUTF16 is true, if f is W (utf16) function. It is false |
514 // for all A (ascii) functions. | 514 // for all A (ascii) functions. |
515 func (f *Fn) IsUTF16() bool { | 515 func (f *Fn) IsUTF16() bool { |
516 s := f.DLLFuncName() | 516 s := f.DLLFuncName() |
517 return s[len(s)-1] == 'W' | 517 return s[len(s)-1] == 'W' |
518 } | 518 } |
519 | 519 |
520 // StrconvFunc returns name of Go string to OS string function for f. | 520 // StrconvFunc returns name of Go string to OS string function for f. |
521 func (f *Fn) StrconvFunc() string { | 521 func (f *Fn) StrconvFunc() string { |
522 if f.IsUTF16() { | 522 if f.IsUTF16() { |
523 » » return syscalldot() + "UTF16PtrFromString" | 523 » » return windowsdot() + "UTF16PtrFromString" |
524 } | 524 } |
525 » return syscalldot() + "BytePtrFromString" | 525 » return windowsdot() + "BytePtrFromString" |
526 } | 526 } |
527 | 527 |
528 // StrconvType returns Go type name used for OS string for f. | 528 // StrconvType returns Go type name used for OS string for f. |
529 func (f *Fn) StrconvType() string { | 529 func (f *Fn) StrconvType() string { |
530 if f.IsUTF16() { | 530 if f.IsUTF16() { |
531 return "*uint16" | 531 return "*uint16" |
532 } | 532 } |
533 return "*byte" | 533 return "*byte" |
534 } | 534 } |
535 | 535 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 return err | 612 return err |
613 } | 613 } |
614 packageName = pkg.Name.Name | 614 packageName = pkg.Name.Name |
615 | 615 |
616 return nil | 616 return nil |
617 } | 617 } |
618 | 618 |
619 // Generate output source file from a source set src. | 619 // Generate output source file from a source set src. |
620 func (src *Source) Generate(w io.Writer) error { | 620 func (src *Source) Generate(w io.Writer) error { |
621 funcMap := template.FuncMap{ | 621 funcMap := template.FuncMap{ |
622 » » "syscalldot": syscalldot, | 622 » » "windowsdot": windowsdot, |
623 "packagename": packagename, | 623 "packagename": packagename, |
624 } | 624 } |
625 t := template.Must(template.New("main").Funcs(funcMap).Parse(srcTemplate
)) | 625 t := template.Must(template.New("main").Funcs(funcMap).Parse(srcTemplate
)) |
626 err := t.Execute(w, src) | 626 err := t.Execute(w, src) |
627 if err != nil { | 627 if err != nil { |
628 return errors.New("Failed to execute template: " + err.Error()) | 628 return errors.New("Failed to execute template: " + err.Error()) |
629 } | 629 } |
630 return nil | 630 return nil |
631 } | 631 } |
632 | 632 |
(...skipping 20 matching lines...) Expand all Loading... |
653 } | 653 } |
654 | 654 |
655 // TODO: use println instead to print in the following template | 655 // TODO: use println instead to print in the following template |
656 const srcTemplate = ` | 656 const srcTemplate = ` |
657 | 657 |
658 {{define "main"}}// go build mksyscall_windows.go && ./mksyscall_windows{{range
.Files}} {{.}}{{end}} | 658 {{define "main"}}// go build mksyscall_windows.go && ./mksyscall_windows{{range
.Files}} {{.}}{{end}} |
659 // MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT | 659 // MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT |
660 | 660 |
661 package {{packagename}} | 661 package {{packagename}} |
662 | 662 |
663 import "unsafe"{{if syscalldot}} | 663 import "unsafe"{{if windowsdot}} |
664 import "syscall"{{end}} | 664 import "windows"{{end}} |
665 | 665 |
666 var ( | 666 var ( |
667 {{template "dlls" .}} | 667 {{template "dlls" .}} |
668 {{template "funcnames" .}}) | 668 {{template "funcnames" .}}) |
669 {{range .Funcs}}{{template "funcbody" .}}{{end}} | 669 {{range .Funcs}}{{template "funcbody" .}}{{end}} |
670 {{end}} | 670 {{end}} |
671 | 671 |
672 {{/* help functions */}} | 672 {{/* help functions */}} |
673 | 673 |
674 {{define "dlls"}}{{range .DLLs}}» mod{{.}} = {{syscalldot}}NewLazyDLL("{{.
}}.dll") | 674 {{define "dlls"}}{{range .DLLs}}» mod{{.}} = {{windowsdot}}NewLazyDLL("{{.
}}.dll") |
675 {{end}}{{end}} | 675 {{end}}{{end}} |
676 | 676 |
677 {{define "funcnames"}}{{range .Funcs}} proc{{.DLLFuncName}} = mod{{.DLLName}}.N
ewProc("{{.DLLFuncName}}") | 677 {{define "funcnames"}}{{range .Funcs}} proc{{.DLLFuncName}} = mod{{.DLLName}}.N
ewProc("{{.DLLFuncName}}") |
678 {{end}}{{end}} | 678 {{end}}{{end}} |
679 | 679 |
680 {{define "funcbody"}} | 680 {{define "funcbody"}} |
681 func {{.Name}}({{.ParamList}}) {{if .Rets.List}}{{.Rets.List}} {{end}}{ | 681 func {{.Name}}({{.ParamList}}) {{if .Rets.List}}{{.Rets.List}} {{end}}{ |
682 {{template "tmpvars" .}} {{template "syscall" .}} | 682 {{template "tmpvars" .}} {{template "syscall" .}} |
683 {{template "seterror" .}}{{template "printtrace" .}} return | 683 {{template "seterror" .}}{{template "printtrace" .}} return |
684 } | 684 } |
685 {{end}} | 685 {{end}} |
686 | 686 |
687 {{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}} | 687 {{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}} |
688 {{end}}{{end}}{{end}} | 688 {{end}}{{end}}{{end}} |
689 | 689 |
690 {{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName
}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}} | 690 {{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName
}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}} |
691 | 691 |
692 {{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}} | 692 {{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}} |
693 {{end}}{{end}} | 693 {{end}}{{end}} |
694 | 694 |
695 {{define "printtrace"}}{{if .PrintTrace}} print("SYSCALL: {{.Name}}(", {{.
ParamPrintList}}") (", {{.Rets.PrintList}}")\n") | 695 {{define "printtrace"}}{{if .PrintTrace}} print("SYSCALL: {{.Name}}(", {{.
ParamPrintList}}") (", {{.Rets.PrintList}}")\n") |
696 {{end}}{{end}} | 696 {{end}}{{end}} |
697 | 697 |
698 ` | 698 ` |
OLD | NEW |