summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/otps/routines.c
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
committerKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
commit487ca4806cc046076293cf6cc5fbba0db282bac7 (patch)
tree847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/web2c/otps/routines.c
parenta3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff)
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/otps/routines.c')
-rw-r--r--Build/source/texk/web2c/otps/routines.c549
1 files changed, 549 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/otps/routines.c b/Build/source/texk/web2c/otps/routines.c
new file mode 100644
index 00000000000..4dcc8b66f9e
--- /dev/null
+++ b/Build/source/texk/web2c/otps/routines.c
@@ -0,0 +1,549 @@
+/* routines.c: Generating the finite state automaton.
+
+This file is part of Omega,
+which is based on the web2c distribution of TeX,
+
+Copyright (c) 1994--2001 John Plaice and Yannis Haralambous
+
+Omega is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+Omega is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Omega; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include <kpathsea/config.h>
+#include <kpathsea/types.h>
+#include <kpathsea/c-proto.h>
+#include <kpathsea/c-std.h>
+#include "routines.h"
+#include "otp.h"
+
+#define out_ptr (states[cur_state].length)
+#define out_array (states[cur_state].instrs)
+
+list left_false_holes;
+
+int left_state;
+int right_offset;
+int input_bytes;
+int output_bytes;
+
+int no_states = 0;
+int cur_state = 0;
+int room_for_states = 0;
+state_type states[100];
+
+int no_tables = 0;
+int cur_table = 0;
+int room_for_tables = 0;
+table_type tables[100];
+
+int no_aliases = 0;
+alias_pair aliases[1000];
+
+list
+cons P2C(int, x, list, L)
+{
+list temp;
+temp = (list) malloc(sizeof(cell));
+temp->val = x;
+temp->ptr = L;
+return temp;
+}
+
+list
+list1 P1C(int, x)
+{
+list temp;
+temp = (list) malloc(sizeof(cell));
+temp->val = x;
+temp->ptr = nil;
+return temp;
+}
+
+list
+list2 P2C(int, x, int, y)
+{
+list temp, temp1;
+temp = (list) malloc(sizeof(cell));
+temp1 = (list) malloc(sizeof(cell));
+temp->val = x;
+temp->ptr = temp1;
+temp1->val = y;
+temp1->ptr = nil;
+return temp;
+}
+
+list
+append P2C(list, K, list, L)
+{
+if (K==nil) return L;
+return cons(K->val, append(K->ptr, L));
+}
+
+list
+append1 P2C(list, L, int, x)
+{
+return (append(L,list1(x)));
+}
+
+llist
+lcons P2C(left, x, llist, L)
+{
+llist temp;
+temp = (llist) malloc(sizeof(lcell));
+temp->val = x;
+temp->ptr = L;
+return temp;
+}
+
+llist
+llist1 P1C(left, x)
+{
+llist temp;
+temp = (llist) malloc(sizeof(lcell));
+temp->val = x;
+temp->ptr = nil;
+return temp;
+}
+
+llist
+llist2 P2C(left, x, left, y)
+{
+llist temp, temp1;
+temp = (llist) malloc(sizeof(lcell));
+temp1 = (llist) malloc(sizeof(lcell));
+temp->val = x;
+temp->ptr = temp1;
+temp1->val = y;
+temp1->ptr = nil;
+return temp;
+}
+
+llist
+lappend P2C(llist, K, llist, L)
+{
+if (K==nil) return L;
+return lcons(K->val, lappend(K->ptr, L));
+}
+
+llist
+lappend1 P2C(llist, L, left, x)
+{
+return (lappend(L,llist1(x)));
+}
+
+left
+WildCard P1H(void)
+{
+left temp;
+temp = (left) malloc(sizeof(lft_cell));
+temp->kind=WILDCARD;
+return temp;
+}
+
+left
+StringLeft P1C(char *, x)
+{
+left temp;
+temp = (left) malloc(sizeof(lft_cell));
+temp->kind=STRINGLEFT;
+temp->valstr=x;
+return temp;
+}
+
+left
+SingleLeft P1C(int, x)
+{
+left temp;
+temp = (left) malloc(sizeof(lft_cell));
+temp->kind=SINGLELEFT;
+temp->val1=x;
+return temp;
+}
+
+left
+DoubleLeft P2C(int, x, int, y)
+{
+left temp;
+temp = (left) malloc(sizeof(lft_cell));
+temp->kind=DOUBLELEFT;
+temp->val1=x;
+temp->val2=y;
+return temp;
+}
+
+left
+ChoiceLeft P1C(llist, L)
+{
+left temp;
+temp = (left) malloc(sizeof(lft_cell));
+temp->kind=CHOICELEFT;
+temp->more_lefts=L;
+return temp;
+}
+
+left
+NotChoiceLeft P1C(llist, L)
+{
+left temp;
+temp = (left) malloc(sizeof(lft_cell));
+temp->kind=NOTCHOICELEFT;
+temp->more_lefts=L;
+return temp;
+}
+
+left
+PlusLeft P2C(left, l, int, n)
+{
+left temp;
+temp = (left) malloc(sizeof(lft_cell));
+temp->kind=PLUSLEFT;
+temp->one_left=l;
+temp->val1=n;
+return temp;
+}
+
+left
+CompleteLeft P3C(left, l, int, n, int, m)
+{
+left temp;
+temp = (left) malloc(sizeof(lft_cell));
+temp->kind=COMPLETELEFT;
+temp->one_left=l;
+temp->val1=n;
+temp->val2=m;
+return temp;
+}
+
+left
+BeginningLeft P1H(void)
+{
+left temp;
+temp = (left) malloc(sizeof(lft_cell));
+temp->kind=BEGINNINGLEFT;
+return temp;
+}
+
+left
+EndLeft P1H(void)
+{
+left temp;
+temp = (left) malloc(sizeof(lft_cell));
+temp->kind=ENDLEFT;
+return temp;
+}
+
+list
+gen_left P1C(left, arg)
+{
+int save_ptr, k;
+list holes, false_holes, true_holes, backup_holes;
+char *runner;
+llist p;
+
+switch(arg->kind) {
+case WILDCARD:
+ return nil;
+case STRINGLEFT:
+ runner=arg->valstr;
+ holes=nil;
+ while (*runner) {
+ out_int(OTP_GOTO_NE, *runner);
+ out_int(0, 0);
+ holes=cons(out_ptr-1,holes);
+ runner++;
+ if (*runner) {
+ out_int(OTP_GOTO_NO_ADVANCE, 0);
+ holes = cons(out_ptr-1, holes);
+ }
+ }
+ return holes;
+case SINGLELEFT:
+ out_int(OTP_GOTO_NE, arg->val1);
+ out_int(0, 0);
+ return list1(out_ptr-1);
+case DOUBLELEFT:
+ out_int(OTP_GOTO_LT, arg->val1);
+ out_int(0, 0);
+ save_ptr = out_ptr;
+ out_int(OTP_GOTO_GT, arg->val2);
+ out_int(0, 0);
+ return list2(save_ptr-1, out_ptr-1);
+case CHOICELEFT:
+ true_holes=nil;
+ false_holes=nil;
+ p=arg->more_lefts;
+ while (p!=nil) {
+ false_holes = gen_left(p->val);
+ if (p->ptr) {
+ out_int(OTP_GOTO, 0);
+ true_holes=cons(out_ptr-1, true_holes);
+ fill_in(false_holes);
+ }
+ p=p->ptr;
+ }
+ fill_in(true_holes);
+ return false_holes;
+case NOTCHOICELEFT:
+ true_holes=nil;
+ p=arg->more_lefts;
+ while (p!=nil) {
+ false_holes = gen_left(p->val);
+ out_int(OTP_GOTO, 0);
+ true_holes=cons(out_ptr-1, true_holes);
+ fill_in(false_holes);
+ p=p->ptr;
+ }
+ return true_holes;
+case PLUSLEFT:
+ false_holes=nil;
+ true_holes=nil;
+ backup_holes=nil;
+ k=1;
+ while (k<arg->val1) {
+ holes = gen_left(arg->one_left);
+ false_holes = append(false_holes, holes);
+ out_int(OTP_GOTO_NO_ADVANCE, 0);
+ false_holes = cons(out_ptr-1, false_holes);
+ k++;
+ }
+ holes=gen_left(arg->one_left);
+ false_holes = append(false_holes, holes);
+ save_ptr = out_ptr;
+ out_int(OTP_GOTO_NO_ADVANCE, 0);
+ true_holes=cons(out_ptr-1, true_holes);
+ backup_holes=gen_left(arg->one_left);
+ out_int(OTP_GOTO, save_ptr);
+ fill_in(backup_holes);
+ out_int(OTP_LEFT_BACKUP, 0);
+ fill_in(true_holes);
+ return false_holes;
+case COMPLETELEFT:
+ false_holes=nil;
+ true_holes=nil;
+ backup_holes=nil;
+ k=1;
+ if (arg->val1 > arg->val2) {
+ return nil;
+ }
+ while (k<=arg->val1) {
+ holes = gen_left(arg->one_left);
+ false_holes = append(false_holes, holes);
+ out_int(OTP_GOTO_NO_ADVANCE, 0);
+ false_holes = cons(out_ptr-1, false_holes);
+ k++;
+ }
+ while (k<arg->val2) {
+ holes = gen_left(arg->one_left);
+ true_holes = append(true_holes, holes);
+ out_int(OTP_GOTO_NO_ADVANCE, 0);
+ backup_holes = cons(out_ptr-1, backup_holes);
+ k++;
+ }
+ holes = gen_left(arg->one_left);
+ true_holes = append(true_holes, holes);
+ out_int(OTP_GOTO, out_ptr+2);
+ fill_in(true_holes);
+ out_int(OTP_LEFT_BACKUP, 0);
+ fill_in(backup_holes);
+ return false_holes;
+case BEGINNINGLEFT:
+ out_int(OTP_GOTO_BEG, 0);
+ true_holes=list1(out_ptr-1);
+ out_int(OTP_GOTO, 0);
+ false_holes=list1(out_ptr-1);
+ fill_in(true_holes);
+ return false_holes;
+case ENDLEFT:
+ out_int(OTP_GOTO_END, 0);
+ true_holes=list1(out_ptr-1);
+ out_int(OTP_GOTO, 0);
+ false_holes=list1(out_ptr-1);
+ fill_in(true_holes);
+ return false_holes;
+default:
+ fprintf(stderr, "Unrecognized left: %d\n", arg->kind);
+ exit(EXIT_FAILURE);
+}
+}
+
+void
+store_alias P2C(string, str, left, l)
+{
+int i;
+for (i=0; i<no_aliases; i++) {
+ if (!strcmp(str,aliases[i].str)) {
+ fprintf(stderr, "alias %s already defined\n", str);
+ exit(1);
+ }
+}
+aliases[i].str=xstrdup(str);
+aliases[i].left_val=l;
+no_aliases++;
+}
+
+left
+lookup_alias P1C(string, str)
+{
+int i;
+for (i=0; i<no_aliases; i++) {
+ if (!strcmp(str,aliases[i].str)) {
+ return aliases[i].left_val;
+ }
+}
+fprintf(stderr, "state %s not defined\n", str);
+exit(EXIT_FAILURE);
+}
+
+void
+out_left P1C(llist, L)
+{
+llist p;
+list holes;
+if ((states[cur_state].no_exprs)==1) {
+ out_int(OTP_LEFT_START, 0);
+} else {
+ out_int(OTP_LEFT_RETURN, 0);
+}
+p=L;
+left_false_holes=nil;
+while (p!=nil) {
+ holes = gen_left(p->val);
+ if ((p->ptr != nil) &&
+ ((p->val)->kind !=BEGINNINGLEFT) &&
+ (((p->ptr)->val)->kind !=ENDLEFT)) {
+ out_int(OTP_GOTO_NO_ADVANCE, 0);
+ left_false_holes = cons(out_ptr-1,left_false_holes);
+ }
+ left_false_holes = append(left_false_holes, holes);
+ p=p->ptr;
+}
+}
+
+void
+fill_in_left P1H(void)
+{
+ out_int(OTP_STOP, 0);
+ fill_in(left_false_holes);
+}
+
+void
+fill_in P1C(list, L)
+{
+list p;
+p=L;
+while (p!=0) {
+ out_array[p->val] = out_array[p->val] + out_ptr;
+ p=p->ptr;
+}
+}
+
+void
+out_right P2C(int, instr, int, val)
+{
+out_int(instr+right_offset, val);
+}
+
+void
+out_int P2C(int, instr, int, val)
+{
+if (val>=(1<<24)) {
+ fprintf(stderr, "Argument (%d) of instruction too big\n", val);
+ exit(EXIT_FAILURE);
+}
+add_to_state((instr<<24)+val);
+}
+
+void
+store_state P1C(string, str)
+{
+int i;
+for (i=0; i<no_states; i++) {
+ if (!strcmp(str,states[i].str)) {
+ fprintf(stderr, "state %s already defined\n", str);
+ exit(EXIT_FAILURE);
+ }
+}
+states[i].str=xstrdup(str);
+states[i].length=0;
+states[i].no_exprs=0;
+cur_state=i;
+no_states++;
+}
+
+int
+lookup_state P1C(string, str)
+{
+int i;
+for (i=0; i<no_states; i++) {
+ if (!strcmp(str,states[i].str)) {
+ return i;
+ }
+}
+fprintf(stderr, "state %s not defined\n", str);
+exit(EXIT_FAILURE);
+}
+
+void
+add_to_state P1C(int, x)
+{
+int len;
+len = states[cur_state].length;
+if (len > ARRAY_SIZE) {
+ char * str = states[cur_state].str;
+ fprintf(stderr, "%s state has too many instructions\n", str);
+ exit(EXIT_FAILURE);
+}
+(states[cur_state].instrs)[len] = x;
+states[cur_state].length = len+1;
+}
+
+void
+store_table P2C(string, str, int, len)
+{
+int i;
+for (i=0; i<no_tables; i++) {
+ if (!strcmp(str,tables[i].str)) {
+ fprintf(stderr, "table %s already defined\n", str);
+ exit(EXIT_FAILURE);
+ }
+}
+tables[i].str=xstrdup(str);
+tables[i].length=0;
+cur_table=i;
+no_tables++;
+}
+
+void
+add_to_table P1C(int, x)
+{
+int len;
+len = tables[cur_table].length;
+(tables[cur_table].table)[len] = x;
+tables[cur_table].length = len+1;
+}
+
+int
+lookup_table P1C(string, str)
+{
+int i;
+for (i=0; i<no_tables; i++) {
+ if (!strcmp(str,tables[i].str)) {
+ return i;
+ }
+}
+fprintf(stderr, "table %s not defined\n", str);
+exit(EXIT_FAILURE);
+}
+