3 /* Copyright (C) 2002 Brad Jorsch <anomie@users.sourceforge.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <sys/types.h>
29 #define GROW(var, len){{ \
33 if((var=realloc(c=var, len))==NULL){ \
35 warn("realloc error"); \
41 if(k>=formatlen) GROW(format, formatlen); \
45 char *subst(const char *s
, struct subst_val
*substitutes
){
54 for(i
=j
=0; s
[i
]!='\0'; i
++){
56 if(j
>=outlen
) GROW(out
, outlen
);
61 if(j
>=outlen
) GROW(out
, outlen
);
72 while(strchr("#0- +'!", s
[++n
])){
81 if(isdigit(s
[n
]) && s
[n
]!='0'){
83 while(isdigit(s
[++n
])){ COPY(s
[n
]); }
89 while(isdigit(s
[++n
])){ COPY(s
[n
]); }
98 while(isdigit(s
[++n
])){
99 str_start
=str_start
*10+s
[n
]-'0';
101 if(flags
&2) str_start
=-str_start
;
104 for(m
=0; s
[n
]!=substitutes
[m
].id
&& substitutes
[m
].id
!='\0'; m
++);
105 if(substitutes
[m
].id
=='\0'){
106 warn("Unknown substitition character '%c' (at %d)\n", s
[n
], i
);
110 switch(substitutes
[m
].type
){
117 COPY(toupper(substitutes
[m
].type
));
123 COPY(substitutes
[m
].type
);
128 #define PRINT(var) { while((k=j+snprintf(out+j, outlen-j, format, var))>=outlen) GROW(out, outlen); j=k; }
129 switch(substitutes
[m
].type
){
131 PRINT(*(signed int *)substitutes
[m
].val
);
137 PRINT(*(unsigned int *)substitutes
[m
].val
);
144 PRINT(*(double *)substitutes
[m
].val
);
148 PRINT(*(char *)substitutes
[m
].val
);
149 if(flags
&1) out
[j
-1]=toupper(out
[j
-1]);
154 char *s
=*(char **)substitutes
[m
].val
;
156 str_start
+=strlen(s
);
157 if(str_start
<0) str_start
=0;
158 } else if(str_start
>strlen(s
)){
166 for(; i
<j
; i
++) out
[i
]=toupper(out
[i
]);
172 warn("Unknown substitution type '%c'\n", substitutes
[m
].type
);
180 if(j
>=outlen
) GROW(out
, outlen
);