File: rcfile.c

package info (click to toggle)
tweak 3.02-6
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 516 kB
  • sloc: ansic: 5,852; makefile: 245; perl: 12; sh: 1
file content (333 lines) | stat: -rw-r--r-- 7,878 bytes parent folder | download | duplicates (4)
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#include "tweak.h"

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

#if defined(unix) && !defined(GO32)
#define RCNAME ".tweakrc"
#elif defined(MSDOS)
#define RCNAME "tweak.rc"
#endif

static char *default_rc[] = {
    "# Default "RCNAME" generated by `tweak -D'.",
    "#",
    "# Key bindings: movement keys",
    "bind top-of-file ^[<",
#if defined(unix) && !defined(GO32)
    "bind page-up ^[[5~",
#elif defined(MSDOS)
    "bind page-up ^@I",
    "bind page-up ^@/",
#endif
    "bind page-up ^[V",
    "bind page-up ^[v",
    "bind move-up ^P",
#if defined(unix) && !defined(GO32)
    "bind move-up ^[[A",
#elif defined(MSDOS)
    "bind move-up ^@H",
#endif
    "bind begin-line ^A",
#if defined(unix) && !defined(GO32)
    "bind begin-line ^[[H",
    "bind begin-line ^[[1~",
#elif defined(MSDOS)
    "bind begin-line ^@G",
#endif
    "bind move-left ^B",
#if defined(unix) && !defined(GO32)
    "bind move-left ^[[D",
#elif defined(MSDOS)
    "bind move-left ^@K",
#endif
    "bind move-right ^F",
#if defined(unix) && !defined(GO32)
    "bind move-right ^[[C",
#elif defined(MSDOS)
    "bind move-right ^@M",
#endif
    "bind end-line ^E",
#if defined(unix) && !defined(GO32)
    "bind end-line ^[Ow",
    "bind end-line ^[[4~",
#elif defined(MSDOS)
    "bind end-line ^@O",
#endif
    "bind move-down ^N",
#if defined(unix) && !defined(GO32)
    "bind move-down ^[[B",
#elif defined(MSDOS)
    "bind move-down ^@P",
#endif
    "bind page-down ^V",
#if defined(unix) && !defined(GO32)
    "bind page-down ^[[6~",
#elif defined(MSDOS)
    "bind page-down ^@Q",
#endif
    "bind bottom-of-file ^[>",
    "",
    "# Key bindings: miscellaneous editing keys",
    "bind toggle-insert ^X^I",
#if defined(unix) && !defined(GO32)
    "bind toggle-insert ^[[2~",
#elif defined(MSDOS)
    "bind toggle-insert ^@R",
#endif
    "bind change-mode ^M",
    "bind change-mode ^J",
    "bind quote-next ^Q",
    "bind toggle-status ^XH",
    "bind toggle-status ^Xh",
    "bind toggle-status ^XX",
    "bind toggle-status ^Xx",
    "",
    "# Key bindings: deletion keys",
    "bind delete-left ^?",
    "bind delete-left ^H",
    "bind delete-right ^D",
#if defined(unix) && !defined(GO32)
    "bind delete-right ^[[3~",
#elif defined(MSDOS)
    "bind delete-right ^@S",
#endif
    "",
    "# Key bindings: cut and paste keys",
#if defined(unix) && !defined(GO32)
    "bind mark-place ^@",
#elif defined(MSDOS)
    "bind mark-place ^@^C",
#endif
    "bind cut ^W",
    "bind copy ^[W",
    "bind copy ^[w",
#ifdef MSDOS
    "bind copy ^@^Q",
#endif
    "bind paste ^Y",
    "",
    "# Key bindings: additional movement keys",
    "bind search ^S",
    "bind search-back ^R",
    "bind goto-position ^XG",
    "bind goto-position ^Xg",
    "bind screen-recentre ^L",
    "",
    "# Standard screen size parameters, plus keybindings to alter them",
    "width 16",
    "offset 0",
    "bind new-width ^XW",
    "bind new-width ^Xw",
    "bind new-offset ^XO",
    "bind new-offset ^Xo",
    "",
    "# Key bindings: overall program/file control",
    "bind suspend ^Z",
    "bind exit ^X^C",
    "bind save-file ^X^S",
    "# unbound by default: exit-and-save",
    "",
#ifdef TEST_BUFFER
    "bind diagnostics ^X^D",
    "",
#endif
    "# End of default "RCNAME,
    NULL
};

extern char *pname;

