;/* execute me to compile with SAS/C; uses my global SCOPTS
;SC C-function.c IGNORE 73 CPU=68020 DEBUG=SF STRINGMERGE NOSTKCHK LINK
SC C-function.c IGNORE 73 CPU=68020 OPT OPTTIME STRINGMERGE NOSTKCHK
SLink FROM C-function.o TO C-function SC SD STRIPDEBUG NOICONS
Delete C-function.(o|lnk) QUIET
Quit
*/
/**************************************************************************

C-function.c  --  GoldED4-Scanner für C (nicht C++) Funktionen

AUTOR(EN):        Thies Wellpott
ERSTELLUNG:       23.03.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 C-Funktionsdefinitionen. Eine Zeile, die in der ersten Spalte ein
C-Symbolzeichen (A-Z, a-z, 0-9, _) hat und mit ")", "(" oder "," endet,
wird untersucht; im den letzten beiden Fällen (endet auf "(" oder ",") muß
die Zeile relativ lang sein (hier mind. 40 Zeichen).
Als Funktionsname wird die C-Symbolzeichenfolge vor der hintersten
öffnenden Klammer genommen; Klammerstrukturen innerhalb der Argumente
werden aber berücksichtigt, d. h. "void func(bla(ghj), blub," wird richtig
ausgewertet.
Die ersten paar Zeichen der Argumente werden mit angezeigt und bei Bedarf
mit "..)" abgekürzt.


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)
- Leerzeichen zwischen Funktionsname und "(" nicht berücksichtigt
- ein geklammerter Funktionsname wird nicht erkannt


ENTWICKLUNGSGESCHICHTE:

V1.000   23.03.1997   Thies Wellpott
- erste Version

V1.001   22.05.1997   Thies Wellpott
- leichte interne Änderungen
- Dokumentation geschrieben

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

V1.003   18.04.1998   Thies Wellpott
- "(" am Ende ist auch gültig

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

#include "twscanner.h"



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

   // mind. "f(t v)" oder "f(t v," und C-Symbolzeichen in erster Spalte
   if ( (len >= 6) && ISCSYM(**text) )
   {
      STRPTR zeichen = *text, ende, puffer2;
      unsigned short i, len2, len3, laenge;        // braucht kein ULONG zu sein
      short klammer;

      // Leerzeichen am Ende entfernen
      ende = &zeichen[len - 1];
      while ( len && ISBLANK(*ende) )
      {
         ende--;
         len--;
      } // while

      // Zeile muß auf ")", "(" oder "," enden und in den beiden letzten Fällen "lang" sein
      if ( (*ende == ')') || ((*ende == '(') && (len >= 20))  || ((*ende == ',') && (len >= 40)) )
      {
         if (*ende != '(')
         {
            ende--;
            len2 = 1;         // zählt Textlänge ab öffnender Klammer nach Funktionsname
         } else
            len2 = 0;

         // von hinten öffnende Klammer hinter dem Funktionsnamen suchen
         klammer = 0;
         while ( len && (klammer >= 0) )
         {
            if (*ende == ')')
               klammer++;
            else if (*ende == '(')
               klammer--;     // wird negativ, wenn gewünschte Klammer gefunden
            ende--;
            len--;
            len2++;
         } // while
      
         // restliche Zeile leer oder kein C-Symbolzeichen vor Klammer darf nicht
         if ( (len == 0) || !ISCSYM(*ende) )
            return 0;

#define EXTRATEXTLAENGE  12      // Parameter
      
         // Funktionsname rückwärts in Puffer kopieren
         puffer += PUFFERLAENGE - EXTRATEXTLAENGE;
         puffer2 = puffer;
         zeichen = ende + 1;
         laenge = 0;
         while ( len && (laenge < PUFFERLAENGE - EXTRATEXTLAENGE) && ISCSYM(*ende) )
         {
            *--puffer = *ende--;
            len--;
            laenge++;
         } // while
         *text = puffer;
      
         // Argumenttext kopieren
         if (len2 > EXTRATEXTLAENGE)
         {
            // Argumenttext zu lang, nur Anfang und "..)" anzeigen
            len3 = EXTRATEXTLAENGE - 3;
            laenge += EXTRATEXTLAENGE;
         } else
         {
            // Argumenttext ist kurz, ihn vollständig übernehmen
            len3 = len2;
            laenge += len2;
         } // else
         // Argumenttext kopieren (hinter Funktionsnamen)
         for (i = 0;  i < len3;  i++)   
            *puffer2++ = *zeichen++;
      
         // "..)" anhängen, falls Argumente abgekürzt wurden oder keine
         // Arguemnte gefunden (z. B. Zeile endete auf "(")
         if ( (len2 > EXTRATEXTLAENGE) || (len2 < 3) )
         {
            *puffer2++ = '.';
            *puffer2++ = '.';
            *puffer2 = ')';
            if (len2 < 3)
               laenge += 3;
         } // if
      
         return laenge;
      } // if ( *ende == ')' ... )
   } // if ( len >= ...)

   return 0;
} // golded_scanner()



/**
#include <string.h>

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

   strcpy(text, "struct hallo abkjhsadfhsadhflkajshdflkjashdflkjskhj = {12, q");
   erg = text;
   laenge = golded_scanner(strlen(text)-1, &erg, 0);
   erg[laenge] = 0;

   strcpy(text, "void funktion(short super)q");
   erg = text;
   laenge = golded_scanner(strlen(text)-1, &erg, 0);
   erg[laenge] = 0;

   strcpy(text, "int __asm *fkt2(int *dfg, int (*cmp)(int a, int b),  ");
   erg = text;
   laenge = golded_scanner(strlen(text)-1, &erg, 0);
   erg[laenge] = 0;

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

