![]() | This has been moved to doc/i/tutorial/. |
#!/usr/cogent/bin/gamma
/*
* This program reads a Gamma program that has been marked up with
* processing instructions, and splits it into chunk files suitable
* for inserting into documentation text. It then writes a copy of the
* program without the processing instructions. The source program name
* should have an extra character (I usually use "d") before the ".g",
* like this: <programname>d.g
* The final program name will not have the final character, like this:
* <programname>.g
* The chunk files should be of this format:
* <programname>_<#>.g
* where <#> is an integer representing the cardinal order of the chunks.
*
* Most of the functions in this program are processing instructions that are
* called from a source program, as special comment lines, with this format:
*
* //PI (setq write_file (doc_begin <filename>)) - opens the file.
* //PI (setq enabled 1) - starts writing.
* //PI (setq enabled 0) - finishes writing.
* //PI (setq write_file (doc_end write_file)) - closes the file.
* //PI (doc_newfile <filename>) - finishes and closes a file,
* then opens and starts a new
* file, for convenience.
*
* If a file has been opened, you can call this function:
* //PI (doc_embed_string write_file <string>) - writes the string.
*/
PI_PATH = "../../i/tutorial/";
if (root_path(cadr(argv)) == "../../i/tutorial")
BASENAME = basename(cadr(argv), "d.g");
else
BASENAME = string("lib/", basename(cadr(argv), "d.g"));
function doc_begin(!filename)
{
local fp;
if (!undefined_p(eval(filename))) // This is necessary for calls
filename = eval(filename); // from doc_newfile().
if (fp = open (string(PI_PATH, "chunks/", filename), "w"))
fp;
else
error (string("Failed to open file: ", filename));
}
function doc_end(fp)
{
flush(fp);
close(fp);
nil;
}
function doc_embed_string(fp, string)
{
writec(fp, string);
}
/* This is a convenience function that compresses these four
lines of code in the program to one line.*/
function doc_newfile(!fl)
{
enabled = 0;
doc_end(write_file);
write_file = doc_begin(fl);
enabled = 1;
}
function main()
{
local fr, preproc_file = nil, evs, line = nil, dv,
write_file = nil, enabled = 0, pilist = list();
/* Preprocess the file to change any \n to PI_NEWLINE
to hide it from the parser */
system(string("sed ", PI_PATH, BASENAME, "d.g -e 's/\\\\n/PI_NEWLINE/g' > temp"));
system(string("mv temp ", PI_PATH, "preproc_file"));
if (fr = open(string(PI_PATH, "preproc_file"), "r"))
{
/* Make the chunk files. */
line = read_line(fr);
while (line != _eof_)
{
if (strstr(line, "//PI") == 0)
{
evs = eval_string(substr(line, 4, -1));
}
if ((write_file != nil) &&
(enabled == 1) &&
(strstr(line, "//PI") != 0))
{
writec(write_file, string(" ", line, "\n"));
}
line = read_line(fr);
}
close(fr);
/* Create a distribution version of the code with
all processing instructions removed. (This makes a
call to the Perl program replacer.pl.) */
dn = string(PI_PATH, BASENAME, ".g");
system(string("grep -v \'\/\/PI\' ",
PI_PATH,
BASENAME,
"d.g > ",
dn));
system(string(PI_PATH, "replacer.pl ", dn));
/* Make a list of all chunk files */
system(string("ls ", PI_PATH, "chunks/", basename(BASENAME), "_*.g > temp"));
fp = open("temp", "r");
line = nil;
while (line != _eof_)
{
if (line != nil)
pilist = cons(line, pilist);
line = read_line(fp);
}
close(fp);
/* Call the replacer.pl script to replace all tabs and newlines
for every chunk file in the list. */
with x in pilist do
{
system(string(PI_PATH, "replacer.pl ", x));
}
}
else
error (string("Failed to open file: ", file));
}
Copyright © 1995-2004 by Cogent Real-Time Systems, Inc. All rights reserved.