/*-------------------------------------------------------------------------
  Program   : ModulaPrint.c
  Function  : Printutility for Modula_2 sourcecode
  Compiler  : Aztec C V3.6 a
  Options   : cc ModulaPrint.c -s +l   ln ModulaPrint.o -lc32
  Hints     : 
  Copyright : Public Domain
  Author    : ASSO 1990                                    
  -------------------------------------------------------------------------*/
#include <intuition/intuition.h>
#include <devices/printer.h>
#include <exec/types.h>
#include <stdio.h>

#define BOLD_ON     PrintCommand(request,aSGR1 ,0,0,0,0)
#define BOLD_OFF    PrintCommand(request,aSGR22,0,0,0,0)
#define ITALICS_ON  PrintCommand(request,aSGR3 ,0,0,0,0)
#define ITALICS_OFF PrintCommand(request,aSGR23,0,0,0,0)
#define MAXWORD   80
#define MAXKEY    67

union printerIO {
 struct IOStdReq    ios;
 struct IODRPReq    iodrp;
 struct IOPrtCmdReq iopc;
};
union printerIO *request;
extern struct IORequest *CreateExtIO();
extern struct MsgPort   *CreatePort();
struct MsgPort *printerPort;

int  Error,lines=0;
FILE *fp;
BOOL comment,string,quote;
char word[MAXWORD],
     *keyw[MAXKEY]; 
/*-----------------------------------------------
                                    main
  -----------------------------------------------*/
main (argc,argv)
int argc;
char *argv[];
{
 int  namebuf[20];
 char *name, *gets();
 
 if ((argc > 1) && (*argv[1] != '?'))  name = argv[1];
 else {
  printf("\033[2mUSAGE: ModulaPrint <filename.mod>\n"); 
  printf("Modula_2-Source-Print-Utility\n");
  printf("ASSO 1990\033[0m\n");
  printf("Enter filename: ");
  name = gets(namebuf);
 }
 if ((fp = fopen(name,"r")) == NULL) { /* open file */
  printf("Can't open file ! \n");
  exit(FALSE);
 }
 InitPrinter();
 InitKeyWords();
 ScanWords();
 CloseAll();
} 
/*-----------------------------------------------
                                       ScanWords
 ------------------------------------------------*/
ScanWords()
{  
 int count,j,com;
 char current,prev;

 comment=string=quote=FALSE;
 current=prev='\0';
 com=j=0;

 PrLnNr();                    /* print first linenumber */
 
 while ((current = getc(fp)) != EOF){

   if (current == '\n'){                      /* new line */
    if (j>0) {
     checkword(); j=0;
    }
    PrLnNr();
    current='\0';
   }
   if (current == '\t'){                      /* tabs  */
    if (j>0) {
     checkword(); j=0;
    }
    PrintString(request,"\t");
    current='\0';
   }
   if (comment) {                             /* comment off */
    if (prev == '*' && current == ')')       
      com--;
    if (prev == '(' && current == '*') 
      com++;
    if (com == 0) {
     comment=FALSE;
     ITALICS_OFF;
     PrintString(request,")");
     current='\0';
    } else
      PrintString(request,&current);
   }
   if (string) {                              /* string off */
      PrintString(request,&current);
       if (current == '\"'){
         string=FALSE;
         current='\0';
        } 
     }   
     if (quote) {                              /* quote off */
      PrintString(request,&current);
       if (current == '\'')
        if (prev != '\\') {
         quote=FALSE;
         current='\0';
        }
     }
    if (!string && !comment && !quote && current != '\0') {
       if (prev == '(' && current == '*') {  /* comment on */
         comment=TRUE;
         com++;             /* counter for nested comments */
         ITALICS_ON;
         PrintString(request,"*");
       } 
       else
       if (current == '"') {                 /* " string on  */
         string=TRUE;
         if (j>0) {
          checkword(); j=0;
         }
        PrintString(request,"\"");
       } 
       else
       if (current == '\'') {                 /* ' quote on  */
         quote=TRUE;
         if (j>0) {
          checkword(); j=0;
         }
        PrintString(request,"\'");
       } 
       else
       if (strchr("{} []();,:=.",current)) {
         checkword(); j=0;
         PrintString(request,&current);
        }
        else 
        {
         word[j++]=current;
         word[j]='\0';    /* add word terminator */
        }
    }/*  if  */
  prev=current;
 }/*  while */
}
/*-----------------------------------------------
                                       checkword
 ------------------------------------------------*/
checkword()
{
 int i=0, nokey=1;

while ((nokey != 0) && (i<=MAXKEY))
  nokey = strcmp(word,keyw[i++]);

 if (nokey==0){
     BOLD_ON;
      PrintString(request,word);
     BOLD_OFF;
 } 
  else 
   PrintString(request,word); i=0;
  while(i<=MAXWORD) /* delete word (save version) */
   word[i++]='\0';
}
/*-----------------------------------------------
                                     PrintLineNr
 ------------------------------------------------*/
