|
|
1.1 root 1: #include <ctype.h>
2: #include <stdio.h>
3: #include <stdlib.h>
4: #include <string.h>
5: #include "gen_defs.h"
6:
7: /****************************************************************************/
8: /* Converts an ASCII Hex string into an ulong */
9: /* by Steve Deppe (Ille Homine Albe) */
10: /****************************************************************************/
11: /* Copied from str_util.c */
12: ulong ahtoul(char *str)
13: {
14: ulong l,val=0;
15:
16: while((l=(*str++)|0x20)!=0x20)
17: val=(l&0xf)+(l>>6&1)*9+val*16;
18: return(val);
19: }
20:
21: /****************************************************************************/
22: /* Reads special TEXT.DAT printf style text lines, splicing multiple lines, */
23: /* replacing escaped characters, and allocating the memory */
24: /****************************************************************************/
25: /* Copied from load_cfg.c with comment pointer added */
26: char *readtext(FILE *stream, char **comment_ret)
27: {
28: char buf[2048],str[2048],tmp[256],*p,*p2;
29: char comment[2048], *cp;
30: int i,j,k;
31:
32: if(!fgets(buf,256,stream))
33: return(NULL);
34: if(buf[0]=='#')
35: return(NULL);
36: p=strrchr(buf,'"');
37: if(!p) {
38: return(NULL);
39: }
40: comment[0]=0;
41: if(*(p+1)=='\\') { /* merge multiple lines */
42: for(cp=p+2; *cp && isspace(*cp); cp++);
43: strcat(comment, cp);
44: while(strlen(buf)<2000) {
45: if(!fgets(str,255,stream))
46: return(NULL);
47: p2=strchr(str,'"');
48: if(!p2)
49: continue;
50: strcpy(p,p2+1);
51: p=strrchr(p,'"');
52: if(p && *(p+1)=='\\') {
53: for(cp=p+2; *cp && isspace(*cp); cp++);
54: strcat(comment, cp);
55: continue;
56: }
57: break;
58: }
59: }
60: for(cp=p+2; *cp && isspace(*cp); cp++);
61: strcat(comment, cp);
62: cp=strchr(comment, 0);
63: if(cp && cp > comment) {
64: cp--;
65: while(cp > comment && isspace(*cp)) {
66: *(cp--)=0;
67: }
68: }
69:
70: *(p)=0;
71: k=strlen(buf);
72: for(i=1,j=0;i<k;j++) {
73: if(buf[i]=='\\') { /* escape */
74: i++;
75: if(isdigit(buf[i])) {
76: str[j]=atoi(buf+i); /* decimal, NOT octal */
77: if(isdigit(buf[++i])) /* skip up to 3 digits */
78: if(isdigit(buf[++i]))
79: i++;
80: continue;
81: }
82: switch(buf[i++]) {
83: case '\\':
84: str[j]='\\';
85: break;
86: case '?':
87: str[j]='?';
88: break;
89: case 'x':
90: tmp[0]=buf[i++]; /* skip next character */
91: tmp[1]=0;
92: if(isxdigit(buf[i])) { /* if another hex digit, skip too */
93: tmp[1]=buf[i++];
94: tmp[2]=0;
95: }
96: str[j]=(char)ahtoul(tmp);
97: break;
98: case '\'':
99: str[j]='\'';
100: break;
101: case '"':
102: str[j]='"';
103: break;
104: case 'r':
105: str[j]=CR;
106: break;
107: case 'n':
108: str[j]=LF;
109: break;
110: case 't':
111: str[j]=TAB;
112: break;
113: case 'b':
114: str[j]=BS;
115: break;
116: case 'a':
117: str[j]=BEL;
118: break;
119: case 'f':
120: str[j]=FF;
121: break;
122: case 'v':
123: str[j]=11; /* VT */
124: break;
125: default:
126: str[j]=buf[i];
127: break;
128: }
129: continue;
130: }
131: str[j]=buf[i++];
132: }
133: str[j]=0;
134: if((p=(char *)calloc(1,j+2))==NULL) { /* +1 for terminator, +1 for YNQX line */
135: fprintf(stderr,"Error allocating %u bytes of memory from text.dat",j);
136: return(NULL);
137: }
138: strcpy(p,str);
139: if(comment_ret)
140: *comment_ret=strdup(comment);
141: return(p);
142: }
143:
144: char *format_as_cstr(char *orig)
145: {
146: int len=0;
147: char *ret=NULL;
148: char *in;
149: char hex[32];
150: int outpos=0;
151:
152: len=strlen(orig);
153: len += ((len / 32)*2);
154: len *= 6;
155: len += 32; /* Only needs to be three, the extra is for luck ;-) */
156:
157: ret=(char *)malloc(len);
158: if(ret==NULL)
159: return(ret);
160: strcpy(ret,"\"");
161: for(in=orig; *in; in++) {
162: sprintf(hex, "\\x%02x", (unsigned char)*in);
163: strcat(ret,hex);
164: if((++outpos)%32==0)
165: strcat(ret,"\"\n\t\t\"");
166: }
167: strcat(ret, "\"");
168: return(ret);
169: }
170:
171: int main(int argc, char **argv)
172: {
173: FILE *text_dat;
174: char path[MAX_PATH+1];
175: char *p;
176: char *cstr;
177: char *comment;
178: char *macro;
179: unsigned long lno;
180: int i=0;
181: FILE *text_h;
182: FILE *text_js;
183: FILE *text_defaults_c;
184:
185: if((p=getenv("SBBSCTRL"))==NULL)
186: p="/sbbs/ctrl";
187: sprintf(path,"%s/text.dat",p);
188: if((text_dat=fopen(path,"r"))==NULL) {
189: perror(path);
190: return(1);
191: }
192: if((text_h=fopen("text.h", "w"))==NULL) {
193: perror("text.h");
194: return(1);
195: }
196: fputs("/* text.h */\n",text_h);
197: fputs("\n",text_h);
198: fputs("/* Synchronet static text string constants */\n",text_h);
199: fputs("\n",text_h);
200: fputs("/* $Id: textgen.c,v 1.5 2009/10/20 06:52:32 rswindell Exp $ */\n",text_h);
201: fputs("\n",text_h);
202: fputs("/****************************************************************************\n",text_h);
203: fputs(" * @format.tab-size 4 (Plain Text/Source Code File Header) *\n",text_h);
204: fputs(" * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *\n",text_h);
205: fputs(" * *\n",text_h);
206: fputs(" * Copyright 2009 Rob Swindell - http://www.synchro.net/copyright.html *\n",text_h);
207: fputs(" * *\n",text_h);
208: fputs(" * This program is free software; you can redistribute it and/or *\n",text_h);
209: fputs(" * modify it under the terms of the GNU General Public License *\n",text_h);
210: fputs(" * as published by the Free Software Foundation; either version 2 *\n",text_h);
211: fputs(" * of the License, or (at your option) any later version. *\n",text_h);
212: fputs(" * See the GNU General Public License for more details: gpl.txt or *\n",text_h);
213: fputs(" * http://www.fsf.org/copyleft/gpl.html *\n",text_h);
214: fputs(" * *\n",text_h);
215: fputs(" * Anonymous FTP access to the most recent released source is available at *\n",text_h);
216: fputs(" * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *\n",text_h);
217: fputs(" * *\n",text_h);
218: fputs(" * Anonymous CVS access to the development source and modification history *\n",text_h);
219: fputs(" * is available at cvs.synchro.net:/cvsroot/sbbs, example: *\n",text_h);
220: fputs(" * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *\n",text_h);
221: fputs(" * (just hit return, no password is necessary) *\n",text_h);
222: fputs(" * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *\n",text_h);
223: fputs(" * *\n",text_h);
224: fputs(" * For Synchronet coding style and modification guidelines, see *\n",text_h);
225: fputs(" * http://www.synchro.net/source.html *\n",text_h);
226: fputs(" * *\n",text_h);
227: fputs(" * You are encouraged to submit any modifications (preferably in Unix diff *\n",text_h);
228: fputs(" * format) via e-mail to [email protected] *\n",text_h);
229: fputs(" * *\n",text_h);
230: fputs(" * Note: If this box doesn't appear square, then you need to fix your tabs. *\n",text_h);
231: fputs(" ****************************************************************************/\n",text_h);
232: fputs("\n",text_h);
233: fputs("/****************************************************************************/\n",text_h);
234: fputs("/* Macros for elements of the array of pointers (text[]) to static text */\n",text_h);
235: fputs("/* Auto-generated from CTRL\\TEXT.DAT */\n",text_h);
236: fputs("/****************************************************************************/\n",text_h);
237: fputs("\n",text_h);
238: fputs("#ifndef _TEXT_H\n",text_h);
239: fputs("#define _TEXT_H\n",text_h);
240: fputs("\n",text_h);
241: fputs("enum {\n",text_h);
242:
243: if((p=getenv("SBBSEXEC"))==NULL)
244: p="/sbbs/exec";
245: sprintf(path,"%s/load/text.js",p);
246: if((text_js=fopen(path, "w"))==NULL) {
247: perror(path);
248: return(1);
249: }
250: fputs("/* $Id: textgen.c,v 1.5 2009/10/20 06:52:32 rswindell Exp $ */\n",text_js);
251: fputs("\n",text_js);
252: fputs("/* Synchronet static text string constants */\n",text_js);
253: fputs("\n",text_js);
254: fputs("/* Automatically generated by textgen $ */\n",text_js);
255: fputs("\n",text_js);
256: fputs("/****************************************************************************/\n",text_js);
257: fputs("/* Values for elements of the array of pointers (bbs.text()) to static text */\n",text_js);
258: fputs("/* Auto-generated from ctrl/text.dat */\n",text_js);
259: fputs("/****************************************************************************/\n",text_js);
260: fputs("\n",text_js);
261: if((text_defaults_c=fopen("text_defaults.c","w"))==NULL) {
262: fprintf(stderr,"Can't open text_defaults.c!\n");
263: return(1);
264: }
265: fputs("/* $Id: textgen.c,v 1.5 2009/10/20 06:52:32 rswindell Exp $ */\n",text_defaults_c);
266: fputs("\n",text_defaults_c);
267: fputs("/* Synchronet default text strings */\n",text_defaults_c);
268: fputs("\n",text_defaults_c);
269: fputs("/* Automatically generated by textgen $ */\n",text_defaults_c);
270: fputs("\n",text_defaults_c);
271: fputs("#include \"text_defaults.h\"\n",text_defaults_c);
272: fputs("\n",text_defaults_c);
273: fputs("const char * const text_defaults[TOTAL_TEXT]={\n",text_defaults_c);
274: do {
275: i++;
276: p=readtext(text_dat, &comment);
277: if(p!=NULL) {
278: cstr=format_as_cstr(p);
279: if(cstr==NULL) {
280: fprintf(stderr,"Error creating C string! for %d\n", i+1);
281: }
282: lno=strtoul(comment, ¯o, 10);
283: while(isspace(*macro))
284: macro++;
285: if((int)lno != i) {
286: fprintf(stderr,"Mismatch! %s has %d... should be %d\n", comment, lno, i);
287: }
288: fprintf(text_h, "\t%c%s\n", i==1?' ':',', macro);
289: fprintf(text_js, "var %s=%d;\n", macro, i);
290: fprintf(text_defaults_c, "\t%c%s\n", i==1?' ':',', cstr);
291: }
292: } while(p != NULL);
293: fclose(text_dat);
294:
295: fputs("\n",text_h);
296: fputs("\t,TOTAL_TEXT\n",text_h);
297: fputs("};\n",text_h);
298: fputs("\n",text_h);
299: fputs("#endif\n",text_h);
300: fclose(text_h);
301: fputs("\n",text_h);
302: fprintf(text_h, "var TOTAL_TEXT=%d;\n",i);
303: fclose(text_js);
304: fputs("};\n",text_defaults_c);
305: fclose(text_defaults_c);
306:
307: return 0;
308: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.