~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/cmd/fix/osopen.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2011 The Go 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
 
        "go/ast"
9
 
)
10
 
 
11
 
func init() {
12
 
        register(osopenFix)
13
 
}
14
 
 
15
 
var osopenFix = fix{
16
 
        "osopen",
17
 
        "2011-04-04",
18
 
        osopen,
19
 
        `Adapt os.Open calls to new, easier API and rename O_CREAT O_CREATE.
20
 
 
21
 
http://codereview.appspot.com/4357052
22
 
`,
23
 
}
24
 
 
25
 
func osopen(f *ast.File) bool {
26
 
        if !imports(f, "os") {
27
 
                return false
28
 
        }
29
 
 
30
 
        fixed := false
31
 
        walk(f, func(n interface{}) {
32
 
                // Rename O_CREAT to O_CREATE.
33
 
                if expr, ok := n.(ast.Expr); ok && isPkgDot(expr, "os", "O_CREAT") {
34
 
                        expr.(*ast.SelectorExpr).Sel.Name = "O_CREATE"
35
 
                        fixed = true
36
 
                        return
37
 
                }
38
 
 
39
 
                // Fix up calls to Open.
40
 
                call, ok := n.(*ast.CallExpr)
41
 
                if !ok || len(call.Args) != 3 {
42
 
                        return
43
 
                }
44
 
                if !isPkgDot(call.Fun, "os", "Open") {
45
 
                        return
46
 
                }
47
 
                sel := call.Fun.(*ast.SelectorExpr)
48
 
                args := call.Args
49
 
                // os.Open(a, os.O_RDONLY, c) -> os.Open(a)
50
 
                if isPkgDot(args[1], "os", "O_RDONLY") || isPkgDot(args[1], "syscall", "O_RDONLY") {
51
 
                        call.Args = call.Args[0:1]
52
 
                        fixed = true
53
 
                        return
54
 
                }
55
 
                // os.Open(a, createlike_flags, c) -> os.Create(a, c)
56
 
                if isCreateFlag(args[1]) {
57
 
                        sel.Sel.Name = "Create"
58
 
                        if !isSimplePerm(args[2]) {
59
 
                                warn(sel.Pos(), "rewrote os.Open to os.Create with permission not 0666")
60
 
                        }
61
 
                        call.Args = args[0:1]
62
 
                        fixed = true
63
 
                        return
64
 
                }
65
 
                // Fallback: os.Open(a, b, c) -> os.OpenFile(a, b, c)
66
 
                sel.Sel.Name = "OpenFile"
67
 
                fixed = true
68
 
        })
69
 
        return fixed
70
 
}
71
 
 
72
 
func isCreateFlag(flag ast.Expr) bool {
73
 
        foundCreate := false
74
 
        foundTrunc := false
75
 
        // OR'ing of flags: is O_CREATE on?  + or | would be fine; we just look for os.O_CREATE
76
 
        // and don't worry about the actual operator.
77
 
        p := flag.Pos()
78
 
        for {
79
 
                lhs := flag
80
 
                expr, isBinary := flag.(*ast.BinaryExpr)
81
 
                if isBinary {
82
 
                        lhs = expr.Y
83
 
                }
84
 
                sel, ok := lhs.(*ast.SelectorExpr)
85
 
                if !ok || !isTopName(sel.X, "os") {
86
 
                        return false
87
 
                }
88
 
                switch sel.Sel.Name {
89
 
                case "O_CREATE":
90
 
                        foundCreate = true
91
 
                case "O_TRUNC":
92
 
                        foundTrunc = true
93
 
                case "O_RDONLY", "O_WRONLY", "O_RDWR":
94
 
                        // okay 
95
 
                default:
96
 
                        // Unexpected flag, like O_APPEND or O_EXCL.
97
 
                        // Be conservative and do not rewrite.
98
 
                        return false
99
 
                }
100
 
                if !isBinary {
101
 
                        break
102
 
                }
103
 
                flag = expr.X
104
 
        }
105
 
        if !foundCreate {
106
 
                return false
107
 
        }
108
 
        if !foundTrunc {
109
 
                warn(p, "rewrote os.Open with O_CREATE but not O_TRUNC to os.Create")
110
 
        }
111
 
        return foundCreate
112
 
}
113
 
 
114
 
func isSimplePerm(perm ast.Expr) bool {
115
 
        basicLit, ok := perm.(*ast.BasicLit)
116
 
        if !ok {
117
 
                return false
118
 
        }
119
 
        switch basicLit.Value {
120
 
        case "0666":
121
 
                return true
122
 
        }
123
 
        return false
124
 
}