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 /* Check for SDDS tag format "<filename>=<x>+<y>" */
62 if (!strchr(sddsTags + 1, '+'))
63 sddsTags = NULL;
64 else {
65 /* Split the string without modifying the original */
66 *sddsTags = '\0';
67 sddsTags++;
68 }
69 }
70
71 char *result = NULL;
72 if (search_path && strlen(search_path)) {
73 char *pathList;
74 cp_str(&pathList, search_path);
75 char *path;
76 while ((path = get_token(pathList))) {
77 size_t needed = strlen(localFilename) + strlen(path) + 2 +
78 (sddsTags ? strlen(sddsTags) + 2 : 0);
79 char *tmpName = malloc(needed);
80 sprintf(tmpName, "%s/%s", path, localFilename);
81 free(path);
82 if (fexists(tmpName)) {
83 if (sddsTags) {
84 strcat(tmpName, "=");
85 strcat(tmpName, sddsTags);
86 }
87 cp_str(&result, tmpName);
88 free(tmpName);
89 free(pathList);
90 free(localFilename);
91 return result;
92 }
93 free(tmpName);
94 }
95 free(pathList);
96 }
97 if (fexists(localFilename)) {
98 cp_str(&result, localFilename);
99 free(localFilename);
100 return result;
101 }
102 free(localFilename);
103 return NULL;
104}
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