Add findpaths command line tool

It provides the new find_path*() functionality to the shell.
This commit is contained in:
Ingo Weinhold
2013-11-05 21:42:24 +01:00
parent 8afbcbeb6f
commit 24394a9d11
4 changed files with 249 additions and 3 deletions
+2 -2
View File
@@ -12,8 +12,8 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
csplit cut date dc dd desklink df diff diff3 dircolors dirname
diskimage draggers driveinfo dstcheck du dumpcatalog
echo eject env error expand expr
factor false fdinfo ffm filepanel find finddir FirstBootPrompt fmt fold
fortune frcode ftp ftpd funzip fwcontrol@x86
factor false fdinfo ffm filepanel find finddir findpaths FirstBootPrompt fmt
fold fortune frcode ftp ftpd funzip fwcontrol@x86
gawk gdb@x86 getlimits groupadd groupdel groupmod groups gzip gzexe
hd head hey hostname
id ident ifconfig <bin>install installsound iroster isvolume
+1 -1
View File
@@ -12,7 +12,7 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
csplit cut date dc dd desklink df diff diff3 dircolors dirname
diskimage draggers driveinfo dstcheck du dumpcatalog
echo eject env error expand expr
factor false fdinfo ffm filepanel find finddir fmt fold
factor false fdinfo ffm filepanel find finddir findpaths fmt fold
fortune frcode ftp ftpd funzip
gawk gdb@x86 getlimits groupadd groupdel groupmod groups gzip gzexe
hd head hey hostname
+1
View File
@@ -114,6 +114,7 @@ if $(TARGET_PLATFORM) = libbe_test {
StdBinCommands
alert.cpp
eject.cpp
findpaths.cpp
hey.cpp
reindex.cpp
resattr.cpp
+245
View File
@@ -0,0 +1,245 @@
/*
* Copyright 2013, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Path.h>
#include <PathFinder.h>
#include <StringList.h>
extern const char* __progname;
const char* kCommandName = __progname;
struct DirectoryConstantEntry {
const char* string;
path_base_directory constant;
const char* description;
};
#define DEFINE_CONSTANT(constant, description) \
{ #constant, constant, description }
static const DirectoryConstantEntry kDirectoryConstants[] = {
DEFINE_CONSTANT(B_FIND_PATH_INSTALLATION_LOCATION_DIRECTORY,
"the installation location"),
DEFINE_CONSTANT(B_FIND_PATH_ADD_ONS_DIRECTORY,
"the add-ons directory"),
DEFINE_CONSTANT(B_FIND_PATH_APPS_DIRECTORY,
"the applications directory"),
DEFINE_CONSTANT(B_FIND_PATH_BIN_DIRECTORY,
"the command line programs directory"),
DEFINE_CONSTANT(B_FIND_PATH_BOOT_DIRECTORY,
"the boot data directory"),
DEFINE_CONSTANT(B_FIND_PATH_CACHE_DIRECTORY,
"the cache directory"),
DEFINE_CONSTANT(B_FIND_PATH_DATA_DIRECTORY,
"the data directory"),
DEFINE_CONSTANT(B_FIND_PATH_DEVELOP_DIRECTORY,
"the develop directory"),
DEFINE_CONSTANT(B_FIND_PATH_DEVELOP_LIB_DIRECTORY,
"the development libraries directory"),
DEFINE_CONSTANT(B_FIND_PATH_DOCUMENTATION_DIRECTORY,
"the documentation directory"),
DEFINE_CONSTANT(B_FIND_PATH_ETC_DIRECTORY,
"the Unix etc directory (global settings)"),
DEFINE_CONSTANT(B_FIND_PATH_FONTS_DIRECTORY,
"the fonts directory"),
DEFINE_CONSTANT(B_FIND_PATH_HEADERS_DIRECTORY,
"the development headers directory"),
DEFINE_CONSTANT(B_FIND_PATH_LIB_DIRECTORY,
"the libraries directory"),
DEFINE_CONSTANT(B_FIND_PATH_LOG_DIRECTORY,
"the logging directory"),
DEFINE_CONSTANT(B_FIND_PATH_MEDIA_NODES_DIRECTORY,
"the media node add-ons directory"),
DEFINE_CONSTANT(B_FIND_PATH_PACKAGES_DIRECTORY,
"the packages directory"),
DEFINE_CONSTANT(B_FIND_PATH_PREFERENCES_DIRECTORY,
"the preference applications directory"),
DEFINE_CONSTANT(B_FIND_PATH_SERVERS_DIRECTORY,
"the server programs directory"),
DEFINE_CONSTANT(B_FIND_PATH_SETTINGS_DIRECTORY,
"the global settings directory"),
DEFINE_CONSTANT(B_FIND_PATH_SOUNDS_DIRECTORY,
"the sound files directory"),
DEFINE_CONSTANT(B_FIND_PATH_SPOOL_DIRECTORY,
"the (mail) spool directory"),
DEFINE_CONSTANT(B_FIND_PATH_TRANSLATORS_DIRECTORY,
"the translator add-ons directory"),
DEFINE_CONSTANT(B_FIND_PATH_VAR_DIRECTORY,
"the Unix var directory (global writable data)"),
DEFINE_CONSTANT(B_FIND_PATH_IMAGE_PACKAGE_PATH,
"the path of the package the file specified via -p belongs to"),
};
static const size_t kDirectoryConstantCount
= sizeof(kDirectoryConstants) / sizeof(kDirectoryConstants[0]);
static const char* kUsage =
"Usage: %s [ <options> ] [ <kind> [<subpath>] ]\n"
"Prints paths specified by directory constant <kind>. <subpath>, if\n"
"specified, is appended to each path. By default a path is printed for\n"
"each existing installation location (one per line); the options can\n"
"modify this behavior.\n"
"\n"
"Options:\n"
" -c <separator>\n"
" Concatenate the resulting paths, separated only by <separator>,\n"
" instead of printing a path per line.\n"
" -d, --dependency <dependency>\n"
" Modifies the behavior of the -p option. Use the installation "
"location\n"
" where the dependency <dependency> of the package that the entry\n"
" referred to by <path> belongs to is installed.\n"
" -e, --existing\n"
" Print only paths that refer to existing entries.\n"
" -h, --help\n"
" Print this usage info.\n"
" -l, --list\n"
" Print a list of the possible constants for the <kind> parameter.\n"
" -p, --path <path>\n"
" Print only one path, the one for the installation location that\n"
" contains the path <path>.\n"
;
static void
print_usage_and_exit(bool error)
{
fprintf(error ? stderr : stdout, kUsage, kCommandName);
exit(error ? 1 : 0);
}
int
main(int argc, const char* const* argv)
{
const char* dependency = NULL;
const char* referencePath = NULL;
bool existingOnly = false;
const char* separator = NULL;
while (true) {
static struct option sLongOptions[] = {
{ "dependency", required_argument, 0, 'd' },
{ "help", no_argument, 0, 'h' },
{ "path", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
opterr = 0; // don't print errors
int c = getopt_long(argc, (char**)argv, "+c:d:ehlp:",
sLongOptions, NULL);
if (c == -1)
break;
switch (c) {
case 'c':
separator = optarg;
break;
case 'd':
dependency = optarg;
break;
case 'e':
existingOnly = true;
break;
case 'h':
print_usage_and_exit(false);
break;
case 'l':
for (size_t i = 0; i < kDirectoryConstantCount; i++) {
const DirectoryConstantEntry& entry
= kDirectoryConstants[i];
printf("%s\n - %s\n", entry.string, entry.description);
}
exit(0);
case 'p':
referencePath = optarg;
break;
default:
print_usage_and_exit(true);
break;
}
}
// The remaining arguments are the kind constant and optionally the subpath.
if (optind >= argc || optind + 2 < argc)
print_usage_and_exit(true);
const char* kindConstant = argv[optind++];
const char* subPath = NULL;
if (optind >= argc)
subPath = argv[optind++];
// resolve the directory constant
path_base_directory baseDirectory = B_FIND_PATH_IMAGE_PATH;
bool found = false;
for (size_t i = 0; i < kDirectoryConstantCount; i++) {
const DirectoryConstantEntry& entry = kDirectoryConstants[i];
if (strcmp(kindConstant, entry.string) == 0) {
found = true;
baseDirectory = entry.constant;
break;
}
}
if (!found) {
fprintf(stderr, "Error: Unsupported directory constant \"%s\".\n",
kindConstant);
exit(1);
}
if (referencePath != NULL) {
BPath path;
status_t error = BPathFinder(referencePath, dependency).FindPath(
baseDirectory, subPath,
existingOnly ? B_FIND_PATH_EXISTING_ONLY : 0, path);
if (error != B_OK) {
fprintf(stderr, "Error: Failed to find path: %s\n",
strerror(error));
exit(1);
}
printf("%s\n", path.Path());
} else {
BStringList paths;
status_t error = BPathFinder::FindPaths(baseDirectory, subPath,
existingOnly ? B_FIND_PATH_EXISTING_ONLY : 0, paths);
if (error != B_OK) {
fprintf(stderr, "Error: Failed to find paths: %s\n",
strerror(error));
exit(1);
}
if (separator != NULL) {
BString result = paths.Join(separator);
if (result.IsEmpty()) {
fprintf(stderr, "Error: Out of memory!\n");
exit(1);
}
printf("%s\n", result.String());
} else {
int32 count = paths.CountStrings();
for (int32 i = 0; i < count; i++)
printf("%s\n", paths.StringAt(i).String());
}
}
return 0;
}