home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 4 / AACD04.ISO / AACD / Programming / envsof20 / source / scanner / eiffel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-28  |  5.4 KB  |  184 lines

  1. /*
  2.  * eiffel.c -- Eiffel feature scanner for GoldEd Studio 6.
  3.  *
  4.  * Copyright 1999 Thomas Aglassinger and others, see file "forum.txt"
  5.  *
  6.  */
  7.  
  8. #include <exec/types.h>
  9.  
  10. #define VERSION "$VER: eiffel 2.0 (" __COMMODORE_DATE__ ")"
  11.  
  12. /* The actual handler has to be the first prototype, because GoldEd
  13.  * will *always* use the first function as handler. */
  14. ULONG ScanHandlerEiffel(__D0 ULONG len, __A0 char **text, __A1 ULONG * line);
  15.  
  16. static UBYTE *try_skip_word(UBYTE * from, UBYTE * word);
  17. static void seek_non_identifier(UBYTE ** from, UBYTE * last);
  18. static void skip_blanks(UBYTE ** rider, UBYTE * last);
  19. static int is_letter(UBYTE byte);
  20.  
  21. ULONG
  22. ScanHandlerEiffel(__D0 ULONG len, __A0 char **text, __A1 ULONG * line)
  23. {
  24.    if (len > 3) {
  25.       UBYTE *from = *text;
  26.       UBYTE *last;
  27.       /* Find out if this line is a feature declaration */
  28.       if ((from[0] == '\t') && is_letter(from[1])) {
  29.          from += 1;
  30.          len -= 1;
  31.       } else if ((from[0] == ' ') && (from[0] == ' ')
  32.                  && (from[0] == ' ') && is_letter(from[3])) {
  33.          from += 3;
  34.          len -= 3;
  35.       } else {
  36.          len = 0;
  37.       }
  38.  
  39.       if (len > 0) {
  40.          UBYTE *skipper = NULL; /* Seeks for "frozen", "infix" etc */
  41.          BOOL has_feature = FALSE;
  42.  
  43.          /* Skip backwards trailing blanks */
  44.          for (last = from + len - 1; len && (*last <= 32); --len)
  45.             --last;
  46.  
  47.          /* Does line end in " is"? */
  48.          has_feature = (last[0] == 's') && (last[-1] == 'i') && (last[-2] == ' ');
  49.          if (!has_feature) {
  50.             /* Does line have a ":" somewhere? Otherwise, this is just
  51.              * a "creation" routine */
  52.             skipper = from;
  53.             while ((skipper <= last) && (!has_feature)) {
  54.                if (*skipper == ':') {
  55.                   /* Is it an attribute or an indexing line? Check first
  56.                    * non-white space after ":" to not be a quote (") */
  57.                   skipper+=1;
  58.                   skip_blanks(&skipper, last);
  59.                   if (*skipper != '"') {
  60.                      /* Check if there are any commas (,) in the line,
  61.                       * except inside quotes. If there is, it's an indexing
  62.                       * line. */
  63.                      BOOL figured_it = FALSE;
  64.                      while ((skipper <= last) && (!figured_it)) {
  65.                         switch(*skipper)
  66.                         {
  67.                            case '\"':
  68.                            case '\'':
  69.                               /* The only cases we can't discover with this
  70.                                * are indexing lines like:
  71.                                *
  72.                                * indexing
  73.                                *    year: 1999
  74.                                */
  75.                               has_feature = TRUE;
  76.                               figured_it = TRUE;
  77.                               break;
  78.                            case ',':
  79.                               figured_it = TRUE;
  80.                               break;
  81.                            default:
  82.                               skipper += 1;
  83.                               break;
  84.                         }
  85.                      }
  86.                   }
  87.                } else {
  88.                   skipper += 1;
  89.                }
  90.             }
  91.          }
  92.          if (has_feature) {
  93.             /* Skip frozen */
  94.             skipper = try_skip_word(from, "frozen ");
  95.             if (skipper != NULL) {
  96.                from = skipper;
  97.                skipper = NULL;
  98.             }
  99.             /* Check for infix/prefix */
  100.             skipper = try_skip_word(from, "infix ");
  101.             if (skipper == NULL) {
  102.                skipper = try_skip_word(from, "prefix ");
  103.             }
  104.             if (skipper == NULL) {
  105.                /* Handle normal feature */
  106.                skipper = from;
  107.                seek_non_identifier(&skipper, last);
  108.                last = skipper;
  109.             } else {
  110.                /* Handle infix/prefix */
  111.                ULONG skipped_quotes = 0;
  112.  
  113.                skip_blanks(&skipper, last);
  114.  
  115.                while ((skipper <= last) && (skipped_quotes < 2)) {
  116.                   if (*skipper == '"') {
  117.                      skipped_quotes += 1;
  118.                   }
  119.                   skipper += 1;
  120.                }
  121.                last = skipper;
  122.             }
  123.  
  124.             *text = from;
  125.             return ((ULONG) (last - from));
  126.          }
  127.       }
  128.    }
  129.    return (FALSE);
  130. }
  131.  
  132. /* Compare string beginning at `from' with 0-terminated `word'.
  133.  * Return pointer character of `from' after `word', or NULL if
  134.  * `from' does not begin with `word'. */
  135. static UBYTE *
  136. try_skip_word(UBYTE * from, UBYTE * word)
  137. {
  138.    while (*word && (*word == *from)) {
  139.       word += 1;
  140.       from += 1;
  141.    }
  142.  
  143.    if (*word) {
  144.       from = NULL;
  145.    }
  146.    return from;
  147. }
  148.  
  149. /* Seek from current position to first non-identifier character */
  150. static void
  151. seek_non_identifier(UBYTE ** from, UBYTE * last)
  152. {
  153.    UBYTE *rider = *from;
  154.  
  155.    while ((rider <= last)
  156.           && ((*rider == '_')
  157.               || ((*rider >= 'A') && (*rider <= 'Z'))
  158.               || ((*rider >= 'a') && (*rider <= 'z'))
  159.               || ((*rider >= '0') && (*rider <= '9'))
  160.           )) {
  161.       rider += 1;
  162.    }
  163.  
  164.    *from = rider;
  165. }
  166.  
  167. /* Skip blanks */
  168. static void
  169. skip_blanks(UBYTE ** rider, UBYTE * last)
  170. {
  171.    while ((*rider <= last) && (**rider == 32)) {
  172.       *rider = *rider + 1;
  173.    }
  174. }
  175.  
  176. static int
  177. is_letter(UBYTE byte)
  178. {
  179.    return (((byte >= 'a') && (byte <= 'z'))
  180.            || ((byte >= 'A') && (byte <= 'Z')));
  181. }
  182.  
  183. static const char *version = VERSION;
  184.