PrLnNr()
{
 char LineStr[7];
 
 ++lines;
 PrintString(request,"\n");
 sprintf(LineStr,"%4d: ",lines);
 if (!comment) ITALICS_ON;
  PrintString(request,LineStr);
 if (!comment) ITALICS_OFF;
}
/*-----------------------------------------------
                                    InitKeyWords
 ------------------------------------------------*/
InitKeyWords()
{         /* reserved words */
keyw[ 0]="AND";            keyw[20]="LOOP"; 
keyw[ 1]="ARRAY";          keyw[21]="MOD";
keyw[ 2]="BEGIN";          keyw[22]="MODULE";
keyw[ 3]="BY";             keyw[23]="NOT";
keyw[ 4]="CASE";           keyw[24]="OF";
keyw[ 5]="CONST";          keyw[25]="OR";
keyw[ 6]="DEFINITION";     keyw[26]="POINTER";
keyw[ 7]="DIV";            keyw[27]="PROCEDURE";
keyw[ 8]="DO";             keyw[28]="QUALIFIED";
keyw[ 9]="ELSE";           keyw[29]="RECORD";
keyw[10]="ELSIF";          keyw[30]="REPEAT";
keyw[11]="END";            keyw[31]="RETURN";
keyw[12]="EXIT";           keyw[32]="SET";
keyw[13]="EXPORT";         keyw[33]="THEN";
keyw[14]="FOR";            keyw[34]="TO";
keyw[15]="FROM";           keyw[35]="TYPE";
keyw[16]="IF";             keyw[36]="UNTIL";
keyw[17]="IMPLEMENTATION"; keyw[37]="VAR";
keyw[18]="IMPORT";         keyw[38]="WHILE";
keyw[19]="IN";             keyw[39]="WITH";
          /*  standardnames  */
keyw[40]="ABS";      keyw[53]="HIGH";
keyw[41]="BITSET";   keyw[54]="INC";
keyw[42]="BOOLEAN";  keyw[55]="INCL";
keyw[43]="CAP";      keyw[56]="INTEGER";
keyw[44]="CARDINAL"; keyw[57]="NEW";
keyw[45]="CHAR";     keyw[58]="NIL";
keyw[46]="CHR";      keyw[59]="ODD";
keyw[47]="DEC";      keyw[60]="ORD";
keyw[48]="DISPOSE";  keyw[61]="PROC";
keyw[49]="EXCL";     keyw[62]="REAL";
keyw[50]="FALSE";    keyw[63]="TRUE";
keyw[51]="FLOAT";    keyw[65]="TRUNC";
keyw[52]="HALT";     keyw[66]="VAL";
}
/*-----------------------------------------------
                                        CloseAll
 ------------------------------------------------*/
CloseAll()
{
 fclose(fp);
 PrintCommand(request,aRIS,0,0,0,0);   /* reset printer */
 ClosePrinter(request);
 DeleteExtIO(request,sizeof(union printerIO));
 DeletePort(printerPort);
}
/*-----------------------------------------------
                                     InitPrinter
 ------------------------------------------------*/
InitPrinter()
{
 printerPort = CreatePort("my.print.port",0);
 request = (union printerIO *)CreateExtIO(printerPort,sizeof(union printerIO));
 if ((Error = OpenPrinter(request)) != NULL) {
  DeleteExtIO(request,sizeof(union printerIO));
  DeletePort(printerPort);
  printf("Can't open prt:\n");
  exit(FALSE);
 }
 PrintString(request,"\x00");      /* send nullbyte for new parameters */
 PrintCommand(request,aDEN1,0,0,0,0);   /* NLQ off  */
 PrintCommand(request,aSHORP2,0,0,0,0); /* Elite on */
}  
/*-----------------------------------------------
                                     OpenPrinter
 ------------------------------------------------*/
int OpenPrinter(request)
union printerIO *request;
{
 return(OpenDevice("printer.device",0,request,0));
}
/*-----------------------------------------------
                                    ClosePrinter
 ------------------------------------------------*/
int ClosePrinter(request)
union printerIO *request;
{
 return(CloseDevice(request));
}
/*-----------------------------------------------
                                     PrintString      
 ------------------------------------------------*/
int PrintString(request,string)
union printerIO *request;
char *string;
{ 
 request -> ios.io_Command = CMD_WRITE;
 request -> ios.io_Data    = (APTR)string;
 request -> ios.io_Length  = -1;
 return(DoIO(request));
}
/*-----------------------------------------------
                                    PrintCommand         
 ------------------------------------------------*/
  int PrintCommand(request,command,p0,p1,p2,p3)
  union printerIO *request;
  int command,p0,p1,p2,p3;
  {
   request -> iopc.io_Command = PRD_PRTCOMMAND;
   request -> iopc.io_PrtCommand = command;
   request -> iopc.io_Parm0 = p0;
   request -> iopc.io_Parm1 = p1;
   request -> iopc.io_Parm2 = p2;
   request -> iopc.io_Parm3 = p3;
   return(DoIO(request));
  }
/*-----------------------------END-of-FILE-------------------------------*/