1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/* var.c
*
* Variable expansion and maintenance.
*
* All variables are stored as enviroment variables.
*/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include "lafe.h"
extern char **environ;
static void printvar() {
int i;
for (i=0;environ[i];i++) {
printf("%s\n",environ[i]);
}
}
char *getvar(char *name) {
char *v;
v = getenv(name);
if (v) return strdup(v);
else return NULL;
}
void putvar(char *name,char *val) {
setenv(name,val,1);
}
void clearvar(char *name) {
unsetenv(name);
}
/* variable expansion, return a malloced line */
char *expand_variables(char *line) {
char *oldline;
int size;
int src,dst,i;
char *var,*val;
/* exit fast if no $ in line */
/* if (!strchr(line,'$')) return line; */
oldline=line;
size=256;
line=malloc(size);
if (!line) {
perror("malloc");
return oldline;
}
for (src=dst=0;oldline[src];) {
/* begining of a variable */
if (oldline[src] == '$') {
/* allocate var to be the variable name */
/* a general {} variable */
if (oldline[++src]=='{') {
for (i=(++src);oldline[i] && oldline[i]!='}';i++) ;
var=malloc(i-src+1);
strncpy(var,oldline+src,i-src);
var[i-src]=0;
src=i+1;
/* a simple alphanumeric variable */
} else if (isalnum(oldline[src])) {
for (i=src;isalnum(oldline[i]);i++) ;
var=malloc(i-src+1);
strncpy(var,oldline+src,i-src);
var[i-src]=0;
src=i;
/* single character variable */
} else {
var=malloc(2);
var[0]=oldline[src];
var[1]=0;
src++;
}
/* get value and copy into line at point dst */
val=getvar(var);
if (!val) {
if (verbose) fprintf(stderr,"%s not defined\n",var);
} else {
for (;*val;val++) {
line[dst++] = *val;
if (dst>=size-1) {
line=realloc(line,size*=2);
}
}
}
free(var);
/* everything between '' is returned verbatim, without the quotes.
* needed to define aliases with runtime variables */
} else if (oldline[src]=='\'') {
for (src++;oldline[src] && oldline[src]!='\'';src++) {
line[dst++]=oldline[src];
if (dst>=size-1) {
line=realloc(line,size*=2);
}
}
if (oldline[src]) src++;
/* copy character from src to dst */
} else {
line[dst++]=oldline[src++];
if (dst>=size-1) {
line=realloc(line,size*=2);
}
}
}
/* terminate string */
line[dst]=0;
free(oldline);
return line;
}
/* local commands to affect variables */
void setvar(char *line) {
int i,j;
for (i=0;line[i] && !isspace(line[i]);i++) ;
if (!line[i]) { printvar(); return; }
for (j=i;line[j] && isspace(line[j]);j++) ;
line[i]=0;
if (line[j]) putvar(line,line+j); else clearvar(line);
}
|