C Preprocessing With Tcl
by Jonathan Arney

Example 1:

(a)
set a "abcdefg"
puts stdout $a

(b)
proc print_a_string {a} {
	puts stdout $a
}
print_a_string "abcdefg"


Example 2:

(a)
#$
set include_file "<stdio.h>"
puts stdout "#include $include_file"
#$
int main(int argc, char **argv)
{
	printf("Hello World");
}

(b)
#include <stdio.h>
int main(int argc, char **argv)
{
	printf("Hello World");
}

Example 3:

(a)
#include <stdio.h>
#$
set pi 3.14159265359
puts stdout "float s_cos_table\[181\] = {"
set deg 0
while { 1 } {
	puts stdout "[expr cos(($deg*$pi)/180) ]" nonewline 
		incr deg 
	if { $deg == 180 } break; 
	puts stdout "," 
}
puts stdout "};"
proc c_cos {a} { \
	puts stdout s_cos_table\\[$a\\] \
}
#$
int main(int argc, char **argv)
{
	int     i;
	for (i = 0; i < 180; i++) {
		printf("Cosine of %i is %f\n", i, #$c_cos i#$);
	}
}

(b)
#include <stdio.h>
float s_cos_table[181] = {
1.0,
0.999848,
 ...
-0.999391,
-0.999848};
int main(int argc, char **argv)
{
	int     i;
	for (i = 0; i < 180; i++) {
		printf("Cosine of %i is %f\n", i, s_cos_table[i]);
	}
}

Listing One
#include <tcl.h>
#define modeCC		1
#define modeCPDQ	2
#define BUFFER_SIZE	512

char *read_to_delimiter(FILE *f, char *delimiter);
int main(int argc, char **argv)
{
	Tcl_Interp	*interp;
	char	*s;
	int	mode = modeCC;
	FILE	*f,*fout;
	f = stdin;
	fout = stdout;
	interp = Tcl_CreateInterp();
	while (1) {
		s = read_to_delimiter(f, "#$");
		if (!*s) break;
		switch (mode) {
			case modeCC:
				fputs(s, fout);
				mode = modeCPDQ;
				break;
			case modeCPDQ:
				if (Tcl_Eval(interp, s) != TCL_OK) {
					fprintf(stderr, "%s\n", interp->result);
					exit(2);
				}
				mode = modeCC;
				break;
		}
		free(s);
		fflush(fout);
	}
	Tcl_DeleteInterp(interp);
}
char *read_to_delimiter(FILE *f, char *delimiter)
{
	char	*str, *ret;
	len = BUFFER_SIZE;
	ptr = 0;
	ret = str = (char *)malloc(sizeof(char) * len);
	i = 0;
		*str = fgetc(f);
		if (feof(f)) break;
		if (*str == delimiter[i]) i++;
		else i = 0;
		if (delimiter[i] == '\0') {
			str -= strlen(delimiter)-1;
			break;
		}
		str++; ptr++;
		if (ptr == len) {
			len += BUFFER_SIZE;
			str = (char *)realloc(ret, sizeof(char) * len);
		}
	}
	*str = '\0';
	return ret;
}



3


