Commit 1900710c6854891ea76e04bcef4625a475d99840

Authored by Perry Werneck
1 parent ee8c50e3

Adding method to build filenames independent of the OS.

src/core/linux/util.c
... ... @@ -36,31 +36,37 @@
36 36 #include <config.h>
37 37 #include <stdarg.h>
38 38 #include <lib3270-internals.h>
  39 +#include <unistd.h>
39 40  
40   -static char * build_filename(const char *root, const char *str, va_list args)
  41 +static char * concat(char *path, const char *name, size_t *length)
41 42 {
42   - size_t szFilename = 1024 + strlen(root);
43   - char * filename = (char *) lib3270_malloc(szFilename);
  43 + size_t szCurrent = strlen(path);
44 44  
45   - strcpy(filename,root);
  45 + if(szCurrent > 1 && path[szCurrent-1] != '/')
  46 + strcat(path,"/");
46 47  
47   - while(str) {
  48 + szCurrent += strlen(name);
48 49  
49   - size_t szCurrent = strlen(filename);
  50 + if(szCurrent >= *length)
  51 + {
  52 + *length += (szCurrent + 1024);
  53 + path = lib3270_realloc(path,*length);
  54 + }
50 55  
51   - if(filename[szCurrent-1] != '/')
52   - strcat(filename,"/");
  56 + strcat(path,name);
53 57  
54   - szCurrent += strlen(str);
  58 + return path;
  59 +}
55 60  
56   - if(szCurrent >= szFilename)
57   - {
58   - szFilename += (szCurrent + 1024);
59   - filename = lib3270_realloc(filename,szFilename);
60   - }
  61 +static char * build_filename(const char *root, const char *str, va_list args)
  62 +{
  63 + size_t szFilename = 1024 + strlen(root);
  64 + char * filename = (char *) lib3270_malloc(szFilename);
61 65  
62   - strcat(filename,str);
  66 + strcpy(filename,root);
63 67  
  68 + while(str) {
  69 + filename = concat(filename,str,&szFilename);
64 70 str = va_arg(args, const char *);
65 71 }
66 72  
... ... @@ -90,3 +96,54 @@ char * lib3270_build_config_filename(const char *str, ...)
90 96  
91 97 return filename;
92 98 }
  99 +
  100 +char * lib3270_build_filename(const char *str, ...)
  101 +{
  102 + size_t szFilename = 1024;
  103 + char * filename = (char *) lib3270_malloc(szFilename);
  104 + char * tempname;
  105 +
  106 + // First build the base filename
  107 + memset(filename,0,szFilename);
  108 +
  109 + va_list args;
  110 + va_start (args, str);
  111 + while(str) {
  112 + filename = concat(filename,str,&szFilename);
  113 + str = va_arg(args, const char *);
  114 + }
  115 + va_end (args);
  116 +
  117 + // Check paths
  118 + size_t ix;
  119 +
  120 + static const char * paths[] =
  121 + {
  122 + LIB3270_STRINGIZE_VALUE_OF(DATADIR),
  123 + LIB3270_STRINGIZE_VALUE_OF(CONFDIR),
  124 + "."
  125 + };
  126 +
  127 + for(ix = 0; ix < (sizeof(paths)/sizeof(paths[0])); ix++)
  128 + {
  129 + tempname = lib3270_strdup_printf("%s/%s",paths[ix],filename);
  130 +
  131 + if(access(tempname, F_OK) == 0)
  132 + {
  133 + lib3270_free(filename);
  134 + return tempname;
  135 + }
  136 +
  137 + lib3270_free(tempname);
  138 +
  139 + }
  140 +
  141 + // Not found! Force the standard data dir
  142 +
  143 + tempname = lib3270_strdup_printf("%s/%s",paths[0],filename);
  144 + lib3270_free(filename);
  145 +
  146 + return tempname;
  147 +
  148 +}
  149 +
... ...
src/core/windows/util.c
... ... @@ -276,33 +276,32 @@ char * lib3270_get_user_name()
276 276  
277 277 }
278 278  
279   -/*
280   -LIB3270_EXPORT char * lib3270_build_data_filename(const char *name)
  279 +static char * concat(char *path, const char *name, size_t *length)
281 280 {
282   - // https://github.com/GNOME/glib/blob/master/glib/gwin32.c
283   -
284   - char *p;
285   - char wc_fn[MAX_PATH];
  281 + char *ptr;
  282 + size_t szCurrent = strlen(path);
286 283  
287   - if (!GetModuleFileName(NULL, wc_fn, MAX_PATH))
288   - return NULL;
  284 + for(ptr=path;*ptr;ptr++)
  285 + {
  286 + if(*ptr == '/')
  287 + *ptr = '\\';
  288 + }
289 289  
290   - if((p = strrchr(wc_fn, '\\')) != NULL)
291   - *p = '\0';
  290 + if(szCurrent > 1 && path[szCurrent-1] != '\\')
  291 + strcat(path,"\\");
292 292  
293   - if((p = strrchr(wc_fn, '/')) != NULL)
294   - *p = '\0';
  293 + szCurrent += strlen(name);
295 294  
296   - return lib3270_strdup_printf("%s\\%s",wc_fn,name);
  295 + if(szCurrent >= *length)
  296 + {
  297 + *length += (szCurrent + 1024);
  298 + path = lib3270_realloc(path,*length);
  299 + }
297 300  
298   -}
  301 + strcat(path,name);
299 302  
300   -char * lib3270_build_config_filename(const char *name)
301   -{
302   - // On windows the data and config path are the same.
303   - return lib3270_build_data_filename(name);
  303 + return path;
304 304 }
305   -*/
306 305  
307 306 static char * build_filename(const char *str, va_list args)
308 307 {
... ... @@ -314,6 +313,7 @@ static char * build_filename(const char *str, va_list args)
314 313  
315 314 #ifdef DEBUG
316 315 filename[0] = '.';
  316 + filename[1] = '\\';
317 317 #else
318 318 DWORD szPath = GetModuleFileName(hModule,filename,szFilename);
319 319 filename[szPath] = 0;
... ... @@ -324,28 +324,7 @@ static char * build_filename(const char *str, va_list args)
324 324 ptr[1] = 0;
325 325  
326 326 while(str) {
327   -
328   - size_t szCurrent = strlen(filename);
329   -
330   - for(ptr=filename;*ptr;ptr++)
331   - {
332   - if(*ptr == '/')
333   - *ptr = '\\';
334   - }
335   -
336   - if(filename[szCurrent-1] != '\\')
337   - strcat(filename,"\\");
338   -
339   - szCurrent += strlen(str);
340   -
341   - if(szCurrent >= szFilename)
342   - {
343   - szFilename += (szCurrent + 1024);
344   - filename = lib3270_realloc(filename,szFilename);
345   - }
346   -
347   - strcat(filename,str);
348   -
  327 + filename = concat(filename,str,&szFilename);
349 328 str = va_arg(args, const char *);
350 329 }
351 330  
... ... @@ -376,3 +355,15 @@ char * lib3270_build_config_filename(const char *str, ...)
376 355 return filename;
377 356 }
378 357  
  358 +char * lib3270_build_filename(const char *str, ...)
  359 +{
  360 + va_list args;
  361 + va_start (args, str);
  362 +
  363 + char *filename = build_filename(str, args);
  364 +
  365 + va_end (args);
  366 +
  367 + return filename;
  368 +}
  369 +
