-
Notifications
You must be signed in to change notification settings - Fork 10.5k
/
Copy pathCommandLine.swift
122 lines (108 loc) · 4.39 KB
/
CommandLine.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftShims
#if SWIFT_STDLIB_HAS_COMMANDLINE
@_silgen_name("_swift_stdlib_getUnsafeArgvArgc")
internal func _swift_stdlib_getUnsafeArgvArgc(_: UnsafeMutablePointer<Int32>)
-> UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>
/// Command-line arguments for the current process.
@frozen // namespace
public enum CommandLine: ~BitwiseCopyable {}
extension CommandLine {
/// The backing static variable for argument count may come either from the
/// entry point or it may need to be computed e.g. if we're in the REPL.
@usableFromInline
internal static var _argc: Int32 = 0
/// The backing static variable for arguments may come either from the
/// entry point or it may need to be computed e.g. if we're in the REPL.
///
/// Care must be taken to ensure that `_swift_stdlib_getUnsafeArgvArgc` is
/// not invoked more times than is necessary (at most once).
@usableFromInline
internal static var _unsafeArgv:
UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>
= unsafe _swift_stdlib_getUnsafeArgvArgc(&_argc)
/// Access to the raw argc value from C.
public static var argc: Int32 {
// We intentionally ignore the argc value given to us from
// '_swift_stdlib_getUnsafeArgvArgc' because argv and argc are mutable, so
// someone can mutate the contents of argv and never update the argc value.
// This results in an out of sync argc which can lead to crashes on first
// access to 'CommandLine.arguments' due to attempting to read '0 ..< argc'
// strings.
//
// Note: It's still entirely possible that someone may update argv after
// this iteration and before we actually read argv, but we have no control
// over synchronizing access to argc and argv.
var argc: Int32 = 0
while let _ = unsafe _unsafeArgv[Int(argc)] {
argc += 1
}
return argc
}
/// Access to the raw argv value from C.
///
/// The value of this property is a `nil`-terminated C array. Including the
/// trailing `nil`, there are ``argc`` `+ 1` elements in the array.
///
/// - Note: Accessing the argument vector through this pointer is unsafe.
/// Where possible, use ``arguments`` instead.
public static var unsafeArgv:
UnsafeMutablePointer<UnsafeMutablePointer<Int8>?> {
return unsafe _unsafeArgv
}
// This is extremely unsafe and allows for concurrent writes with no
// synchronization to the underlying data. In a future version of Swift you
// will not be able to write to 'CommandLine.arguments'.
static nonisolated(unsafe) var _arguments: [String] = (0 ..< Int(argc)).map {
unsafe String(cString: _unsafeArgv[$0]!)
}
/// An array that provides access to this program's command line arguments.
///
/// Use `CommandLine.arguments` to access the command line arguments used
/// when executing the current program. The name of the executed program is
/// the first argument.
///
/// The following example shows a command line executable that squares the
/// integer given as an argument.
///
/// if CommandLine.arguments.count == 2,
/// let number = Int(CommandLine.arguments[1]) {
/// print("\(number) x \(number) is \(number * number)")
/// } else {
/// print(
/// """
/// Error: Please provide a number to square.
/// Usage: command <number>
/// """
/// )
/// }
///
/// Running the program results in the following output:
///
/// $ command 5
/// 5 x 5 is 25
/// $ command ZZZ
/// Error: Please provide a number to square.
/// Usage: command <number>
public static var arguments: [String] {
get {
_arguments
}
@available(*, deprecated, message: "Do not modify CommandLine.arguments. It will become read-only in a future version of Swift.")
@available(swift, obsoleted: 6.0)
set {
_arguments = newValue
}
}
}
#endif // SWIFT_STDLIB_HAS_COMMANDLINE