"Fossies" - the Fresh Open Source Software archive 
Member "cftp-0.12/mkbind.c" of archive cftp-0.12.tar.gz:
/*
$NiH: mkbind.c,v 1.23 2002/09/17 11:46:23 dillo Exp $
mkbind.c -- make binding table
Copyright (C) 1996-2002 Dieter Baron
This file is part of cftp, a fullscreen ftp client
The author can be contacted at <dillo@giga.or.at>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <sys/types.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "bindings.h"
#include "display.h"
#include "fntable.h"
#include "functions.h"
#include "keys.h"
#include "rc.h"
#define FNAME "bindings"
#define NAME "binding"
#define POOL "pool"
#define ARGS "argpool"
#define TABLE "fntable.c"
#define MAX_FN 8192
#define LINELEN 72
const char header[] = "/*\n\
This file is automatically created from ``bindings.desc'' by mkbind;\n\
don't make changes to this file, change ``bindings.desc'' instead.\n\
*/\n\
\n\
#include <stddef.h>\n\
#include \"bindings.h\"\n\n";
char *states[] = {
"bs_quit", "bs_none", "bs_remote", "bs_local", "bs_tag"
};
int nstates = sizeof(states)/sizeof(states[0]);
function functions[MAX_FN];
int num;
struct binding binding[MAX_FN];
char *binding_argpool[1];
int binding_nargpool = 0;
char *prg, *srcdir;
void print_args(FILE *fout, char **args);
FILE *vpath_open(char *name);
void initnames(void);
int
main(int argc, char **argv)
{
FILE *fin, *fout;
char line[4069], *p, *tok, **args;
char tmp[128];
struct binding *b;
int i, j, off, argoff, len;
int maxkey;
prg = argv[0];
rc_inrc = 1;
maxkey = max_fnkey + 256;
if (argc == 2 && strcmp(argv[1], ".") != 0)
srcdir = argv[1];
else
srcdir = NULL;
initnames();
for (i=0; i<maxkey; i++) {
binding[i].next = NULL;
binding[i].state = bs_none;
binding[i].fn = -1;
binding[i].args = NULL;
}
off = 0;
/* processing ``bindings.desc'' */
if ((fin=vpath_open(FNAME ".desc")) == NULL)
exit(1);
rc_lineno = 0;
while (fgets(line, 4096, fin) != NULL) {
rc_lineno++;
p = line;
if ((tok=rc_token(&p)) == NULL || tok[0] == '#')
continue;
if (strcasecmp(tok, "bind") != 0) {
rc_error("non-bind command ignored: %s", tok);
continue;
}
args = rc_list(p);
fn_bind(args);
}
if (ferror(fin)) {
fprintf(stderr, "%s: read error in `%s': %s.\n",
prg, rc_filename, strerror(errno));
fclose(fin);
exit(1);
}
fclose(fin);
free(rc_filename);
rc_filename = NULL;
/* writing ``bindings.c'' in temp file */
sprintf(tmp, FNAME ".c.%d", getpid());
if ((fout=fopen(tmp, "w")) == NULL) {
fprintf(stderr, "%s: can't open output file `%s': %s.\n",
prg, tmp, strerror(errno));
exit(1);
}
fprintf(fout, "%s", header);
/* output: bindings */
off = argoff = 0;
fprintf(fout, "struct binding " NAME "[] = {\n");
for (i=0; i<maxkey; i++) {
fprintf(fout, " { ");
if (binding[i].next) {
fprintf(fout, "binding_pool+%3d, ", off);
for (b=binding[i].next; b; b=b->next)
off++;
}
else
fprintf(fout, "NULL , ");
if (binding[i].state+1 < nstates)
fprintf(fout, "%s, ", states[binding[i].state+1]);
else
fprintf(fout, "%d, ", binding[i].state);
fprintf(fout, "%3d, ", binding[i].fn);
if (binding[i].args) {
fprintf(fout, "binding_argpool+%d },\n", argoff);
for (j=0; binding[i].args[j]; j++)
;
argoff += j+1;
}
else
fprintf(fout, "NULL },\n");
}
fprintf(fout, "};\n\n");
if (ferror(fout)) {
fprintf(stderr, "%s: write error on `%s': %s.\n",
prg, FNAME ".c", strerror(errno));
exit(1);
fclose(fout);
}
/* output: bindings_pool */
off = 1;
fprintf(fout, "struct binding " NAME "_" POOL "[] = {\n");
for (i=0; i<maxkey; i++)
if (binding[i].next) {
for (b=binding[i].next; b; b=b->next) {
fprintf(fout, " { ");
if (b->next)
fprintf(fout, "binding_pool+%3d, ", off);
else
fprintf(fout, "NULL , ");
if (b->state+1 < nstates)
fprintf(fout, "%s, ", states[b->state+1]);
else
fprintf(fout, "%d, ", b->state);
fprintf(fout, "%3d, ", b->fn);
if (b->args) {
fprintf(fout, "binding_argpool+%d },\n", argoff);
for (j=0; b->args[j]; j++)
;
argoff += j+1;
}
else
fprintf(fout, "NULL },\n");
off++;
}
}
fprintf(fout, "};\n\n");
fprintf(fout, "int " NAME "_n" POOL " = sizeof(" NAME "_" POOL ")"
" / sizeof(" NAME "_" POOL "[0]);\n\n");
if (ferror(fout)) {
fprintf(stderr, "%s: write error on `%s': %s.\n",
prg, FNAME ".c", strerror(errno));
exit(1);
fclose(fout);
}
/* output: binding_argpool */
len = 3;
fprintf(fout, "char *" NAME "_" ARGS "[] = {\n ");
for (i=0; i<maxkey; i++)
if (binding[i].args)
print_args(fout, binding[i].args);
for (i=0; i<maxkey; i++)
if (binding[i].next)
for (b=binding[i].next; b; b=b->next)
if (b->args)
print_args(fout, b->args);
fprintf(fout, "\n};\n\n");
fprintf(fout, "int " NAME "_n" ARGS " = sizeof(" NAME "_" ARGS ")"
" / sizeof(" NAME "_" ARGS "[0]);\n");
if (ferror(fout)) {
fprintf(stderr, "%s: write error on `%s': %s.\n",
prg, FNAME ".c", strerror(errno));
fclose(fout);
exit(1);
}
fclose(fout);
/* rename tmp file to ``bindings.c'' */
if (rename(tmp, FNAME ".c") < 0) {
fprintf(stderr, "%s: cannot rename `%s' to `%s': %s\n",
prg, tmp, FNAME ".c", strerror(errno));
exit(1);
}
exit(0);
}
void
initnames(void)
{
char line[8192], *p, *q;
FILE *f;
num = 0;
if ((f=vpath_open(TABLE)) == NULL) {
exit(1);
}
rc_lineno = 1;
while (fgets(line, 8192, f) && line[strlen(line)-2] != '{')
rc_lineno++;
if (ferror(f)) {
fprintf(stderr, "%s: read error in `%s': %s.\n",
prg, rc_filename, strerror(errno));
exit(1);
}
if (feof(f)) {
rc_error("beggining of functions array not found");
exit(1);
}
while (fgets(line, 8192, f) && line[0] != '}') {
if (strncmp(line, " { 0, 0, ", 10) == 0)
break;
if (strncmp(line, "/*", 2) == 0)
continue;
p = strchr(line, '\"');
if (p == NULL) {
rc_error("function name missing; line skipped");
continue;
}
q = strchr(p+1, '\"');
if (q == NULL)
rc_error("end of function name missing; line skipped");
else {
p++;
*q = '\0';
functions[num].name = strdup(p);
functions[num].fn = NULL;
functions[num].type = 0;
functions[num].help = NULL;
if (++num >= MAX_FN) {
fprintf(stderr, "%s: internal function "
"table too small\n", prg);
exit(1);
}
}
}
if (ferror(f)) {
fprintf(stderr, "%s: read error in `%s': %s.\n",
prg, rc_filename, strerror(errno));
exit(1);
}
fclose(f);
free(rc_filename);
rc_filename = NULL;
}
void
print_args(FILE *fout, char **args)
{
static int len = 0;
int wlen, j;
for (j=0; args[j]; j++) {
wlen = 4+strlen(args[j]);
if (len+wlen > LINELEN) {
fprintf(fout, "\n ");
len = 3;
}
else
len += wlen;
fprintf(fout, " \"%s\",", args[j]);
}
if (len+6 > LINELEN) {
fprintf(fout, "\n ");
len = 3;
}
else
len += 6;
fprintf(fout, " NULL,");
}
FILE *
vpath_open(char *name)
{
FILE *f;
char *vname;
if ((f=fopen(name, "r")) != NULL) {
rc_filename = strdup(name);
return f;
}
if (srcdir == NULL) {
fprintf(stderr, "%s: can't open file `%s': %s\n",
prg, name, strerror(errno));
return NULL;
}
if ((vname=(char *)malloc(strlen(name)+strlen(srcdir)+2)) == NULL) {
fprintf(stderr, "%s: malloc failure\n", prg);
exit(1);
}
sprintf(vname, "%s/%s", srcdir, name);
if ((f=fopen(vname, "r")) != NULL) {
rc_filename = vname;
return f;
}
fprintf(stderr, "%s: can't find file `%s': %s\n",
prg, name, strerror(errno));
free(vname);
return NULL;
}
/* dummy functions needed by fn_bind */
void
disp_status(int flags, char *fmt, ...)
{
va_list argp;
if (flags & DISP_STDERR) {
va_start(argp, fmt);
vfprintf(stderr, fmt, argp);
va_end(argp);
}
return;
}
char *
read_string(char *prompt, int echop)
{
return NULL;
}