1 // Inferno utils/6a/a.h and lex.c.
2 // http://code.google.com/p/inferno-os/source/browse/utils/6a/a.h
3 // http://code.google.com/p/inferno-os/source/browse/utils/6a/lex.c
5 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
6 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
7 // Portions Copyright © 1997-1999 Vita Nuova Limited
8 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
9 // Portions Copyright © 2004,2006 Bruce Ellis
10 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
11 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
12 // Portions Copyright © 2009 The Go Authors. All rights reserved.
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to deal
16 // in the Software without restriction, including without limitation the rights
17 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 // copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
21 // The above copyright notice and this permission notice shall be included in
22 // all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
32 // Package asm holds code shared among the assemblers.
47 // Initialized by client.
58 Thelinkarch *obj.LinkArch
60 Arches map[string]*obj.LinkArch
129 hash = map[string]*Sym{}
155 func dodef(p string) {
156 Dlist = append(Dlist, p)
160 fmt.Printf("usage: %ca [options] file.c...\n", Thechar)
168 // Allow GOARCH=Thestring or GOARCH=Thestringsuffix,
169 // but not other values.
172 if !strings.HasPrefix(p, Thestring) {
173 log.Fatalf("cannot use %cc with GOARCH=%s", Thechar, p)
176 Thelinkarch = Arches[p]
177 if Thelinkarch == nil {
178 log.Fatalf("unknown arch %s", p)
182 Ctxt = obj.Linknew(Thelinkarch)
185 Ctxt.Enforce_data_order = 1
186 bstdout = *obj.Binitw(os.Stdout)
193 flag.Var(flagFn(dodef), "D", "name[=value]: add #define")
194 flag.Var(flagFn(setinclude), "I", "dir: add dir to include path")
195 flag.Var((*count)(&debug['S']), "S", "print assembly and machine code")
196 flag.Var((*count)(&debug['m']), "m", "debug preprocessor macros")
197 flag.StringVar(&outfile, "o", "", "file: set output file")
198 flag.StringVar(&Ctxt.Trimpath, "trimpath", "", "prefix: remove prefix from recorded source file paths")
202 Ctxt.Debugasm = int32(debug['S'])
208 fmt.Printf("can't assemble multiple files\n")
212 if assemble(flag.Arg(0)) != 0 {
221 func assemble(file string) int {
225 outfile = strings.TrimSuffix(filepath.Base(file), ".s") + "." + string(Thechar)
228 of, err := os.Create(outfile)
230 Yyerror("%ca: cannot create %s", Thechar, outfile)
234 obuf = *obj.Binitw(of)
235 fmt.Fprintf(&obuf, "go object %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion())
236 fmt.Fprintf(&obuf, "!\n")
238 for Pass = 1; Pass <= 2; Pass++ {
240 for i = 0; i < len(Dlist); i++ {
250 obj.Writeobjdirect(Ctxt, &obuf)
256 for i := 0; i < len(Lexinit); i++ {
257 s := Lookup(Lexinit[i].Name)
259 Yyerror("double initialization %s", Lexinit[i].Name)
261 s.Type = Lexinit[i].Type
262 s.Value = Lexinit[i].Value
266 func syminit(s *Sym) {
271 type flagFn func(string)
273 func (flagFn) String() string {
277 func (f flagFn) Set(s string) error {
284 // count is a flag.Value that is like a flag.Bool and a flag.Int.
285 // If used as -name, it increments the count, but -name=x sets the count.
286 // Used for verbose flag -v.
289 func (c *count) String() string {
290 return fmt.Sprint(int(*c))
293 func (c *count) Set(s string) error {
300 n, err := strconv.Atoi(s)
302 return fmt.Errorf("invalid count %q", s)
309 func (c *count) IsBoolFlag() bool {