XTRAN Example — Add I/O Documentation to C
The following example uses a set of XTRAN rules
that analyzes the stream I/O in C code and adds a comment at the
beginning of the module documenting that I/O before putting the code
back out. The rule set handles the full set of I/O calls declared
in stdio.h
.
The XTRAN rules know, for each I/O function
call declared in stdio.h
, its implications in terms of
file activity. This includes knowing the nature of the formal
parameters (and corresponding calling arguments) to each
function.
The rules used are specific to C and its stream I/O, but they can easily be adapted for any computer language, whether I/O is implemented as part of the language's syntax, via preprocessor constructs, or via subroutine calls.
How can such powerful code manipulation be automated in only 4 hours and 195 lines of meta-code? Because there is so much capability already available as part of XTRAN's rules language. The rules used for this example take advantage of the following functionality provided by that rules language:
- Text manipulation
- Text formatting
- Delimited list manipulation
- Content-addressable data bases
- "Per statement" recursive iterators
- "Per expression" recursive iterators
- Access to XTRAN's Internal Representation (XIR)
- Navigation in XIR
- Creating new meta-functions written in meta-code
- Meta-variable and meta-function pointers
NOTE that the rendered code shown as XTRAN's output below was done with default conditions; XTRAN provides many options for controlling the way it renders code for output.
XTRAN's input and output shown below are untouched, except that the documentation comment XTRAN added has been highlighted in red.
Process Flowchart
Here is a flowchart for this process, in which the elements are color coded:
- BLUE for XTRAN versions (runnable programs)
- ORANGE for XTRAN rules (text files)
- RED for
code
Input to XTRAN:
/* demdio-r.c -- Demonstrate XTRAN rules that document I/O * Revised 2005-03-16.0032 by Stephen F. Heffner (Win2K on I8100) * Written 2005-03-16 by Stephen F. Heffner (Win2K on I8100) */ #include <stdio.h> /*Posix-style I/O*/ #define MAXLIN 500 /*max line length*/ extern FILE *p_ext_file; /*global file ptr*/ void func(FILE *p_param_file) { FILE *p_lcl_file, *p_tmp_file; /*local file ptrs*/ char p_line_txt[MAXLIN + 1]; /*file I/O buffer*/ fgets(p_line_txt, MAXLIN, p_ext_file); /*read a line from ext file*/ fclose(p_ext_file); /*close external file*/ p_lcl_file = fopen("foo.dat", "a"); /*open for append*/ fputs(p_line_txt, p_lcl_file); /*append a line*/ p_tmp_file = tmpfile(); /*create temp file*/ fputs(p_line_txt, p_tmp_file); /*write a line to it*/ fputs("end\n", p_tmp_file); /*write to it again*/ fclose(p_tmp_file); /*close it*/ printf("%d", 3); /*write to stdout*/ return; }
Output from XTRAN:
/* demdio-r.c -- Demonstrate XTRAN rules that document I/O * Revised 2005-03-16.0032 by Stephen F. Heffner (Win2K on I8100) * Written 2005-03-16 by Stephen F. Heffner (Win2K on I8100) */ /* * Stream I/O in this module as of 2005-03-21: * * Reads from p_ext_file * Closes p_ext_file * Appends to "foo.dat"; pointer p_lcl_file * Writes to p_lcl_file * Creates p_tmp_file * Writes to p_tmp_file * Closes p_tmp_file * Writes to stdout */ #include <stdio.h> /*Posix-style I/O*/ #define MAXLIN 500 /*max line length*/ extern FILE *p_ext_file; /*global file ptr*/ void func(FILE *p_param_file) { FILE *p_lcl_file, *p_tmp_file; /*local file ptrs*/ char p_line_txt[MAXLIN + 1]; /*file I/O buffer*/ fgets(p_line_txt, MAXLIN, p_ext_file); /*read a line from ext file*/ fclose(p_ext_file); /*close external file*/ p_lcl_file = fopen("foo.dat", "a"); /*open for append*/ fputs(p_line_txt, p_lcl_file); /*append a line*/ p_tmp_file = tmpfile(); /*create temp file*/ fputs(p_line_txt, p_tmp_file); /*write a line to it*/ fputs("end\n", p_tmp_file); /*write to it again*/ fclose(p_tmp_file); /*close it*/ printf("%d", 3); /*write to stdout*/ return; }