78ed81a3 |
1 | /* |
2 | * Expand a string, substituting any "%" with the current filename, |
3 | * and any "#" with the previous filename and an initial "!" with |
4 | * the second string. |
5 | */ |
6 | char * |
7 | fexpand(s, t) |
8 | char *s; |
9 | char *t; |
10 | { |
11 | extern char *current_file, *previous_file; |
12 | register char *fr, *to; |
13 | register int n; |
14 | register char *e; |
15 | |
16 | if (*s == '\0') |
17 | return ((char *) 0); |
18 | /* |
19 | * Make one pass to see how big a buffer we |
20 | * need to allocate for the expanded string. |
21 | */ |
22 | n = 0; |
23 | for (fr = s; *fr != '\0'; fr++) |
24 | { |
25 | switch (*fr) |
26 | { |
27 | case '!': |
28 | if (s == fr && t == (char *) 0) { |
29 | error("no previous command"); |
30 | return ((char *) 0); |
31 | } |
32 | n += (s == fr) ? strlen(t) : 1; |
33 | break; |
34 | case '%': |
35 | n += (current_file != (char *) 0) ? |
36 | strlen(current_file) : 1; |
37 | break; |
38 | case '#': |
39 | n += (previous_file != (char *) 0) ? |
40 | strlen(previous_file) : 1; |
41 | break; |
42 | default: |
43 | n++; |
44 | if (*fr == '\\') { |
45 | n++; |
46 | if (*++fr == '\0') { |
47 | error("syntax error"); |
48 | return ((char *) 0); |
49 | } |
50 | } |
51 | break; |
52 | } |
53 | } |
54 | |
55 | if ((e = (char *) calloc(n+1, sizeof(char))) == (char *) 0) { |
56 | error("cannot allocate memory"); |
57 | quit(); |
58 | } |
59 | |
60 | /* |
61 | * Now copy the string, expanding any "%" or "#". |
62 | */ |
63 | to = e; |
64 | for (fr = s; *fr != '\0'; fr++) |
65 | { |
66 | switch (*fr) |
67 | { |
68 | case '!': |
69 | if (s == fr) { |
70 | strcpy(to, t); |
71 | to += strlen(to); |
72 | } else |
73 | *to++ = *fr; |
74 | break; |
75 | case '%': |
76 | if (current_file == (char *) 0) |
77 | *to++ = *fr; |
78 | else { |
79 | strcpy(to, current_file); |
80 | to += strlen(to); |
81 | } |
82 | break; |
83 | case '#': |
84 | if (previous_file == (char *) 0) |
85 | *to++ = *fr; |
86 | else { |
87 | strcpy(to, previous_file); |
88 | to += strlen(to); |
89 | } |
90 | break; |
91 | default: |
92 | *to++ = *fr; |
93 | if (*fr == '\\') |
94 | *to++ = *++fr; |
95 | break; |
96 | } |
97 | } |
98 | *to = '\0'; |
99 | return (e); |
100 | } |