1 /*
2  *	Syntax highlighting DFA interpreter
3  *	Copyright
4  *		(C) 2004 Joseph H. Allen
5  *
6  *	This file is part of JOE (Joe's Own Editor)
7  */
8 
9 /* State */
10 
11 struct high_state {
12 	ptrdiff_t no;			/* State number */
13 	const char *name;		/* Highlight state name */
14 	int color;			/* Color for this state */
15 	struct color_def *colorp;	/* Mapped color definition */
16 
17 	struct Rtree rtree;		/* Character map (character ->struct high_cmd *) */
18 	struct high_cmd *dflt;		/* Default for no match */
19 	struct high_cmd *same_delim;	/* Same delimiter */
20 	struct high_cmd *delim;		/* Matching delimiter */
21 };
22 
23 /* Parameter list */
24 
25 struct high_param {
26 	struct high_param *next;
27 	char *name;
28 };
29 
30 /* Command (transition) */
31 
32 struct high_cmd {
33 	unsigned noeat : 1;		/* Set to give this character to next state */
34 	unsigned start_buffering : 1;	/* Set if we should start buffering */
35 	unsigned stop_buffering : 1;	/* Set if we should stop buffering */
36 	unsigned save_c : 1;		/* Save character */
37 	unsigned save_s : 1;		/* Save string */
38 	unsigned ignore : 1;		/* Set to ignore case */
39 	unsigned start_mark : 1;	/* Set to begin marked area including this char */
40 	unsigned stop_mark : 1;		/* Set to end marked area excluding this char */
41 	unsigned recolor_mark : 1;	/* Set to recolor marked area with new state */
42 	unsigned rtn : 1;		/* Set to return */
43 	unsigned reset : 1;		/* Set to reset the call stack */
44 	ptrdiff_t recolor;		/* No. chars to recolor if <0. */
45 	struct high_state *new_state;	/* The new state */
46 	ZHASH *keywords;		/* Hash table of keywords */
47 	struct high_cmd *delim;		/* Matching delimiter */
48 	struct high_syntax *call;	/* Syntax subroutine to call */
49 };
50 
51 /* Call stack frame */
52 
53 struct high_frame {
54 	struct high_frame *parent;		/* Caller's frame */
55 	struct high_frame *child;		/* First callee's frame */
56 	struct high_frame *sibling;		/* Caller's next callee's frame */
57 	struct high_syntax *syntax;		/* Current syntax subroutine */
58 	struct high_state *return_state;	/* Return state in the caller's subroutine */
59 };
60 
61 /* Loaded form of syntax file or subroutine */
62 
63 struct high_syntax {
64 	struct high_syntax *next;	/* Linked list of loaded syntaxes */
65 	char *name;			/* Name of this syntax */
66 	char *subr;			/* Name of the subroutine (or NULL for whole file) */
67 	struct high_param *params;	/* Parameters defined */
68 	struct high_state **states;	/* The states of this syntax.  states[0] is idle state */
69 	HASH *ht_states;		/* Hash table of states */
70 	ptrdiff_t nstates;		/* No. states */
71 	ptrdiff_t szstates;		/* Malloc size of states array */
72 	struct color_def *color;	/* Linked list of color definitions */
73 	struct high_cmd default_cmd;	/* Default transition for new states */
74 	struct high_frame *stack_base;  /* Root of run-time call tree */
75 };
76 
77 /* Find a syntax.  Load it if necessary. */
78 
79 struct high_syntax *load_syntax(const char *name);
80 
81 /* Parse a lines.  Returns new state. */
82 
83 HIGHLIGHT_STATE parse(struct high_syntax *syntax,P *line,HIGHLIGHT_STATE state,struct charmap *charmap);
84 extern int *attr_buf;
85 
86 #define clear_state(s) (((s)->saved_s = 0), ((s)->state = 0), ((s)->stack = 0))
87 #define invalidate_state(s) (((s)->state = -1), ((s)->saved_s = 0), ((s)->stack = 0))
88 #define move_state(to,from) (*(to)= *(from))
89 #define eq_state(x,y) ((x)->state == (y)->state && (x)->stack == (y)->stack && (x)->saved_s == (y)->saved_s)
90 
91 extern struct high_syntax *syntax_list;
92 
93 void dump_syntax(BW *bw);
94