|
|
3.15b
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gen_defs.h"
/****************************************************************************/
/* Converts an ASCII Hex string into an ulong */
/* by Steve Deppe (Ille Homine Albe) */
/****************************************************************************/
/* Copied from str_util.c */
ulong ahtoul(char *str)
{
ulong l,val=0;
while((l=(*str++)|0x20)!=0x20)
val=(l&0xf)+(l>>6&1)*9+val*16;
return(val);
}
/****************************************************************************/
/* Reads special TEXT.DAT printf style text lines, splicing multiple lines, */
/* replacing escaped characters, and allocating the memory */
/****************************************************************************/
/* Copied from load_cfg.c with comment pointer added */
char *readtext(FILE *stream, char **comment_ret)
{
char buf[2048],str[2048],tmp[256],*p,*p2;
char comment[2048], *cp;
int i,j,k;
if(!fgets(buf,256,stream))
return(NULL);
if(buf[0]=='#')
return(NULL);
p=strrchr(buf,'"');
if(!p) {
return(NULL);
}
comment[0]=0;
if(*(p+1)=='\\') { /* merge multiple lines */
for(cp=p+2; *cp && isspace(*cp); cp++);
strcat(comment, cp);
while(strlen(buf)<2000) {
if(!fgets(str,255,stream))
return(NULL);
p2=strchr(str,'"');
if(!p2)
continue;
strcpy(p,p2+1);
p=strrchr(p,'"');
if(p && *(p+1)=='\\') {
for(cp=p+2; *cp && isspace(*cp); cp++);
strcat(comment, cp);
continue;
}
break;
}
}
for(cp=p+2; *cp && isspace(*cp); cp++);
strcat(comment, cp);
cp=strchr(comment, 0);
if(cp && cp > comment) {
cp--;
while(cp > comment && isspace(*cp)) {
*(cp--)=0;
}
}
*(p)=0;
k=strlen(buf);
for(i=1,j=0;i<k;j++) {
if(buf[i]=='\\') { /* escape */
i++;
if(isdigit(buf[i])) {
str[j]=atoi(buf+i); /* decimal, NOT octal */
if(isdigit(buf[++i])) /* skip up to 3 digits */
if(isdigit(buf[++i]))
i++;
continue;
}
switch(buf[i++]) {
case '\\':
str[j]='\\';
break;
case '?':
str[j]='?';
break;
case 'x':
tmp[0]=buf[i++]; /* skip next character */
tmp[1]=0;
if(isxdigit(buf[i])) { /* if another hex digit, skip too */
tmp[1]=buf[i++];
tmp[2]=0;
}
str[j]=(char)ahtoul(tmp);
break;
case '\'':
str[j]='\'';
break;
case '"':
str[j]='"';
break;
case 'r':
str[j]=CR;
break;
case 'n':
str[j]=LF;
break;
case 't':
str[j]=TAB;
break;
case 'b':
str[j]=BS;
break;
case 'a':
str[j]=BEL;
break;
case 'f':
str[j]=FF;
break;
case 'v':
str[j]=11; /* VT */
break;
default:
str[j]=buf[i];
break;
}
continue;
}
str[j]=buf[i++];
}
str[j]=0;
if((p=(char *)calloc(1,j+2))==NULL) { /* +1 for terminator, +1 for YNQX line */
fprintf(stderr,"Error allocating %u bytes of memory from text.dat",j);
return(NULL);
}
strcpy(p,str);
if(comment_ret)
*comment_ret=strdup(comment);
return(p);
}
char *format_as_cstr(char *orig)
{
int len=0;
char *ret=NULL;
char *in;
char hex[32];
int outpos=0;
len=strlen(orig);
len += ((len / 32)*2);
len *= 6;
len += 32; /* Only needs to be three, the extra is for luck ;-) */
ret=(char *)malloc(len);
if(ret==NULL)
return(ret);
strcpy(ret,"\"");
for(in=orig; *in; in++) {
sprintf(hex, "\\x%02x", (unsigned char)*in);
strcat(ret,hex);
if((++outpos)%32==0)
strcat(ret,"\"\n\t\t\"");
}
strcat(ret, "\"");
return(ret);
}
int main(int argc, char **argv)
{
FILE *text_dat;
char path[MAX_PATH+1];
char *p;
char *cstr;
char *comment;
char *macro;
unsigned long lno;
int i=0;
FILE *text_h;
FILE *text_js;
FILE *text_defaults_c;
if((p=getenv("SBBSCTRL"))==NULL)
p="/sbbs/ctrl";
sprintf(path,"%s/text.dat",p);
if((text_dat=fopen(path,"r"))==NULL) {
perror(path);
return(1);
}
if((text_h=fopen("text.h", "w"))==NULL) {
perror("text.h");
return(1);
}
fputs("/* text.h */\n",text_h);
fputs("\n",text_h);
fputs("/* Synchronet static text string constants */\n",text_h);
fputs("\n",text_h);
fputs("/* $Id: textgen.c,v 1.1.1.1 2018/04/24 16:42:38 root Exp $ */\n",text_h);
fputs("\n",text_h);
fputs("/****************************************************************************\n",text_h);
fputs(" * @format.tab-size 4 (Plain Text/Source Code File Header) *\n",text_h);
fputs(" * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *\n",text_h);
fputs(" * *\n",text_h);
fputs(" * Copyright 2009 Rob Swindell - http://www.synchro.net/copyright.html *\n",text_h);
fputs(" * *\n",text_h);
fputs(" * This program is free software; you can redistribute it and/or *\n",text_h);
fputs(" * modify it under the terms of the GNU General Public License *\n",text_h);
fputs(" * as published by the Free Software Foundation; either version 2 *\n",text_h);
fputs(" * of the License, or (at your option) any later version. *\n",text_h);
fputs(" * See the GNU General Public License for more details: gpl.txt or *\n",text_h);
fputs(" * http://www.fsf.org/copyleft/gpl.html *\n",text_h);
fputs(" * *\n",text_h);
fputs(" * Anonymous FTP access to the most recent released source is available at *\n",text_h);
fputs(" * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *\n",text_h);
fputs(" * *\n",text_h);
fputs(" * Anonymous CVS access to the development source and modification history *\n",text_h);
fputs(" * is available at cvs.synchro.net:/cvsroot/sbbs, example: *\n",text_h);
fputs(" * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *\n",text_h);
fputs(" * (just hit return, no password is necessary) *\n",text_h);
fputs(" * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *\n",text_h);
fputs(" * *\n",text_h);
fputs(" * For Synchronet coding style and modification guidelines, see *\n",text_h);
fputs(" * http://www.synchro.net/source.html *\n",text_h);
fputs(" * *\n",text_h);
fputs(" * You are encouraged to submit any modifications (preferably in Unix diff *\n",text_h);
fputs(" * format) via e-mail to [email protected] *\n",text_h);
fputs(" * *\n",text_h);
fputs(" * Note: If this box doesn't appear square, then you need to fix your tabs. *\n",text_h);
fputs(" ****************************************************************************/\n",text_h);
fputs("\n",text_h);
fputs("/****************************************************************************/\n",text_h);
fputs("/* Macros for elements of the array of pointers (text[]) to static text */\n",text_h);
fputs("/* Auto-generated from CTRL\\TEXT.DAT */\n",text_h);
fputs("/****************************************************************************/\n",text_h);
fputs("\n",text_h);
fputs("#ifndef _TEXT_H\n",text_h);
fputs("#define _TEXT_H\n",text_h);
fputs("\n",text_h);
fputs("enum {\n",text_h);
if((p=getenv("SBBSEXEC"))==NULL)
p="/sbbs/exec";
sprintf(path,"%s/load/text.js",p);
if((text_js=fopen(path, "w"))==NULL) {
perror(path);
return(1);
}
fputs("/* $Id: textgen.c,v 1.1.1.1 2018/04/24 16:42:38 root Exp $ */\n",text_js);
fputs("\n",text_js);
fputs("/* Synchronet static text string constants */\n",text_js);
fputs("\n",text_js);
fputs("/* Automatically generated by textgen $ */\n",text_js);
fputs("\n",text_js);
fputs("/****************************************************************************/\n",text_js);
fputs("/* Values for elements of the array of pointers (bbs.text()) to static text */\n",text_js);
fputs("/* Auto-generated from ctrl/text.dat */\n",text_js);
fputs("/****************************************************************************/\n",text_js);
fputs("\n",text_js);
if((text_defaults_c=fopen("text_defaults.c","w"))==NULL) {
fprintf(stderr,"Can't open text_defaults.c!\n");
return(1);
}
fputs("/* $Id: textgen.c,v 1.1.1.1 2018/04/24 16:42:38 root Exp $ */\n",text_defaults_c);
fputs("\n",text_defaults_c);
fputs("/* Synchronet default text strings */\n",text_defaults_c);
fputs("\n",text_defaults_c);
fputs("/* Automatically generated by textgen $ */\n",text_defaults_c);
fputs("\n",text_defaults_c);
fputs("#include \"text_defaults.h\"\n",text_defaults_c);
fputs("\n",text_defaults_c);
fputs("const char * const text_defaults[TOTAL_TEXT]={\n",text_defaults_c);
do {
i++;
p=readtext(text_dat, &comment);
if(p!=NULL) {
cstr=format_as_cstr(p);
if(cstr==NULL) {
fprintf(stderr,"Error creating C string! for %d\n", i+1);
}
lno=strtoul(comment, ¯o, 10);
while(isspace(*macro))
macro++;
if((int)lno != i) {
fprintf(stderr,"Mismatch! %s has %d... should be %d\n", comment, lno, i);
}
fprintf(text_h, "\t%c%s\n", i==1?' ':',', macro);
fprintf(text_js, "var %s=%d;\n", macro, i);
fprintf(text_defaults_c, "\t%c%s\n", i==1?' ':',', cstr);
}
} while(p != NULL);
fclose(text_dat);
fputs("\n",text_h);
fputs("\t,TOTAL_TEXT\n",text_h);
fputs("};\n",text_h);
fputs("\n",text_h);
fputs("#endif\n",text_h);
fclose(text_h);
fputs("\n",text_h);
fprintf(text_h, "var TOTAL_TEXT=%d;\n",i);
fclose(text_js);
fputs("};\n",text_defaults_c);
fclose(text_defaults_c);
return 0;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.