void read_rc (void) {
    FILE *fp;
    char **p, *q, *r, *s, *keyseq;
    char rcbuffer[256];
    char rcname[FILENAME_MAX];
    int lineno = 0;
    int errors = FALSE, errors_here;

    rcname[sizeof(rcname) - 1] = '\0'; /* ensure null termination */
#if defined(unix) && !defined(GO32)
    rcname[0] = '\0';
    if (getenv("HOME"))
	strncpy (rcname, getenv("HOME"), sizeof(rcname) - 1);
    strncat (rcname, "/.tweakrc", sizeof(rcname) - (1 + strlen(rcname)));
#elif defined(MSDOS)
    /*
     * Use environment variable TWEAKRC if set. Otherwise, look for
     * TWEAK.RC in the same directory as TWEAK.EXE, if _that_ exists,
     * and failing everything else, try C:\TWEAK\TWEAK.RC.
     */
    if (getenv("TWEAKRC"))
	strncpy (rcname, getenv("TWEAKRC"), sizeof(rcname) - 1);
    else {
	if ( (q = strrchr(pname, '\\')) != NULL) {
	    FILE *tempfp;

	    strncpy (rcname, pname, q+1-pname);
	    strncpy (rcname+(q+1-pname), "TWEAK.RC", sizeof(rcname) - (2+q-pname));
	    if ( (tempfp = fopen(rcname, "r")) != NULL)
		fclose (tempfp);
	    else
		strncpy (rcname, "C:\\TWEAK\\TWEAK.RC", sizeof(rcname-1));
	} else
	    strncpy (rcname, "C:\\TWEAK\\TWEAK.RC", sizeof(rcname-1));
    }
#endif

    {				       /* easy keybindings: self inserts */
	int i;
	char c;
	for (i=32; i<127; i++) {
	    c = i;
	    bind_key (&c, 1, act_self_ins);
	}
    }

    fp = fopen(rcname, "r");
    p = default_rc;
    for (EVER) {
	if (fp) {
	    if (!fgets(rcbuffer, sizeof(rcbuffer), fp)) {
		fclose (fp);
		break;
	    }
	    rcbuffer[strcspn(rcbuffer, "\r\n")] = '\0';
	} else {
	    if (!*p)
		break;
	    strncpy (rcbuffer, *p++, sizeof(rcbuffer));
	}
	lineno++;
	errors_here = FALSE;

	/*
	 * Now we have a line from the .rc file, wherever it's
	 * really come from. Process it.
	 */
	q = rcbuffer;
	while (*q && isspace((unsigned char)*q))
	    q++;

	if (!*q || *q == '#')
	    continue;		       /* comment or blank line */

	r = q;
	while (*r && !isspace((unsigned char)*r))
	    r++;
	if (*r)
	    *r++ = '\0';

	/*
	 * Now "q" points to the command word, "r" to the rest of
	 * the line.
	 */
	if (!strcmp(q, "bind")) {
	    /*
	     * It's a "bind" directive. The rest of the line should
	     * consist of an action name, then a single whitespace
	     * character, then a key sequence.
	     */
	    keyact action;

	    while (*r && isspace((unsigned char)*r))
		r++;

	    q = r;
	    while (*q && !isspace((unsigned char)*q))
		q++;
	    if (*q)
		*q++ = '\0';
	    else {
		fprintf(stderr, "%s: no key sequence after \"bind\" command"
			" on line %d of "RCNAME, pname, lineno);
		errors = TRUE;
		continue;
	    }

	    /*
	     * "r" points to the action name; "q" to the key sequence.
	     */
	    keyseq = s = q;
	    while (*q) {
		if (*q == '^') {
		    if (!*++q) {
			fprintf(stderr, "%s: nothing follows `^' on line %d"
				" of "RCNAME, pname, lineno);
			errors = TRUE;
			errors_here = TRUE;
		    } else {
			*s++ = *q++ ^ 0x40;
		    }
		} else if (*q == '\\') {
		    if (!*++q) {
			fprintf(stderr, "%s: nothing follows `\\' on line %d"
				" of "RCNAME, pname, lineno);
			errors = TRUE;
			errors_here = TRUE;
		    } else if (*q == '\\' || *q == '^') {
			*s++ = *q++;
		    } else if (isxdigit((unsigned char)*q) &&
			       q[1] && isxdigit((unsigned char)q[1])) {
			char buf[3];
			buf[0] = *q++;
			buf[1] = *q++;
			buf[2] = '\0';
			*s++ = strtol (buf, NULL, 16);
		    } else {
			fprintf(stderr, "%s: badly formed `\\' sequence on"
				" line %d of "RCNAME, pname, lineno);
			errors = TRUE;
			errors_here = TRUE;
		    }
		} else
		    *s++ = *q++;
	    }
	    if (errors_here)
		continue;

	    if (!strcmp(r, "quote-next")) {
		/*
		 * The "quote next" sequence requires special
		 * treatment.
		 */
		int i;

		for (i=0; i<256; i++) {
		    *s = i;
		    bind_key (keyseq, s-keyseq+1, act_self_ins);
		}
	    } else if ( (action = parse_action (r)) ) {
		/*
		 * An ordinary action, requiring ordinary treatment.
		 */
		bind_key (keyseq, s-keyseq, action);
	    } else {
		fprintf(stderr, "%s: unrecognised key action \"%s\""
			" at line %d of "RCNAME"\n",
			pname, r, lineno);
		errors = TRUE;
	    }
	} else if (!strcmp(q, "width")) {
	    width = atoi(r);
	} else if (!strcmp(q, "offset")) {
	    realoffset = atoi(r);
	} else {
	    fprintf(stderr, "%s: unrecognised "RCNAME" directive \"%s\""
		    " at line %d of "RCNAME"\n",
		    pname, q, lineno);
	    errors = TRUE;
	}
    }
    if (errors)
	exit(1);
}

void write_default_rc (void) {
    char **p;

    for (p = default_rc; *p; p++)
	puts (*p);
}