2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
12 #include <Architecture.h>
14 #include <PathFinder.h>
15 #include <StringList.h>
18 extern const char* __progname
;
19 const char* kCommandName
= __progname
;
22 static const char* kUsage
=
23 "Usage: %s [ <options> ] [ <path> ]\n"
24 "Prints the architecture currently set via the PATH environment variable,\n"
25 "when no arguments are given. When <path> is specified, the architecture\n"
26 "associated with that path is printed. The options allow to print the\n"
27 "primary architecture or the secondary architectures.\n"
31 " Print this usage info.\n"
33 " Print the primary architecture.\n"
35 " Print all secondary architectures for which support is installed.\n"
40 print_usage_and_exit(bool error
)
42 fprintf(error
? stderr
: stdout
, kUsage
, kCommandName
);
48 get_current_architecture()
50 // get the system installation location path
52 if (find_directory(B_SYSTEM_DIRECTORY
, &systemPath
) != B_OK
)
55 // get all architectures
56 BStringList architectures
;
57 get_architectures(architectures
);
58 if (architectures
.CountStrings() < 2)
61 // get the system bin directory for each architecture
62 BStringList binDirectories
;
63 BPathFinder
pathFinder(systemPath
.Path());
64 int32 architectureCount
= architectures
.CountStrings();
65 for (int32 i
= 0; i
< architectureCount
; i
++) {
67 if (pathFinder
.FindPath(architectures
.StringAt(i
),
68 B_FIND_PATH_BIN_DIRECTORY
, NULL
, 0, path
) != B_OK
69 || !binDirectories
.Add(path
.Path())) {
74 // Get and split the PATH environmental variable value. The first system
75 // bin path we encounter implies the architecture.
76 char* pathVariableValue
= getenv("PATH");
78 if (pathVariableValue
!= NULL
79 && BString(pathVariableValue
).Split(":", true, paths
)) {
80 int32 count
= paths
.CountStrings();
81 for (int32 i
= 0; i
< count
; i
++) {
82 // normalize the path, but skip a relative one
84 if (paths
.StringAt(i
)[0] != '/'
85 || path
.SetTo(paths
.StringAt(i
), NULL
, true) != B_OK
) {
89 int32 index
= binDirectories
.IndexOf(path
.Path());
91 return architectures
.StringAt(index
);
100 main(int argc
, const char* const* argv
)
102 bool printPrimary
= false;
103 bool printSecondary
= false;
106 static struct option sLongOptions
[] = {
107 { "help", no_argument
, 0, 'h' },
108 { "primary", no_argument
, 0, 'p' },
109 { "secondary", no_argument
, 0, 's' },
113 opterr
= 0; // don't print errors
114 int c
= getopt_long(argc
, (char**)argv
, "+hps",
121 print_usage_and_exit(false);
129 printSecondary
= true;
133 print_usage_and_exit(true);
138 // The remaining argument is the optional path.
139 const char* path
= optind
< argc
? argv
[optind
++] : NULL
;
141 print_usage_and_exit(true);
143 // only one of path, printPrimary, printSecondary may be specified
144 if (int(path
!= NULL
) + int(printPrimary
) + int(printSecondary
) > 1)
145 print_usage_and_exit(true);
148 // architecture for given path
149 printf("%s\n", guess_architecture_for_path(path
));
150 } else if (printPrimary
) {
151 // primary architecture
152 printf("%s\n", get_primary_architecture());
153 } else if (printSecondary
) {
154 // secondary architectures
155 BStringList architectures
;
156 get_secondary_architectures(architectures
);
157 int32 count
= architectures
.CountStrings();
158 for (int32 i
= 0; i
< count
; i
++)
159 printf("%s\n", architectures
.StringAt(i
).String());
161 // current architecture as implied by PATH
162 BString architecture
= get_current_architecture();
164 architecture
.IsEmpty()
165 ? get_primary_architecture() : architecture
.String());