usr.sbin/makefs/hammer2: Remove redundant hammer2_inode_modify()
[dragonfly.git] / contrib / less / lesskey.c
blob39ebe8b980a9551ed904abe11b571a820fcb7875
1 /*
2 * Copyright (C) 1984-2022 Mark Nudelman
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Less License, as specified in the README file.
7 * For more information, see the README file.
8 */
12 * lesskey [-o output] [input]
14 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
16 * Make a .less file.
17 * If no input file is specified, standard input is used.
18 * If no output file is specified, $HOME/.less is used.
20 * The .less file is used to specify (to "less") user-defined
21 * key bindings. Basically any sequence of 1 to MAX_CMDLEN
22 * keystrokes may be bound to an existing less function.
24 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
26 * The input file is an ascii file consisting of a
27 * sequence of lines of the form:
28 * string <whitespace> action [chars] <newline>
30 * "string" is a sequence of command characters which form
31 * the new user-defined command. The command
32 * characters may be:
33 * 1. The actual character itself.
34 * 2. A character preceded by ^ to specify a
35 * control character (e.g. ^X means control-X).
36 * 3. A backslash followed by one to three octal digits
37 * to specify a character by its octal value.
38 * 4. A backslash followed by b, e, n, r or t
39 * to specify \b, ESC, \n, \r or \t, respectively.
40 * 5. Any character (other than those mentioned above) preceded
41 * by a \ to specify the character itself (characters which
42 * must be preceded by \ include ^, \, and whitespace.
43 * "action" is the name of a "less" action, from the table below.
44 * "chars" is an optional sequence of characters which is treated
45 * as keyboard input after the command is executed.
47 * Blank lines and lines which start with # are ignored,
48 * except for the special control lines:
49 * #command Signals the beginning of the command
50 * keys section.
51 * #line-edit Signals the beginning of the line-editing
52 * keys section.
53 * #env Signals the beginning of the environment
54 * variable section.
55 * #stop Stops command parsing in less;
56 * causes all default keys to be disabled.
58 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
60 * The output file is a non-ascii file, consisting of a header,
61 * one or more sections, and a trailer.
62 * Each section begins with a section header, a section length word
63 * and the section data. Normally there are three sections:
64 * CMD_SECTION Definition of command keys.
65 * EDIT_SECTION Definition of editing keys.
66 * END_SECTION A special section header, with no
67 * length word or section data.
69 * Section data consists of zero or more byte sequences of the form:
70 * string <0> <action>
71 * or
72 * string <0> <action|A_EXTRA> chars <0>
74 * "string" is the command string.
75 * "<0>" is one null byte.
76 * "<action>" is one byte containing the action code (the A_xxx value).
77 * If action is ORed with A_EXTRA, the action byte is followed
78 * by the null-terminated "chars" string.
80 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
83 #include <stdio.h>
84 #include <string.h>
85 #include <stdlib.h>
86 #include "lesskey.h"
87 #include "cmd.h"
88 #include "defines.h"
90 char fileheader[] = {
91 C0_LESSKEY_MAGIC,
92 C1_LESSKEY_MAGIC,
93 C2_LESSKEY_MAGIC,
94 C3_LESSKEY_MAGIC
96 char filetrailer[] = {
97 C0_END_LESSKEY_MAGIC,
98 C1_END_LESSKEY_MAGIC,
99 C2_END_LESSKEY_MAGIC
101 char cmdsection[1] = { CMD_SECTION };
102 char editsection[1] = { EDIT_SECTION };
103 char varsection[1] = { VAR_SECTION };
104 char endsection[1] = { END_SECTION };
106 char *infile = NULL;
107 char *outfile = NULL ;
109 extern char version[];
111 static void
112 usage(void)
114 fprintf(stderr, "usage: lesskey [-o output] [input]\n");
115 exit(1);
118 void
119 lesskey_parse_error(s)
120 char *s;
122 fprintf(stderr, "%s\n", s);
126 lstrtoi(buf, ebuf)
127 char *buf;
128 char **ebuf;
130 return (int) strtol(buf, ebuf, 10);
133 void *
134 ecalloc(count, size)
135 int count;
136 unsigned int size;
138 void *p;
140 p = calloc(count, size);
141 if (p != NULL)
142 return (p);
143 fprintf(stderr, "lesskey: cannot allocate %d bytes of memory\n", count*size);
144 exit(1);
147 static char *
148 mkpathname(dirname, filename)
149 char *dirname;
150 char *filename;
152 char *pathname;
154 pathname = ecalloc(strlen(dirname) + strlen(filename) + 2, sizeof(char));
155 strcpy(pathname, dirname);
156 strcat(pathname, PATHNAME_SEP);
157 strcat(pathname, filename);
158 return (pathname);
162 * Figure out the name of a default file (in the user's HOME directory).
164 char *
165 homefile(filename)
166 char *filename;
168 char *p;
169 char *pathname;
171 if ((p = getenv("HOME")) != NULL && *p != '\0')
172 pathname = mkpathname(p, filename);
173 #if OS2
174 else if ((p = getenv("INIT")) != NULL && *p != '\0')
175 pathname = mkpathname(p, filename);
176 #endif
177 else
179 fprintf(stderr, "cannot find $HOME - using current directory\n");
180 pathname = mkpathname(".", filename);
182 return (pathname);
186 * Parse command line arguments.
188 static void
189 parse_args(argc, argv)
190 int argc;
191 char **argv;
193 char *arg;
195 outfile = NULL;
196 while (--argc > 0)
198 arg = *++argv;
199 if (arg[0] != '-')
200 /* Arg does not start with "-"; it's not an option. */
201 break;
202 if (arg[1] == '\0')
203 /* "-" means standard input. */
204 break;
205 if (arg[1] == '-' && arg[2] == '\0')
207 /* "--" means end of options. */
208 argc--;
209 argv++;
210 break;
212 switch (arg[1])
214 case '-':
215 if (strncmp(arg, "--output", 8) == 0)
217 if (arg[8] == '\0')
218 outfile = &arg[8];
219 else if (arg[8] == '=')
220 outfile = &arg[9];
221 else
222 usage();
223 goto opt_o;
225 if (strcmp(arg, "--version") == 0)
227 goto opt_V;
229 usage();
230 break;
231 case 'o':
232 outfile = &argv[0][2];
233 opt_o:
234 if (*outfile == '\0')
236 if (--argc <= 0)
237 usage();
238 outfile = *(++argv);
240 break;
241 case 'V':
242 opt_V:
243 printf("lesskey version %s\n", version);
244 exit(0);
245 default:
246 usage();
249 if (argc > 1)
250 usage();
252 * Open the input file, or use DEF_LESSKEYINFILE if none specified.
254 if (argc > 0)
255 infile = *argv;
259 * Output some bytes.
261 static void
262 fputbytes(fd, buf, len)
263 FILE *fd;
264 char *buf;
265 int len;
267 while (len-- > 0)
269 fwrite(buf, sizeof(char), 1, fd);
270 buf++;
275 * Output an integer, in special KRADIX form.
277 static void
278 fputint(fd, val)
279 FILE *fd;
280 unsigned int val;
282 char c;
284 if (val >= KRADIX*KRADIX)
286 fprintf(stderr, "error: cannot write %d, max %d\n",
287 val, KRADIX*KRADIX);
288 exit(1);
290 c = val % KRADIX;
291 fwrite(&c, sizeof(char), 1, fd);
292 c = val / KRADIX;
293 fwrite(&c, sizeof(char), 1, fd);
297 main(argc, argv)
298 int argc;
299 char *argv[];
301 struct lesskey_tables tables;
302 FILE *out;
303 int errors;
305 #ifdef WIN32
306 if (getenv("HOME") == NULL)
309 * If there is no HOME environment variable,
310 * try the concatenation of HOMEDRIVE + HOMEPATH.
312 char *drive = getenv("HOMEDRIVE");
313 char *path = getenv("HOMEPATH");
314 if (drive != NULL && path != NULL)
316 char *env = (char *) ecalloc(strlen(drive) +
317 strlen(path) + 6, sizeof(char));
318 strcpy(env, "HOME=");
319 strcat(env, drive);
320 strcat(env, path);
321 putenv(env);
324 #endif /* WIN32 */
327 * Process command line arguments.
329 parse_args(argc, argv);
330 errors = parse_lesskey(infile, &tables);
331 if (errors)
333 fprintf(stderr, "%d errors; no output produced\n", errors);
334 return (1);
337 fprintf(stderr, "NOTE: lesskey is deprecated.\n It is no longer necessary to run lesskey,\n when using less version 582 and later.\n");
340 * Write the output file.
341 * If no output file was specified, use "$HOME/.less"
343 if (outfile == NULL)
344 outfile = getenv("LESSKEY");
345 if (outfile == NULL)
346 outfile = homefile(LESSKEYFILE);
347 if ((out = fopen(outfile, "wb")) == NULL)
349 #if HAVE_PERROR
350 perror(outfile);
351 #else
352 fprintf(stderr, "Cannot open %s\n", outfile);
353 #endif
354 return (1);
357 /* File header */
358 fputbytes(out, fileheader, sizeof(fileheader));
360 /* Command key section */
361 fputbytes(out, cmdsection, sizeof(cmdsection));
362 fputint(out, tables.cmdtable.buf.end);
363 fputbytes(out, (char *)tables.cmdtable.buf.data, tables.cmdtable.buf.end);
364 /* Edit key section */
365 fputbytes(out, editsection, sizeof(editsection));
366 fputint(out, tables.edittable.buf.end);
367 fputbytes(out, (char *)tables.edittable.buf.data, tables.edittable.buf.end);
369 /* Environment variable section */
370 fputbytes(out, varsection, sizeof(varsection));
371 fputint(out, tables.vartable.buf.end);
372 fputbytes(out, (char *)tables.vartable.buf.data, tables.vartable.buf.end);
374 /* File trailer */
375 fputbytes(out, endsection, sizeof(endsection));
376 fputbytes(out, filetrailer, sizeof(filetrailer));
377 fclose(out);
378 return (0);