SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
searchPath.c
Go to the documentation of this file.
1/**
2 * @file searchPath.c
3 * @brief Implementation of search path management and file locating functions.
4 *
5 * @copyright
6 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
7 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
8 *
9 * @license
10 * This file is distributed under the terms of the Software License Agreement
11 * found in the file LICENSE included with this distribution.
12 *
13 * @author H. Shang, M. Borland, R. Soliday
14 */
15
16#include "mdb.h"
17
18static MDB_THREAD_LOCK search_path_lock = MDB_THREAD_LOCK_INITIALIZER;
19static char *search_path = NULL;
20/**
21 * @brief Sets the search path for file lookup.
22 *
23 * This function updates the global `search_path` variable. If a new input path is provided,
24 * it copies the input string to `search_path`, freeing any previously allocated memory.
25 * If the input is `NULL`, `search_path` is set to `NULL`.
26 *
27 * @param input The new search path to set. If `NULL`, the search path is cleared.
28 */
29void setSearchPath(char *input) {
30 char *new_search_path = NULL;
31 char *old_search_path;
32
33 if (input)
34 cp_str(&new_search_path, input);
35
36 mdb_thread_lock(&search_path_lock);
37 old_search_path = search_path;
38 search_path = new_search_path;
39 mdb_thread_unlock(&search_path_lock);
40
41 if (old_search_path)
42 free(old_search_path);
43}
44
45/**
46 * @brief Finds a file within the configured search path.
47 *
48 * This function searches for the specified `filename` in each directory listed in the
49 * `search_path`. If the `filename` includes SDDS tags (indicated by '=' and '+'),
50 * the tags are processed and appended to the found file path.
51 *
52 * @param filename The name of the file to locate. It may include SDDS tags in the format
53 * `<filename>=<x>+<y>`.
54 * @return A dynamically allocated string containing the path to the found file with tags,
55 * or `NULL` if the file is not found.
56 */
57char *findFileInSearchPath(const char *filename) {
58 char *pathList = NULL;
59
60 if (!filename || !strlen(filename))
61 return NULL;
62
63 /* Work on a modifiable copy of filename */
64 char *localFilename = strdup(filename);
65 if (!localFilename)
66 return NULL;
67
68 char *sddsTags = NULL;
69 /* Look for '=' in the copy */
70 if ((sddsTags = strchr(localFilename, '='))) {
71 *sddsTags = '\0';
72 sddsTags++;
73 }
74
75 char *result = NULL;
76 mdb_thread_lock(&search_path_lock);
77 if (search_path && strlen(search_path))
78 cp_str(&pathList, search_path);
79 mdb_thread_unlock(&search_path_lock);
80
81 if (pathList) {
82 char *path;
83 while ((path = get_token(pathList))) {
84 size_t needed = strlen(localFilename) + strlen(path) + 2 +
85 (sddsTags ? strlen(sddsTags) + 2 : 0);
86 char *tmpName = malloc(needed);
87 sprintf(tmpName, "%s/%s", path, localFilename);
88 free(path);
89 if (fexists(tmpName)) {
90 if (sddsTags) {
91 strcat(tmpName, "=");
92 strcat(tmpName, sddsTags);
93 }
94 cp_str(&result, tmpName);
95 free(tmpName);
96 free(pathList);
97 free(localFilename);
98 return result;
99 }
100 free(tmpName);
101 }
102 free(pathList);
103 }
104 if (fexists(localFilename)) {
105 result = strdup(filename);
106 free(localFilename);
107 return result;
108 }
109 free(localFilename);
110 return NULL;
111}
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
char * get_token(char *s)
Extracts the next token from the input string.
Definition data_scan.c:413
long fexists(const char *filename)
Checks if a file exists.
Definition fexists.c:27
void setSearchPath(char *input)
Sets the search path for file lookup.
Definition searchPath.c:29
char * findFileInSearchPath(const char *filename)
Finds a file within the configured search path.
Definition searchPath.c:57