%s QUOTED %{ /* * $Header: /usr/build/vile/vile/filters/RCS/rcs-filt.l,v 1.8 2003/05/20 20:38:41 tom Exp $ * * Filter to add vile "attribution" sequences to RCS archives. */ #include DefineFilter("rcs"); static char *Ident2_attr; static char *Number_attr; static char *String_attr; static void add_to_quoted(char *text, int length); static void flush_quoted(void); %} NUMBER [0-9]+(\.[0-9]+)* NAME [a-zA-Z0-9]+ %% [\n] { ECHO; } {NAME} { WriteToken(keyword_attr(yytext)); } {NUMBER} { WriteToken(Number_attr); } "@" { add_to_quoted(yytext, yyleng); BEGIN(QUOTED); } [^@\n]* { add_to_quoted(yytext, yyleng); } @ { add_to_quoted(yytext, yyleng); flush_quoted(); BEGIN(INITIAL); } [\n] { flush_quoted(); ECHO; } %% /* * Returns true if the parameter points to an identifier */ static int is_ident(char *src) { char *base = src; while (isalnum(CharOf(*src))) src++; return (src != base && (*src == ':' || *src == '$')) ; } /* * Find an embedded RCS keyword */ static char * find_ident(char *first) { char *dollar = strchr(first, '$'); if (dollar != 0 && is_ident(dollar+1) && strchr(dollar+1, '$')) { return dollar; } return 0; } /* * Buffer text for quoted-strings, so we can highlight the embedded RCS * keywords. */ static char *save_bfr; static unsigned save_max; static unsigned save_len; static void add_to_quoted(char *text, int length) { save_bfr = do_alloc(save_bfr, save_len + length + 1, &save_max); strncpy(save_bfr + save_len, text, length + 1); save_len += length; } static void flush_quoted(void) { if (save_len) { char *base = save_bfr; char *last = save_bfr + save_len; while (base < last) { char *ident = find_ident(base); if (ident != 0) { char *next = strchr(ident+1, '$'); if (ident != base) flt_puts(base, ident - base, String_attr); base = next + 1; flt_puts(ident, base - ident, Ident2_attr); } else { flt_puts(base, last - base, String_attr); break; } } save_len = 0; } } static void init_filter(int before GCC_UNUSED) { } static void do_filter(FILE *inputs) { yyin = inputs; Ident2_attr = class_attr(NAME_IDENT2); Number_attr = class_attr(NAME_NUMBER); String_attr = class_attr(NAME_LITERAL); BEGIN(INITIAL); while (yylex() > 0) { } flush_quoted(); }