... ...
src/include/lib3270.h
... ... @@ -1483,15 +1483,31 @@
1483 1483 #endif // WIn32
1484 1484  
1485 1485 /**
1486   - * @brief Build filename on "DATADIR".
  1486 + * @brief Build filename on application data dir.
1487 1487 *
1488 1488 * @return Full path for the file (release it with lib3270_free).
1489 1489 *
1490 1490 */
1491 1491 LIB3270_EXPORT char * lib3270_build_data_filename(const char *str, ...) LIB3270_GNUC_NULL_TERMINATED;
1492 1492  
  1493 + /**
  1494 + * @brief Build filename on application configuration dir.
  1495 + *
  1496 + * @return Full path for the file (release it with lib3270_free).
  1497 + *
  1498 + */
1493 1499 LIB3270_EXPORT char * lib3270_build_config_filename(const char *str, ...) LIB3270_GNUC_NULL_TERMINATED;
1494 1500  
  1501 + /**
  1502 + * @brief Build and search for filename.
  1503 + *
  1504 + * Build filename and search for it on current, configuration and data dirs.
  1505 + *
  1506 + * @return Full path for the file (release it with lib3270_free).
  1507 + *
  1508 + */
  1509 + LIB3270_EXPORT char * lib3270_build_filename(const char *str, ...) LIB3270_GNUC_NULL_TERMINATED;
  1510 +
1495 1511 LIB3270_EXPORT void lib3270_set_session_id(H3270 *hSession, char id);
1496 1512 LIB3270_EXPORT char lib3270_get_session_id(H3270 *hSession);
1497 1513  
... ...
src/testprogram/testprogram.c
... ... @@ -84,6 +84,12 @@ int main(int argc, char *argv[])
84 84 printf("Configfile: \"%s\"\n",datafile);
85 85 }
86 86  
  87 + {
  88 + lib3270_autoptr(char) datafile = lib3270_build_filename("Makefile",NULL);
  89 + printf("Custom file: \"%s\"\n",datafile);
  90 + }
  91 +
  92 +
87 93 /*
88 94 if(lib3270_set_url(h,NULL))
89 95 lib3270_set_url(h,"tn3270://fandezhi.efglobe.com");
... ...