SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
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 char *search_path = NULL;
19/**
20 * @brief Sets the search path for file lookup.
21 *
22 * This function updates the global `search_path` variable. If a new input path is provided,
23 * it copies the input string to `search_path`, freeing any previously allocated memory.
24 * If the input is `NULL`, `search_path` is set to `NULL`.
25 *
26 * @param input The new search path to set. If `NULL`, the search path is cleared.
27 */
28void setSearchPath(char *input) {
29 if (search_path)
30 free(search_path);
31 if (input)
32 cp_str(&search_path, input);
33 else
34 search_path = NULL;
35}
36
37/**
38 * @brief Finds a file within the configured search path.
39 *
40 * This function searches for the specified `filename` in each directory listed in the
41 * `search_path`. If the `filename` includes SDDS tags (indicated by '=' and '+'),
42 * the tags are processed and appended to the found file path.
43 *
44 * @param filename The name of the file to locate. It may include SDDS tags in the format
45 * `<filename>=<x>+<y>`.
46 * @return A dynamically allocated string containing the path to the found file with tags,
47 * or `NULL` if the file is not found.
48 */
49char *findFileInSearchPath(const char *filename) {
50 if (!filename || !strlen(filename))
51 return NULL;
52
53 /* Work on a modifiable copy of filename */
54 char *localFilename = strdup(filename);
55 if (!localFilename)
56 return NULL;
57
58 char *sddsTags = NULL;
59 /* Look for '=' in the copy */
60 if ((sddsTags = strchr(localFilename, '='))) {
61 *sddsTags = '\0';
62 sddsTags++;
63 }
64
65 char *result = NULL;
66 if (search_path && strlen(search_path)) {
67 char *pathList;
68 cp_str(&pathList, search_path);
69 char *path;
70 while ((path = get_token(pathList))) {
71 size_t needed = strlen(localFilename) + strlen(path) + 2 +
72 (sddsTags ? strlen(sddsTags) + 2 : 0);
73 char *tmpName = malloc(needed);
74 sprintf(tmpName, "%s/%s", path, localFilename);
75 free(path);
76 if (fexists(tmpName)) {
77 if (sddsTags) {
78 strcat(tmpName, "=");
79 strcat(tmpName, sddsTags);
80 }
81 cp_str(&result, tmpName);
82 free(tmpName);
83 free(pathList);
84 free(localFilename);
85 return result;
86 }
87 free(tmpName);
88 }
89 free(pathList);
90 }
91 if (fexists(localFilename)) {
92 result = strdup(filename);
93 free(localFilename);
94 return result;
95 }
96 free(localFilename);
97 return NULL;
98}
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:28
char * findFileInSearchPath(const char *filename)
Finds a file within the configured search path.
Definition searchPath.c:49