From:	MERC::"uunet!WKUVX1.BITNET!MacroMan" 26-APR-1992 16:05:18.77
To:	MACRO32%WKUVX1.BITNET@TGV.COM
CC:	
Subj:	Re:  OK, you C hackers under VMS, how do you do this:

>OK, you VMS hacking C experts (I know I'm going to hit some
>real ones in this news group), how do you deal with this include
>file naming problem when compiling "unix developed" code on the VAX?
[...]
>Is there a way to deal with this? (In the VAXC compiler).

I have a program, written by Peter Kay (i think), which does what
you want.  It's a preprocessor, unfortunately, but it does the trick.
Peter included it with this UNIXSHR socket library for VMS.

Here's a description:

preprocess takes a file a generates a new file with the following changes
1. it appends the #defines to change read's to si_read's etc
2. it converts #includes "xx/yy' to a form suitable for the vax c compiler
3. it splits long (>200odd chars) lines into several lines.
4. it converts >31 character identifiers into unique short forms

>I bet, somebody has a version of the GNU C compiler for VMS
>which has much better handling of filename translation
>for #include files. Right?
>
>I'm willing to go that route. Sure.

We use GCC here at TGV.  It does all of the things PREPROCESS does.
The only draw back is the lack of MACRO output (Dave Kashtan just
added that here) and .LIS files (working on that).   GCC allows you
to include MACRO code in-line.

We also use a slick little in-line expander which slips in between
phases of the GCC compiler and allows you to program-in any function
linkages you like.  For example, the string "splx(s);" could be replaced
by a series of in-line macro instructions, automatically.

-bruce

Here's the pre-processor:

#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define MAX_LENGTH 31

char *x[2000];
int x_count;
int changed;

