|
|
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.