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.

These rules comprise 195 code lines of XTRAN's rules language ("meta-code"), and took about four hours to create.  (That's right, four hours!)

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:

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:

process flowchart

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;
}