summaryrefslogtreecommitdiff
path: root/usr.bin/more/filename.c
blob: 36a3ab43716329450268842d8024423bbd0bccbf (plain)
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
/*	$NetBSD: filename.c,v 1.2 1994/12/24 17:17:06 cgd Exp $	*/

#include <stdlib.h>
#include <string.h>

/*
 * Expand a string, substituting any "%" with the current filename,
 * and any "#" with the previous filename and an initial "!" with 
 * the second string.
 */
char *
fexpand(s, t)
	char *s;
	char *t;
{
	extern char *current_file, *previous_file;
	register char *fr, *to;
	register int n;
	register char *e;

	if (*s == '\0')
		return ((char *) 0);
	/*
	 * Make one pass to see how big a buffer we 
	 * need to allocate for the expanded string.
	 */
	n = 0;
	for (fr = s;  *fr != '\0';  fr++)
	{
		switch (*fr)
		{
		case '!':
			if (s == fr && t == (char *) 0) {
				error("no previous command");
				return ((char *) 0);
			}
			n += (s == fr) ? strlen(t) : 1;
			break;
		case '%':
			n += (current_file != (char *) 0) ?  
			     strlen(current_file) : 1;
			break;
		case '#':
			n += (previous_file != (char *) 0) ?  
			     strlen(previous_file) : 1;
			break;
		default:
			n++;
			if (*fr == '\\') {
				n++;
				if (*++fr == '\0') {
					error("syntax error");
					return ((char *) 0);
				}
			}
			break;
		}
	}

	if ((e = (char *) calloc(n+1, sizeof(char))) == (char *) 0) {
		error("cannot allocate memory");
		quit();
	}

	/*
	 * Now copy the string, expanding any "%" or "#".
	 */
	to = e;
	for (fr = s;  *fr != '\0';  fr++)
	{
		switch (*fr)
		{
		case '!':
			if (s == fr) {
				strcpy(to, t);
				to += strlen(to);
			} else
				*to++ = *fr;
			break;
		case '%':
			if (current_file == (char *) 0)
				*to++ = *fr;
			else {
				strcpy(to, current_file);
				to += strlen(to);
			}
			break;
		case '#':
			if (previous_file == (char *) 0)
				*to++ = *fr;
			else {
				strcpy(to, previous_file);
				to += strlen(to);
			}
			break;
		default:
			*to++ = *fr;
			if (*fr == '\\')
				*to++ = *++fr;
			break;
		}
	}
	*to = '\0';
	return (e);
}