Skip to content

Commit

Permalink
Print the prefix if a deep path is given to search
Browse files Browse the repository at this point in the history
When search is given a deep path (for example, /all.g/box.r) it will do
the search using box.r as the starting point.  Previously, this meant
that the results would be printed using box.r as the root:

/box.r
/box.r/box.s

This may be surprising when the full path is supplied, particularly if
the caller wants the results to be relative to the full specified path.
The adjustment here keeps the prefix when reporting the search results:

/all.g/box.r
/all.g/box.r/box.s

Note that under the hood the search is still conducted relative to
box.r.  In particular, a -depth 1 option will start counting from box.r,
not all.g - this is a bit unintuitive, but a fix will require somewhat
deeper changes to the search logic to recognize the initial depth of the
supplied path and process accordingly.
  • Loading branch information
starseeker committed May 7, 2022
1 parent b73ada8 commit 197bf6a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 14 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ changes made. See document footer for additional details.
--- 2021-XX-XX Release 7.34.X ---
----------------------------------------------------------------------

* preserved path prefixes on search cmd results - Cliff Yapp
* new 'material' command and material object infrastructure
- Dinges, Connelly, Olivarez, McGregor, Studwell, Wilson

Expand Down
57 changes: 43 additions & 14 deletions src/libged/search/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ fp_name_compare(const void *d1, const void *d2, void *arg)


