Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
ac0dd5ae
Commit
ac0dd5ae
authored
Jul 23, 2008
by
Rob Pike
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a flags package.
R=gri OCL=13399 CL=13399
parent
5a30b5b8
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
444 additions
and
3 deletions
+444
-3
src/lib/flag.go
src/lib/flag.go
+439
-0
src/lib/fmt.go
src/lib/fmt.go
+1
-1
src/lib/make.bash
src/lib/make.bash
+4
-2
No files found.
src/lib/flag.go
0 → 100644
View file @
ac0dd5ae
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
flag
/*
* Flags
*
* Usage:
* 1) Define flags using flag.String(), Bool(), or Int(). Int flag values have type int64. Example:
* import flag "flag"
* var i int64
* var fi *flag.Flag = flag.Int("flagname", 1234, &i, "help message for flagname")
* The pointer may be nil; if non-nil, it points to a cell of the appropriate type to store the
* flag's value.
*
* 2) After all flags are defined, call
* flag.Parse()
* to parse the command line into the defined flags.
*
* 3) Flags may then be used directly (getters are SVal, BVal, Ival) or through the associated
* cell, if set:
* print "fi has value ", fi.IVal(), "\n";
* print "i has value ", i, "\n";
*
* 4) After parsing, flag.Arg(i) is the i'th argument after the flags.
* Args are indexed from 0 up to flag.NArg().
*
* Command line flag syntax:
* -flag
* -flag=x
* -flag x
* One or two minus signs may be used; they are equivalent.
* A lone -- terminates the parsing of the command line.
* Integer flags accept 1234, 0664, 0x1234 and may be negative.
* Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
*/
export
Bool
,
Int
,
String
export
Arg
,
NArg
export
Parse
//export Flag.BVal BUG: variable exported but not defined: Flag.BVal
//export Flag.SVal BUG: variable exported but not defined: Flag.SVal
export
Flag
// BUG: ctoi, atoi, atob belong elsewhere
func
ctoi
(
c
int64
)
int64
{
if
'0'
<=
c
&&
c
<=
'9'
{
return
c
-
'0'
}
if
'a'
<=
c
&&
c
<=
'f'
{
return
c
-
'a'
}
if
'A'
<=
c
&&
c
<=
'F'
{
return
c
-
'A'
}
return
1000
// too large for any base
}
func
atoi
(
s
string
)
(
value
int64
,
ok
bool
)
{
if
len
(
s
)
==
0
{
return
0
,
false
}
if
s
[
0
]
==
'-'
{
n
,
t
:=
atoi
(
s
[
1
:
len
(
s
)]);
return
-
n
,
t
}
var
base
int64
=
10
;
i
:=
0
;
if
s
[
0
]
==
'0'
{
base
=
8
if
len
(
s
)
>
1
&&
(
s
[
1
]
==
'x'
||
s
[
1
]
==
'X'
)
{
base
=
16
;
i
+=
2
;
}
}
var
n
int64
=
0
for
;
i
<
len
(
s
);
i
++
{
k
:=
ctoi
(
int64
(
s
[
i
]));
if
k
>=
base
{
return
0
,
false
}
n
=
n
*
base
+
k
}
return
n
,
true
}
func
atob
(
str
string
)
(
value
bool
,
ok
bool
)
{
switch
str
{
case
"1"
,
"t"
,
"T"
,
"true"
,
"TRUE"
,
"True"
:
return
true
,
true
case
"0"
,
"f"
,
"F"
,
"false"
,
"FALSE"
,
"False"
:
return
false
,
true
}
return
false
,
false
}
// -- Bool Value
type
BoolValue
struct
{
val
bool
;
p
*
bool
;
}
func
(
b
*
BoolValue
)
AsBool
()
*
BoolValue
{
return
b
}
func
(
b
*
BoolValue
)
AsInt
()
*
IntValue
{
return
nil
}
func
(
b
*
BoolValue
)
AsString
()
*
StringValue
{
return
nil
}
func
(
b
*
BoolValue
)
IsBool
()
bool
{
return
true
}
func
(
b
*
BoolValue
)
IsInt
()
bool
{
return
false
}
func
(
b
*
BoolValue
)
IsString
()
bool
{
return
false
}
func
(
b
*
BoolValue
)
ValidValue
(
str
string
)
bool
{
i
,
ok
:=
atob
(
str
);
return
ok
;
}
func
(
b
*
BoolValue
)
Set
(
val
bool
)
{
if
b
.
p
!=
nil
{
*
b
.
p
=
val
}
b
.
val
=
val
}
func
NewBoolValue
(
b
bool
,
p
*
bool
)
*
BoolValue
{
v
:=
new
(
BoolValue
);
v
.
val
=
b
;
v
.
p
=
p
;
return
v
;
}
// -- Int Value
type
IntValue
struct
{
val
int64
;
p
*
int64
;
}
func
(
i
*
IntValue
)
AsBool
()
*
BoolValue
{
return
nil
}
func
(
i
*
IntValue
)
AsInt
()
*
IntValue
{
return
i
}
func
(
i
*
IntValue
)
AsString
()
*
StringValue
{
return
nil
}
func
(
i
*
IntValue
)
IsBool
()
bool
{
return
false
}
func
(
i
*
IntValue
)
IsInt
()
bool
{
return
true
}
func
(
i
*
IntValue
)
IsString
()
bool
{
return
false
}
func
(
i
*
IntValue
)
ValidValue
(
str
string
)
bool
{
k
,
ok
:=
atoi
(
str
);
return
ok
;
}
func
(
i
*
IntValue
)
Set
(
val
int64
)
{
if
i
.
p
!=
nil
{
*
i
.
p
=
val
}
i
.
val
=
val
}
func
NewIntValue
(
i
int64
,
p
*
int64
)
*
IntValue
{
v
:=
new
(
IntValue
);
v
.
val
=
i
;
v
.
p
=
p
;
return
v
;
}
// -- String Value
type
StringValue
struct
{
val
string
;
p
*
string
;
}
func
(
e
*
StringValue
)
AsBool
()
*
BoolValue
{
return
nil
}
func
(
e
*
StringValue
)
AsInt
()
*
IntValue
{
return
nil
}
func
(
s
*
StringValue
)
AsString
()
*
StringValue
{
return
s
}
func
(
s
*
StringValue
)
IsBool
()
bool
{
return
false
}
func
(
s
*
StringValue
)
IsInt
()
bool
{
return
false
}
func
(
s
*
StringValue
)
IsString
()
bool
{
return
true
}
func
(
s
*
StringValue
)
ValidValue
(
str
string
)
bool
{
return
true
}
func
(
s
*
StringValue
)
Set
(
val
string
)
{
if
s
.
p
!=
nil
{
*
s
.
p
=
val
}
s
.
val
=
val
}
func
NewStringValue
(
s
string
,
p
*
string
)
*
StringValue
{
v
:=
new
(
StringValue
);
v
.
val
=
s
;
v
.
p
=
p
;
return
v
;
}
// -- Value interface
type
Value
interface
{
AsBool
()
*
BoolValue
;
AsInt
()
*
IntValue
;
AsString
()
*
StringValue
;
IsBool
()
bool
;
IsInt
()
bool
;
IsString
()
bool
;
ValidValue
(
str
string
)
bool
;
}
// -- Flag structure (internal)
type
Flag
struct
{
name
string
;
usage
string
;
value
Value
;
}
type
Flags
struct
{
actual
*
map
[
string
]
*
Flag
;
formal
*
map
[
string
]
*
Flag
;
first_arg
int
;
}
// --Customer's value getters
func
(
f
*
Flag
)
BVal
()
bool
{
if
!
f
.
value
.
IsBool
()
{
return
false
;
}
return
f
.
value
.
AsBool
()
.
val
;
}
func
(
f
*
Flag
)
IVal
()
int64
{
if
!
f
.
value
.
IsInt
()
{
return
0
}
return
f
.
value
.
AsInt
()
.
val
;
}
func
(
f
*
Flag
)
SVal
()
string
{
if
!
f
.
value
.
IsString
()
{
return
"???"
;
}
return
f
.
value
.
AsString
()
.
val
;
}
func
New
()
*
Flags
{
f
:=
new
(
Flags
);
f
.
first_arg
=
1
;
// 0 is the program name, 1 is first arg
f
.
actual
=
new
(
map
[
string
]
*
Flag
);
f
.
formal
=
new
(
map
[
string
]
*
Flag
);
return
f
;
}
var
flags
*
Flags
=
New
();
func
Arg
(
i
int
)
string
{
i
+=
flags
.
first_arg
;
if
i
<
0
||
i
>=
sys
.
argc
()
{
return
""
;
}
return
sys
.
argv
(
i
)
}
func
NArg
()
int32
{
return
sys
.
argc
()
-
flags
.
first_arg
}
func
Add
(
name
string
,
value
Value
,
usage
string
)
*
Flag
{
f
:=
new
(
Flag
);
f
.
name
=
name
;
f
.
usage
=
usage
;
f
.
value
=
value
;
dummy
,
alreadythere
:=
flags
.
formal
[
name
];
if
alreadythere
{
print
"flag redefined: "
,
name
,
"
\n
"
;
panic
"flag redefinition"
}
flags
.
formal
[
name
]
=
f
;
return
f
;
}
func
Bool
(
name
string
,
value
bool
,
p
*
bool
,
usage
string
)
*
Flag
{
return
Add
(
name
,
NewBoolValue
(
value
,
p
),
usage
);
}
func
Int
(
name
string
,
value
int64
,
p
*
int64
,
usage
string
)
*
Flag
{
return
Add
(
name
,
NewIntValue
(
value
,
p
),
usage
);
}
func
String
(
name
,
value
string
,
p
*
string
,
usage
string
)
*
Flag
{
return
Add
(
name
,
NewStringValue
(
value
,
p
),
usage
);
}
func
(
f
*
Flags
)
ParseOne
(
index
int
)
(
ok
bool
,
next
int
)
{
s
:=
sys
.
argv
(
index
);
f
.
first_arg
=
index
;
// until proven otherwise
if
len
(
s
)
==
0
{
return
false
,
-
1
}
if
s
[
0
]
!=
'-'
{
return
false
,
-
1
}
num_minuses
:=
1
;
if
len
(
s
)
==
1
{
return
false
,
-
1
}
if
s
[
1
]
==
'-'
{
num_minuses
++
if
len
(
s
)
==
2
{
// "--" terminates the flags
return
false
,
index
+
1
}
}
name
:=
s
[
num_minuses
:
len
(
s
)];
if
len
(
name
)
==
0
||
name
[
0
]
==
'-'
||
name
[
0
]
==
'='
{
print
"bad flag syntax: "
,
s
,
"
\n
"
return
false
,
-
1
}
// it's a flag. does it have an argument?
has_value
:=
false
;
value
:=
""
;
for
i
:=
1
;
i
<
len
(
name
);
i
++
{
// equals cannot be first
if
name
[
i
]
==
'='
{
value
=
name
[
i
+
1
:
len
(
name
)];
has_value
=
true
;
name
=
name
[
0
:
i
];
break
;
}
}
flag
,
alreadythere
:=
flags
.
actual
[
name
];
if
alreadythere
{
print
"flag specified twice: -"
,
name
,
"
\n
"
return
false
,
-
1
}
m
:=
flags
.
formal
;
flag
,
alreadythere
=
m
[
name
];
// BUG
if
!
alreadythere
{
print
"flag provided but not defined: -"
,
name
,
"
\n
"
return
false
,
-
1
}
if
!
has_value
&&
index
<
sys
.
argc
()
-
1
&&
flag
.
value
.
ValidValue
(
sys
.
argv
(
index
+
1
))
{
// value is the next arg
has_value
=
true
;
index
++
;
value
=
sys
.
argv
(
index
);
}
switch
{
case
flag
.
value
.
IsBool
()
:
if
has_value
{
k
,
ok
:=
atob
(
value
);
if
!
ok
{
print
"invalid boolean value "
,
value
,
" for flag: -"
,
name
,
"
\n
"
return
false
,
-
1
}
flag
.
value
.
AsBool
()
.
Set
(
k
)
}
else
{
flag
.
value
.
AsBool
()
.
Set
(
true
)
}
case
flag
.
value
.
IsInt
()
:
if
!
has_value
{
print
"flag needs an argument: -"
,
name
,
"
\n
"
return
false
,
-
1
}
k
,
ok
:=
atoi
(
value
);
if
!
ok
{
print
"invalid integer value "
,
value
,
" for flag: -"
,
name
,
"
\n
"
return
false
,
-
1
}
flag
.
value
.
AsInt
()
.
Set
(
k
)
case
flag
.
value
.
IsString
()
:
if
!
has_value
{
print
"flag needs an argument: -"
,
name
,
"
\n
"
return
false
,
-
1
}
flag
.
value
.
AsString
()
.
Set
(
value
)
}
flags
.
actual
[
name
]
=
flag
;
return
true
,
index
+
1
}
func
Parse
()
{
for
i
:=
1
;
i
<
sys
.
argc
();
{
ok
,
next
:=
flags
.
ParseOne
(
i
);
if
next
>
0
{
flags
.
first_arg
=
next
;
i
=
next
;
}
if
!
ok
{
break
}
}
}
src/lib/fmt.go
View file @
ac0dd5ae
...
...
@@ -16,7 +16,7 @@ package fmt
export
Fmt
,
New
;
const
NByte
=
64
;
const
NPows10
=
160
;
// BUG: why not nelem(pows10);
const
NPows10
=
160
;
var
ldigits
string
=
"0123456789abcdef"
;
// BUG: Should be const
var
udigits
string
=
"0123456789ABCDEF"
;
// BUG: Should be const
...
...
src/lib/make.bash
View file @
ac0dd5ae
...
...
@@ -5,6 +5,8 @@
#!/bin/bash
rm
-f
*
.6
6g fmt.go
6g container/vector.go
for
i
in
flag.go fmt.go container/vector.go
do
6g
$i
done
mv
*
.6
$GOROOT
/pkg
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment