#include <stdio.h>

#define ROWS	4
/*...*/

int pows[ROWS][COLS] = {  /*...*/ };

int main(int argc, char *argv[])
{
  extern void checknum(int);
  extern void to_roman(int, char []);
  int low;
  char roman[25];
  /*...*/
  checknum(low)
  /*...*/
  to_roman(low, roman);
}

void checknum(int value)
{
  /* ...fprintf(...) ...*/
}

void to_roman(int decimal,
	      char roman[])
{
  /*... ROWS ...*/
}

/* roman.c */
#include <stdio.h>

#define ROWS	4
/*...*/

int pows[ROWS][COLS] = {  /*...*/ };

int main(int argc, char *argv[])
{
  extern void checknum(int);
  extern void to_roman(int, char []);
  int low;
  char roman[25];
  /*...*/
  checknum(low)
  /*...*/
  to_roman(low, roman);
}

/* checknum.c */
#include <stdio.h>

void checknum(int value)
{
  /* ...fprintf(...) ...*/
}

/* to_roman.c */
#define ROWS	4
/*...*/

extern int pows[ROWS][COLS];

void to_roman(int decimal,
	      char roman[])
{
  /*... ROWS ...*/
}

args-required.sh:
------------------
if test $# -eq 0
then
	echo "$USAGE" >&2
	exit 1
fi
------------------

cmd-body.sh:
------------------
includeonce(args-required.sh)
echo $2 $1
------------------

------------------
includeonce(args-required.sh)
includeonce(cmd-body.sh)
------------------

becomes

------------------
if test $# -eq 0
then
	echo "$USAGE" >&2
	exit 1
fi
includeonce(args-required.sh)
echo $2 $1
------------------

while (not end of file)
  if doesn't begin with "includeonce("
    copy it to stdout
  else
    if it has been included
      ignore it
    else
      open the file and do all this
      record the file as included


STRING SET
  operations
    void string_set_insert(char [])
    int string_set_has(char [])

/* #includes */
/* #defines */
extern void shpp(FILE *);
main()
{
   /* ... */
   shpp(stdin);
}

/* string_set external variables */
void string_set_insert(char [])
{ /* ... */ }
int string_set_has(char [])
{ /* ... */ }

void shpp(FILE *fp)
{
  /*... string_set_has(buf) ...*/
}

How to represent the set?

void string_set_insert(char s[])
   /* effect: put copy of s in the set */
int string_set_has(char s[])
   /* effect: is s in the set? */

How is the set created?

----------------------
#define MAX_TRACKED_INCLUDES 1000
#define MAX_PATHNAME_LENGTH 500

char already_included[MAX_TRACKED_INCLUDES]
		     [MAX_PATHNAME_LENGTH];
int num_tracked = 0;

void string_set_insert(char s[])
   /* EFFECT: put a copy of s in the set */
{
  int i;
  for (i=0; i<num_tracked; i++) {
    if (strcmp(s,already_included[i]) == 0) {
      return;
    }
  }
  strcpy(already_included[num_tracked], s);
  num_tracked++;
}

int string_set_has(char s[])
   /* EFFECT: is s in the set? */
{
  int i;
  for (i=0; i<num_tracked; i++) {
    if (strcmp(s,already_included[i]) == 0) {
      return(1);
    }
  }
  return(0);
}

main()
{
  /* ... */
}

char already_included[500][100];

string_set_has(char s[])
{
  /* ... */
}

string_set.c:
--------------------
void string_set_insert(char [])
{ /* ... */ }
int string_set_has(char [])
{ /* ... */ }
--------------------

file shpp.c contains:

extern void string_set_insert(char []);
extern int string_set_has(char []);

string_set.h:
----------------------
extern void string_set_insert(char []);
extern int string_set_has(char []);
----------------------


file shpp.c contains:

#include "string_set.h"