struct ged_search {
struct bu_vls *prefix;
struct directory **paths;
size_t path_cnt;
int search_type;
Expand All @@ -106,7 +107,7 @@ ged_get_interp_eval_callback(struct ged *gedp)


HIDDEN int
_path_scrub(struct bu_vls *path)
_path_scrub(struct bu_vls *prefix, struct bu_vls *path)
{
struct bu_vls tmp = BU_VLS_INIT_ZERO;
const char *normalized;
Expand All @@ -121,10 +122,22 @@ _path_scrub(struct bu_vls *path)
normalized = bu_path_normalize(bu_vls_addr(path));

if (normalized && !BU_STR_EQUAL(normalized, "/")) {

// Search will use the basename
char *tbasename = bu_path_basename(normalized, NULL);
bu_vls_sprintf(&tmp, "%s", tbasename);
bu_free(tbasename, "free bu_path_basename string (caller's responsibility per bu/log.h)");
bu_vls_sprintf(path, "%s", bu_vls_addr(&tmp));
bu_free(tbasename, "free bu_path_basename string (caller's responsibility per bu/path.h)");
bu_vls_sprintf(path, "%s", bu_vls_cstr(&tmp));

// Stash the rest of the path, if any, in prefix
char *tdirname = bu_path_dirname(normalized);
bu_vls_sprintf(&tmp, "%s", tdirname);
bu_free(tdirname, "free bu_path_dirname string (caller's responsibility per bu/path.h)");
bu_vls_trunc(prefix, 0);
if (bu_vls_strlen(&tmp) > 1) {
bu_vls_sprintf(prefix, "%s", bu_vls_cstr(&tmp));
}

bu_vls_free(&tmp);
} else {
bu_vls_sprintf(path, "%s", "/");
Expand All @@ -149,6 +162,10 @@ _ged_free_search_set(struct bu_ptbl *search_set)
if (search->paths) {
bu_free(search->paths, "free search paths");
}
if (search->prefix) {
bu_vls_free(search->prefix);
BU_PUT(search->prefix, struct bu_vls);
}
bu_free(search, "free search");
}
}
Expand Down Expand Up @@ -181,7 +198,7 @@ _ged_plan_item(char *arg)
* The variables is_specific, is_local, and is_flat convey specifics about the search.
*/
HIDDEN int
_ged_search_characterize_path(struct ged *gedp, const char *orig, struct bu_vls *normalized, int *is_specific, int *is_local, int *is_flat, int *flat_only)
_ged_search_characterize_path(struct ged *gedp, const char *orig, struct bu_vls *prefix, struct bu_vls *normalized, int *is_specific, int *is_local, int *is_flat, int *flat_only)
{
struct directory *path_dp = NULL;
(*is_flat) = 0;
Expand Down Expand Up @@ -217,7 +234,7 @@ _ged_search_characterize_path(struct ged *gedp, const char *orig, struct bu_vls
return 1;
}

(*is_local) = _path_scrub(normalized);
(*is_local) = _path_scrub(prefix, normalized);
if (!bu_vls_strlen(normalized))
return 0;
if (BU_STR_EQUAL(bu_vls_addr(normalized), "/")) {
Expand Down Expand Up @@ -297,7 +314,8 @@ ged_search_core(struct ged *gedp, int argc, const char *argv_orig[])
int path_found = 0;
int all_local = 1;
int print_verbose_info = 0;
struct bu_vls argvls = BU_VLS_INIT_ZERO;
struct bu_vls prefix = BU_VLS_INIT_ZERO;
struct bu_vls bname = BU_VLS_INIT_ZERO;
struct bu_vls search_string = BU_VLS_INIT_ZERO;
struct bu_ptbl *search_set;
const char *usage = "[-a] [-v] [-Q] [-h] [path] [expressions...]\n";
Expand Down Expand Up @@ -393,21 +411,25 @@ ged_search_core(struct ged *gedp, int argc, const char *argv_orig[])
struct ged_search *new_search;
int search_path_type;

search_path_type = _ged_search_characterize_path(gedp, argv[plan_argv], &argvls, &is_specific, &is_local, &is_flat, &flat_only);
search_path_type = _ged_search_characterize_path(gedp, argv[plan_argv], &prefix, &bname, &is_specific, &is_local, &is_flat, &flat_only);
path_found = 1;

if (search_path_type) {
BU_ALLOC(new_search, struct ged_search);
BU_GET(new_search->prefix, struct bu_vls);
bu_vls_init(new_search->prefix);
bu_vls_sprintf(new_search->prefix, "%s", bu_vls_cstr(&prefix));
} else {
/* FIXME: confirm 'argvls' is the desired string to print */
/* FIXME: confirm 'bname' is the desired string to print */
if (!wflag) {
bu_vls_printf(gedp->ged_result_str, "Search path error:\n input: '%s' normalized: '%s' \n",
argv[plan_argv], bu_vls_addr(&argvls));
argv[plan_argv], bu_vls_addr(&bname));
} else {
bu_vls_trunc(gedp->ged_result_str, 0);
}

bu_vls_free(&argvls);
bu_vls_free(&bname);
bu_vls_free(&prefix);
bu_argv_free(argc, argv);
_ged_free_search_set(search_set);
return (wflag) ? BRLCAD_OK : BRLCAD_ERROR;
Expand All @@ -424,7 +446,7 @@ ged_search_core(struct ged *gedp, int argc, const char *argv_orig[])
new_search->path_cnt = db_ls(gedp->dbip, DB_LS_HIDDEN, NULL, &(new_search->paths));
} else {
/* _ged_search_characterize_path verified that the db_lookup will succeed */
struct directory *local_dp = db_lookup(gedp->dbip, bu_vls_addr(&argvls), LOOKUP_QUIET);
struct directory *local_dp = db_lookup(gedp->dbip, bu_vls_addr(&bname), LOOKUP_QUIET);
if (is_flat) {
new_search->path_cnt = _ged_search_localized_obj_list(gedp, local_dp, &(new_search->paths), ctx);
} else {
Expand All @@ -449,6 +471,7 @@ ged_search_core(struct ged *gedp, int argc, const char *argv_orig[])
struct ged_search *new_search;

BU_ALLOC(new_search, struct ged_search);
new_search->prefix = NULL;

if (!aflag)
new_search->path_cnt = db_ls(gedp->dbip, DB_LS_TOPS, NULL, &(new_search->paths));
Expand All @@ -473,7 +496,8 @@ ged_search_core(struct ged *gedp, int argc, const char *argv_orig[])
* an invalid plan string, but it will report why it is invalid. So in quiet mode,
* we need to identify the bad string and return now. */
if (wflag && db_search(NULL, flags, bu_vls_addr(&search_string), 0, NULL, NULL, ctx) != -1) {
bu_vls_free(&argvls);
bu_vls_free(&bname);
bu_vls_free(&prefix);
bu_vls_free(&search_string);
bu_argv_free(argc, argv);
_ged_free_search_set(search_set);
Expand Down Expand Up @@ -591,7 +615,11 @@ ged_search_core(struct ged *gedp, int argc, const char *argv_orig[])
struct db_full_path *dfptr = (struct db_full_path *)BU_PTBL_GET(search_results, j);
bu_vls_trunc(&fullpath_string, 0);
db_fullpath_to_vls(&fullpath_string, dfptr, gedp->dbip, print_verbose_info);
bu_vls_printf(gedp->ged_result_str, "%s\n", bu_vls_addr(&fullpath_string));
if (search->prefix && bu_vls_strlen(search->prefix)) {
bu_vls_printf(gedp->ged_result_str, "%s%s\n", bu_vls_cstr(search->prefix), bu_vls_cstr(&fullpath_string));
} else {
bu_vls_printf(gedp->ged_result_str, "%s\n", bu_vls_cstr(&fullpath_string));
}
}
}
break;
Expand Down Expand Up @@ -625,7 +653,8 @@ ged_search_core(struct ged *gedp, int argc, const char *argv_orig[])
}

/* Done - free memory */
bu_vls_free(&argvls);
bu_vls_free(&bname);
bu_vls_free(&prefix);
bu_vls_free(&search_string);
bu_argv_free(argc, argv);
db_search_context_destroy(ctx);
Expand Down

0 comments on commit 197bf6a

Please sign in to comment.