aboutsummaryrefslogtreecommitdiff
path: root/Src/ns-eel/nseel-yylex.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/ns-eel/nseel-yylex.c')
-rw-r--r--Src/ns-eel/nseel-yylex.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/Src/ns-eel/nseel-yylex.c b/Src/ns-eel/nseel-yylex.c
new file mode 100644
index 00000000..073f449d
--- /dev/null
+++ b/Src/ns-eel/nseel-yylex.c
@@ -0,0 +1,162 @@
+/*
+ Nullsoft Expression Evaluator Library (NS-EEL)
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ nseel-yylex.c
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#include "ns-eel-int.h"
+
+
+#define NBPW 16
+#define EOF (-1)
+
+
+#define ERROR 256 /* yacc's value */
+
+static int llset(compileContext *ctx);
+static int llinp(compileContext *ctx, char **exp);
+static int lexgetc(char **exp)
+{
+ char c= **exp;
+ if (c) (*exp)++;
+ return( c != 0 ? c : -1);
+}
+static int tst__b(register int c, char tab[])
+{
+ return (tab[(c >> 3) & 037] & (1 << (c & 07)) );
+}
+
+int nseel_gettoken(compileContext *ctx, char *lltb, int lltbsiz)
+{
+ register char *lp, *tp, *ep;
+
+ tp = lltb;
+ ep = tp+lltbsiz-1;
+ for (lp = ctx->llbuf; lp < ctx->llend && tp < ep;)
+ *tp++ = *lp++;
+ *tp = 0;
+ return(tp-lltb);
+}
+
+
+int nseel_yylex(compileContext *ctx, char **exp)
+{
+ register int c, st;
+ int final, l, llk, i;
+ register struct lextab *lp;
+ char *cp;
+
+ while (1)
+ {
+ llk = 0;
+ if (llset(ctx)) return(0);
+ st = 0;
+ final = -1;
+ lp = &nseel_lextab;
+
+ do {
+ if (lp->lllook && (l = lp->lllook[st])) {
+ for (c=0; c<NBPW; c++)
+ if (l&(1<<c))
+ ctx->llsave[c] = ctx->llp1;
+ llk++;
+ }
+ if ((i = lp->llfinal[st]) != -1) {
+ final = i;
+ ctx->llend = ctx->llp1;
+ }
+ if ((c = llinp(ctx,exp)) < 0)
+ break;
+ if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) {
+ ctx->llp1--;
+ break;
+ }
+ } while ((st = (*lp->llmove)(lp, c, st)) != -1);
+
+
+ if (ctx->llp2 < ctx->llp1)
+ ctx->llp2 = ctx->llp1;
+ if (final == -1) {
+ ctx->llend = ctx->llp1;
+ if (st == 0 && c < 0)
+ return(0);
+ if ((cp = lp->llill) && tst__b(c, cp)) {
+ continue;
+ }
+ return(ERROR);
+ }
+ if (c = (final >> 11) & 037)
+ ctx->llend = ctx->llsave[c-1];
+ if ((c = (*lp->llactr)(ctx,final&03777)) >= 0)
+ return(c);
+ }
+}
+
+void nseel_llinit(compileContext *ctx)
+{
+ ctx->llp1 = ctx->llp2 = ctx->llend = ctx->llbuf;
+ ctx->llebuf = ctx->llbuf + sizeof(ctx->llbuf);
+ ctx->lleof = ctx->yyline = 0;
+}
+
+
+static int llinp(compileContext *ctx, char **exp)
+{
+ register c;
+ register struct lextab *lp;
+ register char *cp;
+
+ lp = &nseel_lextab;
+ cp = lp->llign; /* Ignore class */
+ for (;;) {
+ /*
+ * Get the next character from the save buffer (if possible)
+ * If the save buffer's empty, then return EOF or the next
+ * input character. Ignore the character if it's in the
+ * ignore class.
+ */
+ c = (ctx->llp1 < ctx->llp2) ? *ctx->llp1 & 0377 : (ctx->lleof) ? EOF : lexgetc(exp);
+ if (c >= 0) { /* Got a character? */
+ if (cp && tst__b(c, cp))
+ continue; /* Ignore it */
+ if (ctx->llp1 >= ctx->llebuf) { /* No, is there room? */
+ return -1;
+ }
+ *ctx->llp1++ = c; /* Store in token buff */
+ } else
+ ctx->lleof = 1; /* Set EOF signal */
+ return(c);
+ }
+}
+
+static int llset(compileContext *ctx)
+/*
+ * Return TRUE if EOF and nothing was moved in the look-ahead buffer
+ */
+{
+ register char *lp1, *lp2;
+
+ for (lp1 = ctx->llbuf, lp2 = ctx->llend; lp2 < ctx->llp2;)
+ *lp1++ = *lp2++;
+ ctx->llend = ctx->llp1 = ctx->llbuf;
+ ctx->llp2 = lp1;
+ return(ctx->lleof && lp1 == ctx->llbuf);
+}