Skip to content
Snippets Groups Projects
readtext.c 3.81 KiB
/* Read a string (item) from ctrl/text.dat */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
 *																			*
 * 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.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

#include "sbbsdefs.h"
#include "str_util.h"
#include "text_defaults.h"	/* text_defaults */

int lprintf(int level, const char *fmt, ...);       /* log output */
/****************************************************************************/
/* Reads special TEXT.DAT printf style text lines, splicing multiple lines, */
/* replacing escaped characters, and allocating the memory					*/
/****************************************************************************/
char *readtext(long *line,FILE *stream,long dflt)
{
	char buf[MAX_TEXTDAT_ITEM_LEN+256],str[MAX_TEXTDAT_ITEM_LEN+1],tmp[256],*p,*p2;
	int i,j,k;

	if(!fgets(buf,256,stream)) {
		/* Hide the EOF */
		if(feof(stream))
			clearerr(stream);
		goto use_default;
	}
	if(line)
		(*line)++;
	if(buf[0]=='#')
		goto use_default;
	p=strrchr(buf,'"');
	if(!p) {
		if(line)
			lprintf(LOG_WARNING,"No quotation marks in line %ld of text.dat",*line);
		goto use_default;
	}
	if(*(p+1)=='\\')	/* merge multiple lines */
		while(strlen(buf)<MAX_TEXTDAT_ITEM_LEN) {
			if(!fgets(str,255,stream)) {
				/* Hide the EOF */
				if(feof(stream))
					clearerr(stream);
				goto use_default;
			}
			if(line)
				(*line)++;
			p2=strchr(str,'"');
			if(!p2)
				continue;
			strcpy(p,p2+1);
			p=strrchr(p,'"');
			if(p && *(p+1)=='\\')
				continue;
			break; 
		}
	*(p)=0;
	k=strlen(buf);
	for(i=1,j=0;i<k && j<sizeof(str)-1;j++) {
		if(buf[i]=='\\')	{ /* escape */
			i++;
			if(IS_DIGIT(buf[i])) {
				str[j]=atoi(buf+i); 	/* decimal, NOT octal */
				if(IS_DIGIT(buf[++i]))	/* skip up to 3 digits */
					if(IS_DIGIT(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 */
		lprintf(LOG_CRIT,"Error allocating %u bytes of memory from text.dat",j);
		goto use_default;
	}
	strcpy(p,str);
	return(p);
use_default:
	p=strdup(text_defaults[dflt]);
	if(p==NULL)
		lprintf(LOG_CRIT,"Error duplicating %s text defaults",text_defaults[dflt]);
	return(p);
}