4
* (c)Copyright 1990 by Tobias Ferber, All Rights Reserved
6
* This file is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published
8
* by the Free Software Foundation; either version 1 of the License,
9
* or (at your option) any later version.
11
* This file is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; see the file COPYING. If not, write to
18
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
29
struct rule *rules[256];
34
* Dieses Array enth"alt an der Position rules[x].rhs den String in den `x'
35
* "ubersetzt werden soll und/oder einen Zeiger rules[x].rules auf die Liste,
36
* die in (rules[x].rules)[y] die "Ubersetzungen f"ur `xy' enthalten...
39
static rule_t *rules[256];
44
static rule_t *rule_new(void)
46
rule_t *r= (rule_t *)malloc( sizeof(rule_t) );
53
(r->rules)[c]= (rule_t *)0;
64
static rule_t *rule_dispose(rule_t *r)
71
(r->rules)[c]= rule_dispose( r->rules[c] );
84
static int rule_add(char *lhs, char *rhs)
93
for(R=&rules[0], c= (int)(unsigned char)*lhs; c && (err==0); c= (int)(unsigned char)*++lhs)
104
R[c]->rhs= (rhs ? rhs : ""); /* Fri Feb 24 18:20:39 1995 */
117
static char *rule_find(char **lhs_)
120
char *rhs= (char *)0;
122
rule_t **R= &rules[0];
126
for(done=0; R[(int)(unsigned char)(*lhs)] && !done; ++lhs)
128
rule_t *r= R[ (int)(unsigned char)(*lhs) ];
130
if( r->rules && (r->rules)[ (int)(unsigned char)(lhs[1]) ] )
149
static int strexpand_init(char **table)
154
/* initialize the rules[] array */
156
rules[c]= (rule_t *)0;
158
/* add the given rules */
162
for(t=0; table[t] && (err==0); t+=2)
163
err= rule_add(table[t], table[t+1]);
172
static void strexpand_exit(void)
179
rules[c]= rule_dispose(rules[c]);
184
/****** strexpand/strexpand **************************************************
187
* strexpand -- Expand macros in a string dynamically
190
* str= strexpand(fmt, tab)
192
* char *strexpand( char *, char ** );
195
* This function expands all occurences of tab[n] (n even) in `fmt' to
196
* tab[n+1] and returns a dynamically allocated string which has to be
197
* disposed via free(str) by the user.
199
* In other words: given translation table `tab' holds substitution-
200
* or translation rules with the source string (or left-hand-side)
201
* on even places and the destination string (or right-hand-side) on
202
* the odd places. The translation is performed on given string `fmt'
203
* in the following way:
207
* tab[4] -> tab[5] ....
209
* I.e.: all occurences of tab[0] in `fmt' will be replaced by tab[1],
215
* fmt - The format string holding 0 or more of the macros
217
* tab - A table of strings with the source string (on even
218
* indices) and the destination string.
219
* This table must end with a (char *)0 as the last
223
* str - A dynamically allocated copy of `fmt' with all
224
* occurences of t[n] (n even) replaced by t[n+1].
228
* char *table[] = { "ab" , "1234",
230
* "ef" , "foobar", 0,0 };
232
* compiling the translation table via strexpand_init(table) yields the
235
* +---+---+---+---+---+---+
236
* rules[] = | a | b | c | d | e | f | ....
237
* +---+---+---+---+---+---+
240
* +---+---+ +---+---+---+---+---+---+
241
* | a | b | .... | a | b | c | d | e | f | ....
242
* +---+---+ +---+---+---+---+---+---+
245
* / +-- "1234" +-- "foobar"
248
* +---+---+---+---+---+---+
249
* | a | b | c | d | e | f | ....
250
* +---+---+---+---+---+---+
255
* strexpand("abcdefgab!",table); returns "xyzdfoobarg1234!".
259
******************************************************************************
264
char *strexpand(char *fmt, char **tab)
266
char *buf= (char *)0;
270
if( strexpand_init(tab) == 0 )
272
size_t len= strlen(fmt) + 1; /* size of output buffer */
274
if( (buf= (char *)malloc(len*sizeof(char))) )
276
unsigned int pos= 0; /* char position in buf */
281
char *rhs= rule_find( &fmt );
294
buf= (char *)realloc(buf,len*sizeof(char));
310
buf= (char *)realloc(buf,len*sizeof(char) );
321
/*printf("strexpand(): pos=%d, len=%d\n",pos,len);*/
336
char *table[] = { "ab" , "1234",
338
"ef" , "foobar", 0,0 };
340
int main(int argc, char **argv)
344
char *s= strexpand(*++argv, table);
351
else printf("strexpand(\"%s\") failed.\n",*argv);