;/* execute me to compile with SAS/C (note: CPU option has (nearly) no effect here!)
;SC ModPas-PROC_FUNC.c IGNORE 73  DEBUG=SYMBOLFLUSH STRINGMERGE NOSTKCHK LINK
SC ModPas-PROC_FUNC.c IGNORE 73 CPU=68020 OPT OPTTIME STRINGMERGE NOSTKCHK
SLink FROM ModPas-PROC_FUNC.o TO ModPas-PROC_FUNC SC SD STRIPDEBUG NOICONS
Delete ModPas-PROC_FUNC.(o|lnk) QUIET
QUIT
*/
/**************************************************************************

ModPas-PROC_FUNC.c  --  GoldED4-Scanner für Modula und Pascal Prozeduren

AUTOR(EN):        Thies Wellpott
ERSTELLUNG:       22.05.1997
COPYRIGHT:        (c) 1997 Thies Wellpott
BETRIEBSSYSTEM:   AmigaOS
COMPILER:         SAS/C 6.58

BESCHREIBUNG:

Scanner für GoldED Version 4.
Übergabeparameter:
- ULONG len       Länge der aktuellen Textzeile
- STRPTR *text    Zeiger auf aktuelle Textzeile
- ULONG *line     Zeiger auf aktuelle Zeilennummer
Rückgabewerte:
- ULONG return    Länge des gescannten Textes oder 0 für keinen Text
- STRPTR *text    Zeiger auf Text

Sucht PROCEDURE und FUNCTION. Die Groß-/Kleinschreibung der Schlüsselwörter
ist egal. Leerzeichen (SPACE und TAB) davor werden ignoriert.

Als Prozedur-/Funktionsname werden sehr tolerant alle Zeichen bis zu " ",
"(", ")", ":" oder ";" genommen. Die ersten Zeichen der Parameter werden
mitangezeigt. Eine Funktion wird mit "[FCT]" hinter dem Namen
gekennzeichnet.


FEHLER/EINSCHRÄNKUNGEN:

- Kommentare werden nicht berücksichtigt und führen zu Problemen
- die Maximallänge eines gescannten Textes beträgt 60 Zeichen (wird intern
  überprüft und abgefangen)


ENTWICKLUNGSGESCHICHTE:

V1.000   22.05.1997   Thies Wellpott
- erste Version

V1.001   15.04.1998   Thies Wellpott
- allgemeine Scanner-Headerdatei verwendet
- 68020 compiliert

**************************************************************************/

#include "twscanner.h"



ULONG __asm golded_scanner(register __d0 ULONG len, register __a0 STRPTR *text,
      register __a1 ULONG *line)
{
   const char *version = "\0$VER: ModPas-PROC_FUNC 1.1 " __AMIGADATE__;
   // Stringkonstante (in Code-Hunk) als Puffer mißbrauchen
   STRPTR puffer = "123456789012345678901234567890123456789012345678901234567890";
#define PUFFERLAENGE  60
   STRPTR zeichen = *text;

   // führende Leerzeichen ignorieren
   SKIPBLANKS(zeichen, len);

   // mind. "PROCEDURE p(" oder "FUNCTION f("
   if (len >= 11)
   {
      unsigned short laenge;        // braucht kein ULONG zu sein
      enum { TYP_KEIN, TYP_PROCEDURE, TYP_FUNCTION } typ;
      BOOL klammer;

      // einführendes Schlüsselwort erkennen
      typ = TYP_KEIN;
      if (UPPER(*zeichen) == 'P')
      {
         zeichen++;
         if ( STRICMP4(zeichen, 'R', 'O', 'C', 'E') && STRICMP4(zeichen, 'D', 'U', 'R', 'E') )
         {
            typ = TYP_PROCEDURE;
            len -= 9;
         } // if
      }
      else if (UPPER(*zeichen) == 'F')
      {
         zeichen++;
         if ( STRICMP4(zeichen, 'U', 'N', 'C', 'T') && STRICMP3(zeichen, 'I', 'O', 'N') )
         {
            typ = TYP_FUNCTION;
            len -= 8;
         } // if
      } // else if

      if ( (typ == TYP_KEIN) || !ISBLANK(*zeichen) )
         return 0;

      // folgende Leerzeichen überspringen
      zeichen++;
      len--;
      SKIPBLANKS(zeichen, len);

      // restliche Zeile nach Schlüsselwort leer?
      if (len == 0)
         return 0;

#define PARAMETERTEXTLAENGE  8      // max. Zeichenanzahl der Parameter
#define EXTRATEXTLAENGE  (3+6)      // Zusatzzeichen und -info

      // Name mit Anfang der Parameter kopieren
      *text = puffer;
      laenge = 0;
      klammer = FALSE;
      while ( len && (laenge < PUFFERLAENGE - EXTRATEXTLAENGE) &&
            (klammer || ((*zeichen != ';') && (*zeichen != ':'))) )
      {
         *puffer++ = *zeichen++;
         laenge++;
         len--;
         if (zeichen[-1] == ')')    // kopierte schließende Klammer beendet Schleife
         {
            len = 0;
            klammer = FALSE;
         }
         else if ( !klammer && (ISBLANK(*zeichen) || (*zeichen == '(')) )
         {  // jetzt beginnen die Parameter
            SKIPBLANKS(zeichen, len);
            if (*zeichen == '(')
               klammer = TRUE;
            if (len > PARAMETERTEXTLAENGE)
               len = PARAMETERTEXTLAENGE;
         } // else if
      } // while

      if (laenge == 0)
         return 0;

      if (klammer)
      {
         *puffer++ = '.';
         *puffer++ = '.';
         *puffer++ = ')';
         laenge += 3;
      } // if

      // Infotext bei Funktion anhängen
      if (typ == TYP_FUNCTION)
      {
         *puffer++ = ' ';
         *puffer++ = '[';
         *puffer++ = 'F';
         *puffer++ = 'C';
         *puffer++ = 'T';
         *puffer = ']';
         return (ULONG)(laenge + 6);
      } // if
      return (ULONG)laenge;
   } // if (len >= ..)

   return 0;
} // golded_scanner()



/**
#include <string.h>

int main(int argc, char *argv[])
{
   char text[128], *erg, laenge;
   
   strcpy(text, "fuNCTion f(q");
   erg = text;
   laenge = golded_scanner(strlen(text)-1, &erg, 0);
   erg[laenge] = 0;

   strcpy(text, "  PROCEDURE  hall34&/o   ;q");
   erg = text;
   laenge = golded_scanner(strlen(text)-1, &erg, 0);
   erg[laenge] = 0;

   strcpy(text, "FUNctiON f :   B;q");
   erg = text;
   laenge = golded_scanner(strlen(text)-1, &erg, 0);
   erg[laenge] = 0;

   strcpy(text, "  procedure blobeldksaöl(VAR i : INT) : BOOLEAN;  q");
   erg = text;
   laenge = golded_scanner(strlen(text)-1, &erg, 0);
   erg[laenge] = 0;

   return 0;
} // main()
**/
