summaryrefslogtreecommitdiffabout
path: root/shared.c
Unidiff
Diffstat (limited to 'shared.c') (more/less context) (show whitespace changes)
-rw-r--r--shared.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/shared.c b/shared.c
index 5f46793..76d26dd 100644
--- a/shared.c
+++ b/shared.c
@@ -423,3 +423,74 @@ int readfile(const char *path, char **buf, size_t *size)
423 close(fd); 423 close(fd);
424 return (*size == st.st_size ? 0 : e); 424 return (*size == st.st_size ? 0 : e);
425} 425}
426
427int is_token_char(char c)
428{
429 return isalnum(c) || c == '_';
430}
431
432/* Replace name with getenv(name), return pointer to zero-terminating char
433 */
434char *expand_macro(char *name, int maxlength)
435{
436 char *value;
437 int len;
438
439 len = 0;
440 value = getenv(name);
441 if (value) {
442 len = strlen(value);
443 if (len > maxlength)
444 len = maxlength;
445 strncpy(name, value, len);
446 }
447 return name + len;
448}
449
450#define EXPBUFSIZE (1024 * 8)
451
452/* Replace all tokens prefixed by '$' in the specified text with the
453 * value of the named environment variable.
454 * NB: the return value is a static buffer, i.e. it must be strdup'd
455 * by the caller.
456 */
457char *expand_macros(const char *txt)
458{
459 static char result[EXPBUFSIZE];
460 char *p, *start;
461 int len;
462
463 p = result;
464 start = NULL;
465 while (p < result + EXPBUFSIZE - 1 && txt && *txt) {
466 *p = *txt;
467 if (start) {
468 if (!is_token_char(*txt)) {
469 if (p - start > 0) {
470 *p = '\0';
471 len = result + EXPBUFSIZE - start - 1;
472 p = expand_macro(start, len) - 1;
473 }
474 start = NULL;
475 txt--;
476 }
477 p++;
478 txt++;
479 continue;
480 }
481 if (*txt == '$') {
482 start = p;
483 txt++;
484 continue;
485 }
486 p++;
487 txt++;
488 }
489 *p = '\0';
490 if (start && p - start > 0) {
491 len = result + EXPBUFSIZE - start - 1;
492 p = expand_macro(start, len);
493 *p = '\0';
494 }
495 return result;
496}