[net.sources.mac] Backslash escapes for rmaker strings.

ech@spuxll.UUCP (Ned Horvath) (07/03/85)

<Milk and cookies for Santa>

This is a change I just made to the SUMacC rmaker's datastring() function to
implement backslash escapes.  The usual C escapes are here (\bfnrt) although
it is not clear what value they have except for \r, along with \ooo where the
o's are octal digits.  I also added a nonstandard \xhh where the h's are
hex digits [0-9a-fA-F].  Anything else following a \ is just copied.  Note
that a trailing \ will NOT escape the newline.

With the escapes, one can code, for example,
	Type STR
		,512
	To Cancel:\rHold down \x11 and hit .
where the \r codes for a carriage return and the \x11 is the code for the
command character.

Line numbers may vary, I have hacked the rmaker a bit; also I am not sure how
universal ctype.h is: I presume anyone who lacks 'isdigit', 'isxdigit', and
'tolower' can roll their own easily enough...

Potential bug: \xaaaa will eat all the a's, and \00000 will eat all the zeros.

=Ned=


30a31
> #include <ctype.h>
******* following are mods to datastring() ******
166a168,169
> 	register c;
> 	int shft;
168,169c171,224
< 	for (datap++, len = 0 ; *sp ; len++)
< 		*datap++ = *sp++;
---
> 	for (datap++, len = 0 ; *sp ; len++) {
> 		if ((c = *sp++) != '\\') {
> 			*datap++ = c;
> 			continue;
> 		}
> 		switch (c = *sp++) {
> 		default:
> 			*datap++ = c;
> 			continue;
> 		case 'b':
> 			*datap++ = '\b';
> 			continue;
> 		case 'f':
> 			*datap++ = '\f';
> 			continue;
> 		case 'n':
> 			*datap++ = '\n';
> 			continue;
> 		case 'r':
> 			*datap++ = '\r';
> 			continue;
> 		case 't':
> 			*datap++ = '\t';
> 			continue;
> 		case '0':
> 		case '1':
> 		case '2':
> 		case '3':
> 		case '4':
> 		case '5':
> 		case '6':
> 		case '7':
> 			shft = 3;	/* octal constant */
> 			*datap = c - '0';
> 			goto eatit;
> 		case 'x':		/* hex constant */
> 			shft = 4;
> 			*datap = 0;
> 		eatit:
> 			for (c = tolower (*sp);; c = tolower (*++sp)) {
> 				if (isdigit (c)) {
> 					c -= '0';
> 				} else if (shft == 4 && isxdigit (c)) {
> 					c -= 'a' - 10;
> 				} else {
> 					break;
> 				}
> 				*datap <<= shft;
> 				*datap |= (c&0xf);
> 			}
> 			datap++;
> 			break;
> 		}
> 	}