main(argc, argv)
int argc;
char *argv[];
{
  int in_identifier, in_comment, in_quotes, in_preprocessor;
  int c, prev_c, count, length, i;
  char id[1024], s[256], buffer[256], *p, *q, *r, *strchr(), newbuff[256];
  FILE *fopen(), *infile, *outfile, *namesfile, *deffile;

  if (argc < 3) {
     printf("Usage: Preprocess infile outfile [longnamesfile]\n");
     exit();
  }

  if ( (infile = fopen(argv[1],"r")) == NULL) {
     printf("%s does not exist\n",argv[1]);
     exit();
  }
  if ( (outfile = fopen(argv[2],"w")) == NULL) {
     printf("Cannot open output file\n");
     exit();
  }
  x_count = -1;
  if ((argc == 4) && (namesfile = fopen(argv[3],"r")) != NULL) {
     while (fscanf(namesfile,"%s\n",s) != EOF) {
        x[++x_count] = malloc(strlen(s)+4);
        strcpy(x[x_count],s);
     }
     fclose(namesfile);
  }
  changed = 0;
  prev_c = '\n';
  length = 1;
  in_identifier = FALSE;
  in_comment = FALSE;
  in_quotes = FALSE;
  in_preprocessor = FALSE;
  if (argv[1][strlen(argv[1])-1] == 'c') {  /* add to beginning of .c files */
/* we really should read the include file not hard code it*/
     fprintf(outfile,"#define read si_read\n");
     fprintf(outfile,"#define write si_write\n");
     fprintf(outfile,"#define close si_close\n");
     fprintf(outfile,"#define fdopen si_fdopen\n");
     fprintf(outfile,"#define fprintf si_fprintf\n");
     fprintf(outfile,"#define fgets si_fgets\n");
     fprintf(outfile,"#define fputc si_fputc\n");
     fprintf(outfile,"#define fclose si_fclose\n");
     fprintf(outfile,"#define rewind si_rewind\n");
     fprintf(outfile,"#define fflush si_fflush\n");
     fprintf(outfile,"#define signal si_signal\n");
     fprintf(outfile,"#define sigvec si_sigvec\n");
     fprintf(outfile,"#define alarm si_alarm\n");
     fprintf(outfile,"#define gmtime si_gmtime\n");
     fprintf(outfile,"#define setgid si_setgid\n");
     fprintf(outfile,"#define setuid si_setuid\n");
     fprintf(outfile,"#define exit si_exit\n");
  }
  p = buffer;
  bzero(buffer,256);
  c = getc(infile);
  while (c != EOF) {
     if (prev_c == '\n') in_preprocessor = (c == '#');
     if ( (length > 160) && ( ! in_preprocessor) &&( ! in_quotes) && (c == ' '))
 {
        fprintf(outfile,"%s\n",buffer);
        bzero(buffer,256);
        p = buffer;
        length = 0;
     }
     if (length > 200) {
        *p++ = '\\';
        fprintf(outfile,"%s\n",buffer);
        bzero(buffer,256);
        p = buffer;
        length = 0;
     }
     if ( c == '\n') {
        length = 0;
     }
     if (in_quotes) {
        if (c == '"') in_quotes = FALSE;
        *p++ = c;
        length++;
     }
     else if (in_comment) {
        if ((c == '/') && (prev_c == '*')) in_comment = FALSE;
        *p++ = c;
        length++;
     }
     else if ( ! in_identifier) {
        if ( ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))
             || (c == '_') ) {
           in_identifier = TRUE;
           count = 0;
           id[count] = c;
        }
        else {
           if (c == '"') in_quotes = TRUE;
           if ((c=='*') && (prev_c == '/')) in_comment = TRUE;
           *p++ = c;
           length++;
        }
     }
     else {
        if ( ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))
             || ((c >= '0') && (c <= '9')) || (c == '_') ) {
           id[++count] = c;
        }
        else {
           id[++count] = 0;
           if (count < MAX_LENGTH) {
              sprintf(p,"%s",id);
              p += strlen(id);
              length += strlen(id);
           }
           else {
              sprintf(p,"%.*s%03d",MAX_LENGTH-3,id,xlate(id));
              p += MAX_LENGTH;
              length += MAX_LENGTH;
              if (argc != 4) printf("Warning - longnames but no file given\n");
           }
           *p++ = c;
           length++;
           in_identifier = FALSE;
        }
     }
     if (c == '\n') {
        if (buffer[0] == '#') {
           for(q=buffer+1;(*q == ' ') || (*q == '\t');q++);/*skip white space*/
           if (strncmp(q,"include",7) == 0) {
              p = strchr(buffer,'\"');  /* forget about <...> */
              if (p != NULL) {
                 q = strchr(p+1,'\"'); /* remove any comments */
                 q++;
                 *q++ = '\n';
                 *q++ = '\0';
                 if ((strchr(p,'/') != NULL) && (*(p+1) != '.')){ /* only fix "x
x/yy"
 */
                    strcpy(newbuff,"#include \"c$include_root:[");
                    q = newbuff+26;
                    p++;
                    r = p;
                    while ( (p = strchr(p,'/')) != NULL) {
                       if (strncmp(r,"../",3) == 0) {
                          *q++ = '-';
                          *q++ = '.';
                       }
                       else if (strncmp(r,"./",2) == 0) {
                       }
                       else {
                          for(;r != p;) *q++ = *r++;
                          *q++ = '.';
                       }
                       p++;
                       r = p;
                    }
                    q--;       /*overwrite last . with a ]*/
                    if (*q == '[') q++; /* but not if of form "./xx"*/
                    *q++ = ']';
                    strcpy(q,r);
                    strcpy(buffer,newbuff);
                 }
              }
           }
        }
        fprintf(outfile,"%s",buffer);
        bzero(buffer,256);
        p = buffer;
     }
     prev_c = c;
     c = getc(infile);
  }
  fclose(infile);
  fclose(outfile);
  if (changed == 0) exit();
  if (argc == 4) {
     namesfile = fopen(argv[3],"w");
     for(i=0;i<=x_count;i++) fprintf(namesfile,"%s\n",x[i]);
     fclose(namesfile);
  }
}

int xlate(s)
char *s;
{
  int i;
  for(i=0;i<=x_count;i++) if (strcmp(s,x[i]) == 0) return(i);
  x[++x_count] = malloc(strlen(s)+4);
  strcpy(x[x_count],s);
  changed = 1;
  return(x_count);
}

bzero(dst, length)
char *dst;
int length;
{
  int i;
  for (i=0;i<length;i++) *dst++ = '\0';
}

int getl(fp,s,lim)
FILE *fp;
char s[];
int lim;
{
  int c,i;
  i = 0;
  while (--lim>0 && (c=getc(fp)) != EOF && c != '\n') s[i++] = c;
  if (c == '\n') s[i++] = c;
  s[i] = '\0';
  return(i);
}


