1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. 24*0Sstevel@tonic-gate * All rights reserved. 25*0Sstevel@tonic-gate * Use is subject to license terms. 26*0Sstevel@tonic-gate */ 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 29*0Sstevel@tonic-gate /* All Rights Reserved */ 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #include "ldefs.c" 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate static void add(int **array, int n); 36*0Sstevel@tonic-gate static void follow(int v); 37*0Sstevel@tonic-gate static void first(int v); 38*0Sstevel@tonic-gate static void nextstate(int s, int c); 39*0Sstevel@tonic-gate static void packtrans(int st, CHR *tch, int *tst, int cnt, int tryit); 40*0Sstevel@tonic-gate static void acompute(int s); 41*0Sstevel@tonic-gate static void rprint(int *a, char *s, int n); 42*0Sstevel@tonic-gate static void shiftr(int *a, int n); 43*0Sstevel@tonic-gate static void upone(int *a, int n); 44*0Sstevel@tonic-gate static void bprint(char *a, char *s, int n); 45*0Sstevel@tonic-gate static int notin(int n); 46*0Sstevel@tonic-gate static int member(int d, CHR *t); 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate #ifdef PP 49*0Sstevel@tonic-gate static void padd(int **array, int n); 50*0Sstevel@tonic-gate #endif 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate void 53*0Sstevel@tonic-gate cfoll(int v) 54*0Sstevel@tonic-gate { 55*0Sstevel@tonic-gate int i, j, k; 56*0Sstevel@tonic-gate CHR *p; 57*0Sstevel@tonic-gate i = name[v]; 58*0Sstevel@tonic-gate if (!ISOPERATOR(i)) 59*0Sstevel@tonic-gate i = 1; 60*0Sstevel@tonic-gate switch (i) { 61*0Sstevel@tonic-gate case 1: case RSTR: case RCCL: case RNCCL: case RNULLS: 62*0Sstevel@tonic-gate for (j = 0; j < tptr; j++) 63*0Sstevel@tonic-gate tmpstat[j] = FALSE; 64*0Sstevel@tonic-gate count = 0; 65*0Sstevel@tonic-gate follow(v); 66*0Sstevel@tonic-gate #ifdef PP 67*0Sstevel@tonic-gate padd(foll, v); /* packing version */ 68*0Sstevel@tonic-gate #else 69*0Sstevel@tonic-gate add(foll, v); /* no packing version */ 70*0Sstevel@tonic-gate #endif 71*0Sstevel@tonic-gate if (i == RSTR) 72*0Sstevel@tonic-gate cfoll(left[v]); 73*0Sstevel@tonic-gate else if (i == RCCL || i == RNCCL) { 74*0Sstevel@tonic-gate for (j = 1; j < ncg; j++) 75*0Sstevel@tonic-gate symbol[j] = (i == RNCCL); 76*0Sstevel@tonic-gate p = (CHR *) left[v]; 77*0Sstevel@tonic-gate while (*p) 78*0Sstevel@tonic-gate symbol[*p++] = (i == RCCL); 79*0Sstevel@tonic-gate p = pcptr; 80*0Sstevel@tonic-gate for (j = 1; j < ncg; j++) 81*0Sstevel@tonic-gate if (symbol[j]) { 82*0Sstevel@tonic-gate for (k = 0; p + k < pcptr; k++) 83*0Sstevel@tonic-gate if (cindex[j] == *(p + k)) 84*0Sstevel@tonic-gate break; 85*0Sstevel@tonic-gate if (p + k >= pcptr) 86*0Sstevel@tonic-gate *pcptr++ = cindex[j]; 87*0Sstevel@tonic-gate } 88*0Sstevel@tonic-gate *pcptr++ = 0; 89*0Sstevel@tonic-gate if (pcptr > pchar + pchlen) 90*0Sstevel@tonic-gate error( 91*0Sstevel@tonic-gate "Too many packed character classes"); 92*0Sstevel@tonic-gate left[v] = (int)p; 93*0Sstevel@tonic-gate name[v] = RCCL; /* RNCCL eliminated */ 94*0Sstevel@tonic-gate #ifdef DEBUG 95*0Sstevel@tonic-gate if (debug && *p) { 96*0Sstevel@tonic-gate (void) printf("ccl %d: %d", v, *p++); 97*0Sstevel@tonic-gate while (*p) 98*0Sstevel@tonic-gate (void) printf(", %d", *p++); 99*0Sstevel@tonic-gate (void) putchar('\n'); 100*0Sstevel@tonic-gate } 101*0Sstevel@tonic-gate #endif 102*0Sstevel@tonic-gate } 103*0Sstevel@tonic-gate break; 104*0Sstevel@tonic-gate case CARAT: 105*0Sstevel@tonic-gate cfoll(left[v]); 106*0Sstevel@tonic-gate break; 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate /* XCU4: add RXSCON */ 109*0Sstevel@tonic-gate case RXSCON: 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate case STAR: case PLUS: case QUEST: case RSCON: 112*0Sstevel@tonic-gate cfoll(left[v]); 113*0Sstevel@tonic-gate break; 114*0Sstevel@tonic-gate case BAR: case RCAT: case DIV: case RNEWE: 115*0Sstevel@tonic-gate cfoll(left[v]); 116*0Sstevel@tonic-gate cfoll(right[v]); 117*0Sstevel@tonic-gate break; 118*0Sstevel@tonic-gate #ifdef DEBUG 119*0Sstevel@tonic-gate case FINAL: 120*0Sstevel@tonic-gate case S1FINAL: 121*0Sstevel@tonic-gate case S2FINAL: 122*0Sstevel@tonic-gate break; 123*0Sstevel@tonic-gate default: 124*0Sstevel@tonic-gate warning("bad switch cfoll %d", v); 125*0Sstevel@tonic-gate #endif 126*0Sstevel@tonic-gate } 127*0Sstevel@tonic-gate } 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate #ifdef DEBUG 130*0Sstevel@tonic-gate void 131*0Sstevel@tonic-gate pfoll(void) 132*0Sstevel@tonic-gate { 133*0Sstevel@tonic-gate int i, k, *p; 134*0Sstevel@tonic-gate int j; 135*0Sstevel@tonic-gate /* print sets of chars which may follow positions */ 136*0Sstevel@tonic-gate (void) printf("pos\tchars\n"); 137*0Sstevel@tonic-gate for (i = 0; i < tptr; i++) 138*0Sstevel@tonic-gate if (p = foll[i]) { 139*0Sstevel@tonic-gate j = *p++; 140*0Sstevel@tonic-gate if (j >= 1) { 141*0Sstevel@tonic-gate (void) printf("%d:\t%d", i, *p++); 142*0Sstevel@tonic-gate for (k = 2; k <= j; k++) 143*0Sstevel@tonic-gate (void) printf(", %d", *p++); 144*0Sstevel@tonic-gate (void) putchar('\n'); 145*0Sstevel@tonic-gate } 146*0Sstevel@tonic-gate } 147*0Sstevel@tonic-gate } 148*0Sstevel@tonic-gate #endif 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate static void 151*0Sstevel@tonic-gate add(int **array, int n) 152*0Sstevel@tonic-gate { 153*0Sstevel@tonic-gate int i, *temp; 154*0Sstevel@tonic-gate CHR *ctemp; 155*0Sstevel@tonic-gate temp = nxtpos; 156*0Sstevel@tonic-gate ctemp = tmpstat; 157*0Sstevel@tonic-gate array[n] = nxtpos; /* note no packing is done in positions */ 158*0Sstevel@tonic-gate *temp++ = count; 159*0Sstevel@tonic-gate for (i = 0; i < tptr; i++) 160*0Sstevel@tonic-gate if (ctemp[i] == TRUE) 161*0Sstevel@tonic-gate *temp++ = i; 162*0Sstevel@tonic-gate nxtpos = temp; 163*0Sstevel@tonic-gate if (nxtpos >= positions+maxpos) 164*0Sstevel@tonic-gate error( 165*0Sstevel@tonic-gate "Too many positions %s", 166*0Sstevel@tonic-gate (maxpos == MAXPOS ? "\nTry using %p num" : "")); 167*0Sstevel@tonic-gate } 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate static void 170*0Sstevel@tonic-gate follow(int v) 171*0Sstevel@tonic-gate { 172*0Sstevel@tonic-gate int p; 173*0Sstevel@tonic-gate if (v >= tptr-1) 174*0Sstevel@tonic-gate return; 175*0Sstevel@tonic-gate p = parent[v]; 176*0Sstevel@tonic-gate if (p == 0) 177*0Sstevel@tonic-gate return; 178*0Sstevel@tonic-gate switch (name[p]) { 179*0Sstevel@tonic-gate /* will not be CHAR RNULLS FINAL S1FINAL S2FINAL RCCL RNCCL */ 180*0Sstevel@tonic-gate case RSTR: 181*0Sstevel@tonic-gate if (tmpstat[p] == FALSE) { 182*0Sstevel@tonic-gate count++; 183*0Sstevel@tonic-gate tmpstat[p] = TRUE; 184*0Sstevel@tonic-gate } 185*0Sstevel@tonic-gate break; 186*0Sstevel@tonic-gate case STAR: case PLUS: 187*0Sstevel@tonic-gate first(v); 188*0Sstevel@tonic-gate follow(p); 189*0Sstevel@tonic-gate break; 190*0Sstevel@tonic-gate case BAR: case QUEST: case RNEWE: 191*0Sstevel@tonic-gate follow(p); 192*0Sstevel@tonic-gate break; 193*0Sstevel@tonic-gate case RCAT: case DIV: 194*0Sstevel@tonic-gate if (v == left[p]) { 195*0Sstevel@tonic-gate if (nullstr[right[p]]) 196*0Sstevel@tonic-gate follow(p); 197*0Sstevel@tonic-gate first(right[p]); 198*0Sstevel@tonic-gate } 199*0Sstevel@tonic-gate else 200*0Sstevel@tonic-gate follow(p); 201*0Sstevel@tonic-gate break; 202*0Sstevel@tonic-gate /* XCU4: add RXSCON */ 203*0Sstevel@tonic-gate case RXSCON: 204*0Sstevel@tonic-gate case RSCON: case CARAT: 205*0Sstevel@tonic-gate follow(p); 206*0Sstevel@tonic-gate break; 207*0Sstevel@tonic-gate #ifdef DEBUG 208*0Sstevel@tonic-gate default: 209*0Sstevel@tonic-gate warning("bad switch follow %d", p); 210*0Sstevel@tonic-gate #endif 211*0Sstevel@tonic-gate } 212*0Sstevel@tonic-gate } 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate /* 215*0Sstevel@tonic-gate * Check if I have a RXSCON in my upper node 216*0Sstevel@tonic-gate */ 217*0Sstevel@tonic-gate static int 218*0Sstevel@tonic-gate check_me(int v) 219*0Sstevel@tonic-gate { 220*0Sstevel@tonic-gate int tmp = parent[v]; 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate while (name[tmp] != RNEWE) { 223*0Sstevel@tonic-gate if (name[tmp] == RXSCON) 224*0Sstevel@tonic-gate return (1); 225*0Sstevel@tonic-gate tmp = parent[tmp]; 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate return (0); 228*0Sstevel@tonic-gate } 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate /* calculate set of positions with v as root which can be active initially */ 231*0Sstevel@tonic-gate static void 232*0Sstevel@tonic-gate first(int v) 233*0Sstevel@tonic-gate { 234*0Sstevel@tonic-gate int i; 235*0Sstevel@tonic-gate CHR *p; 236*0Sstevel@tonic-gate i = name[v]; 237*0Sstevel@tonic-gate if (!ISOPERATOR(i)) 238*0Sstevel@tonic-gate i = 1; 239*0Sstevel@tonic-gate switch (i) { 240*0Sstevel@tonic-gate case 1: case RCCL: case RNCCL: 241*0Sstevel@tonic-gate case RNULLS: case FINAL: 242*0Sstevel@tonic-gate case S1FINAL: case S2FINAL: 243*0Sstevel@tonic-gate /* 244*0Sstevel@tonic-gate * XCU4: if we are working on an exclusive start state and 245*0Sstevel@tonic-gate * the parent of this position is not RXSCON or RSTR this 246*0Sstevel@tonic-gate * is not an active position. 247*0Sstevel@tonic-gate * 248*0Sstevel@tonic-gate * (There is a possibility that RSXCON appreas as the 249*0Sstevel@tonic-gate * (parent)* node. Check it by check_me().) 250*0Sstevel@tonic-gate */ 251*0Sstevel@tonic-gate if ((exclusive[stnum/2]) && 252*0Sstevel@tonic-gate ISOPERATOR(name[parent[v]]) && 253*0Sstevel@tonic-gate (name[parent[v]] != RXSCON) && 254*0Sstevel@tonic-gate (name[parent[v]] != RSTR) && 255*0Sstevel@tonic-gate (check_me(v) == 0)) { 256*0Sstevel@tonic-gate break; 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate if (tmpstat[v] == FALSE) { 259*0Sstevel@tonic-gate count++; 260*0Sstevel@tonic-gate tmpstat[v] = TRUE; 261*0Sstevel@tonic-gate } 262*0Sstevel@tonic-gate break; 263*0Sstevel@tonic-gate case BAR: case RNEWE: 264*0Sstevel@tonic-gate first(left[v]); 265*0Sstevel@tonic-gate first(right[v]); 266*0Sstevel@tonic-gate break; 267*0Sstevel@tonic-gate case CARAT: 268*0Sstevel@tonic-gate if (stnum % 2 == 1) 269*0Sstevel@tonic-gate first(left[v]); 270*0Sstevel@tonic-gate break; 271*0Sstevel@tonic-gate /* XCU4: add RXSCON */ 272*0Sstevel@tonic-gate case RXSCON: 273*0Sstevel@tonic-gate case RSCON: 274*0Sstevel@tonic-gate i = stnum/2 +1; 275*0Sstevel@tonic-gate p = (CHR *) right[v]; 276*0Sstevel@tonic-gate while (*p) 277*0Sstevel@tonic-gate if (*p++ == i) { 278*0Sstevel@tonic-gate first(left[v]); 279*0Sstevel@tonic-gate break; 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate break; 282*0Sstevel@tonic-gate case STAR: case QUEST: 283*0Sstevel@tonic-gate case PLUS: case RSTR: 284*0Sstevel@tonic-gate /* 285*0Sstevel@tonic-gate * XCU4: if we are working on an exclusive start state and 286*0Sstevel@tonic-gate * the parent of this position is not RXSCON or RSTR this 287*0Sstevel@tonic-gate * is not an active position. 288*0Sstevel@tonic-gate * 289*0Sstevel@tonic-gate * (There is a possibility that RSXCON appreas as the 290*0Sstevel@tonic-gate * (parent)* node. Check it by check_me().) 291*0Sstevel@tonic-gate */ 292*0Sstevel@tonic-gate if ((exclusive[stnum/2]) && 293*0Sstevel@tonic-gate ISOPERATOR(name[parent[v]]) && 294*0Sstevel@tonic-gate (name[parent[v]] != RXSCON) && 295*0Sstevel@tonic-gate (name[parent[v]] != RSTR) && 296*0Sstevel@tonic-gate (check_me(v) == 0)) { 297*0Sstevel@tonic-gate break; 298*0Sstevel@tonic-gate } 299*0Sstevel@tonic-gate first(left[v]); 300*0Sstevel@tonic-gate break; 301*0Sstevel@tonic-gate case RCAT: case DIV: 302*0Sstevel@tonic-gate first(left[v]); 303*0Sstevel@tonic-gate if (nullstr[left[v]]) 304*0Sstevel@tonic-gate first(right[v]); 305*0Sstevel@tonic-gate break; 306*0Sstevel@tonic-gate #ifdef DEBUG 307*0Sstevel@tonic-gate default: 308*0Sstevel@tonic-gate warning("bad switch first %d", v); 309*0Sstevel@tonic-gate #endif 310*0Sstevel@tonic-gate } 311*0Sstevel@tonic-gate } 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate void 314*0Sstevel@tonic-gate cgoto(void) 315*0Sstevel@tonic-gate { 316*0Sstevel@tonic-gate int i, j; 317*0Sstevel@tonic-gate static int s; 318*0Sstevel@tonic-gate int npos, curpos, n; 319*0Sstevel@tonic-gate int tryit; 320*0Sstevel@tonic-gate CHR tch[MAXNCG]; 321*0Sstevel@tonic-gate int tst[MAXNCG]; 322*0Sstevel@tonic-gate CHR *q; 323*0Sstevel@tonic-gate /* generate initial state, for each start condition */ 324*0Sstevel@tonic-gate if (ratfor) { 325*0Sstevel@tonic-gate (void) fprintf(fout, "blockdata\n"); 326*0Sstevel@tonic-gate (void) fprintf(fout, "common /Lvstop/ vstop\n"); 327*0Sstevel@tonic-gate (void) fprintf(fout, "define Svstop %d\n", nstates+1); 328*0Sstevel@tonic-gate (void) fprintf(fout, "integer vstop(Svstop)\n"); 329*0Sstevel@tonic-gate } else 330*0Sstevel@tonic-gate (void) fprintf(fout, "int yyvstop[] = {\n0,\n"); 331*0Sstevel@tonic-gate while (stnum < 2 || stnum/2 < sptr) { 332*0Sstevel@tonic-gate for (i = 0; i < tptr; i++) 333*0Sstevel@tonic-gate tmpstat[i] = 0; 334*0Sstevel@tonic-gate count = 0; 335*0Sstevel@tonic-gate if (tptr > 0) 336*0Sstevel@tonic-gate first(tptr-1); 337*0Sstevel@tonic-gate add(state, stnum); 338*0Sstevel@tonic-gate #ifdef DEBUG 339*0Sstevel@tonic-gate if (debug) { 340*0Sstevel@tonic-gate if (stnum > 1) 341*0Sstevel@tonic-gate (void) printf("%ws:\n", sname[stnum/2]); 342*0Sstevel@tonic-gate pstate(stnum); 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate #endif 345*0Sstevel@tonic-gate stnum++; 346*0Sstevel@tonic-gate } 347*0Sstevel@tonic-gate stnum--; 348*0Sstevel@tonic-gate /* even stnum = might not be at line begin */ 349*0Sstevel@tonic-gate /* odd stnum = must be at line begin */ 350*0Sstevel@tonic-gate /* even states can occur anywhere, odd states only at line begin */ 351*0Sstevel@tonic-gate for (s = 0; s <= stnum; s++) { 352*0Sstevel@tonic-gate tryit = FALSE; 353*0Sstevel@tonic-gate cpackflg[s] = FALSE; 354*0Sstevel@tonic-gate sfall[s] = -1; 355*0Sstevel@tonic-gate acompute(s); 356*0Sstevel@tonic-gate for (i = 0; i < ncg; i++) 357*0Sstevel@tonic-gate symbol[i] = 0; 358*0Sstevel@tonic-gate npos = *state[s]; 359*0Sstevel@tonic-gate for (i = 1; i <= npos; i++) { 360*0Sstevel@tonic-gate curpos = *(state[s]+i); 361*0Sstevel@tonic-gate if (!ISOPERATOR(name[curpos])) 362*0Sstevel@tonic-gate symbol[name[curpos]] = TRUE; 363*0Sstevel@tonic-gate else { 364*0Sstevel@tonic-gate switch (name[curpos]) { 365*0Sstevel@tonic-gate case RCCL: 366*0Sstevel@tonic-gate tryit = TRUE; 367*0Sstevel@tonic-gate q = (CHR *)left[curpos]; 368*0Sstevel@tonic-gate while (*q) { 369*0Sstevel@tonic-gate for (j = 1; j < ncg; j++) 370*0Sstevel@tonic-gate if (cindex[j] == *q) 371*0Sstevel@tonic-gate symbol[j] = TRUE; 372*0Sstevel@tonic-gate q++; 373*0Sstevel@tonic-gate } 374*0Sstevel@tonic-gate break; 375*0Sstevel@tonic-gate case RSTR: 376*0Sstevel@tonic-gate symbol[right[curpos]] = TRUE; 377*0Sstevel@tonic-gate break; 378*0Sstevel@tonic-gate #ifdef DEBUG 379*0Sstevel@tonic-gate case RNULLS: 380*0Sstevel@tonic-gate case FINAL: 381*0Sstevel@tonic-gate case S1FINAL: 382*0Sstevel@tonic-gate case S2FINAL: 383*0Sstevel@tonic-gate break; 384*0Sstevel@tonic-gate default: 385*0Sstevel@tonic-gate warning( 386*0Sstevel@tonic-gate "bad switch cgoto %d state %d", 387*0Sstevel@tonic-gate curpos, s); 388*0Sstevel@tonic-gate break; 389*0Sstevel@tonic-gate #endif 390*0Sstevel@tonic-gate } 391*0Sstevel@tonic-gate } 392*0Sstevel@tonic-gate } 393*0Sstevel@tonic-gate #ifdef DEBUG 394*0Sstevel@tonic-gate if (debug) { 395*0Sstevel@tonic-gate printf("State %d transitions on char-group {", s); 396*0Sstevel@tonic-gate charc = 0; 397*0Sstevel@tonic-gate for (i = 1; i < ncg; i++) { 398*0Sstevel@tonic-gate if (symbol[i]) { 399*0Sstevel@tonic-gate printf("%d,", i); 400*0Sstevel@tonic-gate } 401*0Sstevel@tonic-gate if (i == ncg-1) 402*0Sstevel@tonic-gate printf("}\n"); 403*0Sstevel@tonic-gate if (charc > LINESIZE/4) { 404*0Sstevel@tonic-gate charc = 0; 405*0Sstevel@tonic-gate printf("\n\t"); 406*0Sstevel@tonic-gate } 407*0Sstevel@tonic-gate } 408*0Sstevel@tonic-gate } 409*0Sstevel@tonic-gate #endif 410*0Sstevel@tonic-gate /* for each char, calculate next state */ 411*0Sstevel@tonic-gate n = 0; 412*0Sstevel@tonic-gate for (i = 1; i < ncg; i++) { 413*0Sstevel@tonic-gate if (symbol[i]) { 414*0Sstevel@tonic-gate /* executed for each state, transition pair */ 415*0Sstevel@tonic-gate nextstate(s, i); 416*0Sstevel@tonic-gate xstate = notin(stnum); 417*0Sstevel@tonic-gate if (xstate == -2) 418*0Sstevel@tonic-gate warning("bad state %d %o", s, i); 419*0Sstevel@tonic-gate else if (xstate == -1) { 420*0Sstevel@tonic-gate if (stnum+1 >= nstates) { 421*0Sstevel@tonic-gate stnum++; 422*0Sstevel@tonic-gate error("Too many states %s", 423*0Sstevel@tonic-gate (nstates == NSTATES ? 424*0Sstevel@tonic-gate "\nTry using %n num":"")); 425*0Sstevel@tonic-gate } 426*0Sstevel@tonic-gate add(state, ++stnum); 427*0Sstevel@tonic-gate #ifdef DEBUG 428*0Sstevel@tonic-gate if (debug) 429*0Sstevel@tonic-gate pstate(stnum); 430*0Sstevel@tonic-gate #endif 431*0Sstevel@tonic-gate tch[n] = i; 432*0Sstevel@tonic-gate tst[n++] = stnum; 433*0Sstevel@tonic-gate } else { /* xstate >= 0 ==> state exists */ 434*0Sstevel@tonic-gate tch[n] = i; 435*0Sstevel@tonic-gate tst[n++] = xstate; 436*0Sstevel@tonic-gate } 437*0Sstevel@tonic-gate } 438*0Sstevel@tonic-gate } 439*0Sstevel@tonic-gate tch[n] = 0; 440*0Sstevel@tonic-gate tst[n] = -1; 441*0Sstevel@tonic-gate /* pack transitions into permanent array */ 442*0Sstevel@tonic-gate if (n > 0) 443*0Sstevel@tonic-gate packtrans(s, tch, tst, n, tryit); 444*0Sstevel@tonic-gate else 445*0Sstevel@tonic-gate gotof[s] = -1; 446*0Sstevel@tonic-gate } 447*0Sstevel@tonic-gate ratfor ? fprintf(fout, "end\n") : fprintf(fout, "0};\n"); 448*0Sstevel@tonic-gate } 449*0Sstevel@tonic-gate 450*0Sstevel@tonic-gate /* 451*0Sstevel@tonic-gate * Beware -- 70% of total CPU time is spent in this subroutine - 452*0Sstevel@tonic-gate * if you don't believe me - try it yourself ! 453*0Sstevel@tonic-gate */ 454*0Sstevel@tonic-gate static void 455*0Sstevel@tonic-gate nextstate(int s, int c) 456*0Sstevel@tonic-gate { 457*0Sstevel@tonic-gate int j, *newpos; 458*0Sstevel@tonic-gate CHR *temp, *tz; 459*0Sstevel@tonic-gate int *pos, i, *f, num, curpos, number; 460*0Sstevel@tonic-gate /* state to goto from state s on char c */ 461*0Sstevel@tonic-gate num = *state[s]; 462*0Sstevel@tonic-gate temp = tmpstat; 463*0Sstevel@tonic-gate pos = state[s] + 1; 464*0Sstevel@tonic-gate for (i = 0; i < num; i++) { 465*0Sstevel@tonic-gate curpos = *pos++; 466*0Sstevel@tonic-gate j = name[curpos]; 467*0Sstevel@tonic-gate if ((!ISOPERATOR(j)) && j == c || 468*0Sstevel@tonic-gate j == RSTR && c == right[curpos] || 469*0Sstevel@tonic-gate j == RCCL && member(c, (CHR *) left[curpos])) { 470*0Sstevel@tonic-gate f = foll[curpos]; 471*0Sstevel@tonic-gate number = *f; 472*0Sstevel@tonic-gate newpos = f+1; 473*0Sstevel@tonic-gate for (j = 0; j < number; j++) 474*0Sstevel@tonic-gate temp[*newpos++] = 2; 475*0Sstevel@tonic-gate } 476*0Sstevel@tonic-gate } 477*0Sstevel@tonic-gate j = 0; 478*0Sstevel@tonic-gate tz = temp + tptr; 479*0Sstevel@tonic-gate while (temp < tz) { 480*0Sstevel@tonic-gate if (*temp == 2) { 481*0Sstevel@tonic-gate j++; 482*0Sstevel@tonic-gate *temp++ = 1; 483*0Sstevel@tonic-gate } 484*0Sstevel@tonic-gate else 485*0Sstevel@tonic-gate *temp++ = 0; 486*0Sstevel@tonic-gate } 487*0Sstevel@tonic-gate count = j; 488*0Sstevel@tonic-gate } 489*0Sstevel@tonic-gate 490*0Sstevel@tonic-gate static int 491*0Sstevel@tonic-gate notin(int n) 492*0Sstevel@tonic-gate { /* see if tmpstat occurs previously */ 493*0Sstevel@tonic-gate int *j, k; 494*0Sstevel@tonic-gate CHR *temp; 495*0Sstevel@tonic-gate int i; 496*0Sstevel@tonic-gate if (count == 0) 497*0Sstevel@tonic-gate return (-2); 498*0Sstevel@tonic-gate temp = tmpstat; 499*0Sstevel@tonic-gate for (i = n; i >= 0; i--) { /* for each state */ 500*0Sstevel@tonic-gate j = state[i]; 501*0Sstevel@tonic-gate if (count == *j++) { 502*0Sstevel@tonic-gate for (k = 0; k < count; k++) 503*0Sstevel@tonic-gate if (!temp[*j++]) 504*0Sstevel@tonic-gate break; 505*0Sstevel@tonic-gate if (k >= count) 506*0Sstevel@tonic-gate return (i); 507*0Sstevel@tonic-gate } 508*0Sstevel@tonic-gate } 509*0Sstevel@tonic-gate return (-1); 510*0Sstevel@tonic-gate } 511*0Sstevel@tonic-gate 512*0Sstevel@tonic-gate static void 513*0Sstevel@tonic-gate packtrans(int st, CHR *tch, int *tst, int cnt, int tryit) 514*0Sstevel@tonic-gate { 515*0Sstevel@tonic-gate /* 516*0Sstevel@tonic-gate * pack transitions into nchar, nexts 517*0Sstevel@tonic-gate * nchar is terminated by '\0', nexts uses cnt, followed by elements 518*0Sstevel@tonic-gate * gotof[st] = index into nchr, nexts for state st 519*0Sstevel@tonic-gate * sfall[st] = t implies t is fall back state for st 520*0Sstevel@tonic-gate * == -1 implies no fall back 521*0Sstevel@tonic-gate */ 522*0Sstevel@tonic-gate 523*0Sstevel@tonic-gate int cmin, cval, tcnt, diff, p, *ast; 524*0Sstevel@tonic-gate int i, j, k; 525*0Sstevel@tonic-gate CHR *ach; 526*0Sstevel@tonic-gate int go[MAXNCG], temp[MAXNCG], index, c; 527*0Sstevel@tonic-gate int swork[MAXNCG]; 528*0Sstevel@tonic-gate CHR cwork[MAXNCG]; 529*0Sstevel@tonic-gate int upper; 530*0Sstevel@tonic-gate 531*0Sstevel@tonic-gate rcount += (long)cnt; 532*0Sstevel@tonic-gate cmin = -1; 533*0Sstevel@tonic-gate cval = ncg; 534*0Sstevel@tonic-gate ast = tst; 535*0Sstevel@tonic-gate ach = tch; 536*0Sstevel@tonic-gate /* try to pack transitions using ccl's */ 537*0Sstevel@tonic-gate if (!optim) 538*0Sstevel@tonic-gate goto nopack; /* skip all compaction */ 539*0Sstevel@tonic-gate if (tryit) { /* ccl's used */ 540*0Sstevel@tonic-gate for (i = 1; i < ncg; i++) { 541*0Sstevel@tonic-gate go[i] = temp[i] = -1; 542*0Sstevel@tonic-gate symbol[i] = 1; 543*0Sstevel@tonic-gate } 544*0Sstevel@tonic-gate for (i = 0; i < cnt; i++) { 545*0Sstevel@tonic-gate index = (unsigned char) tch[i]; 546*0Sstevel@tonic-gate if ((index >= 0) && (index < NCH)) { 547*0Sstevel@tonic-gate go[index] = tst[i]; 548*0Sstevel@tonic-gate symbol[index] = 0; 549*0Sstevel@tonic-gate } else { 550*0Sstevel@tonic-gate fprintf(stderr, 551*0Sstevel@tonic-gate "lex`sub2`packtran: tch[%d] out of bounds (%d)\n", 552*0Sstevel@tonic-gate i, tch[i]); 553*0Sstevel@tonic-gate } 554*0Sstevel@tonic-gate } 555*0Sstevel@tonic-gate for (i = 0; i < cnt; i++) { 556*0Sstevel@tonic-gate c = match[tch[i]]; 557*0Sstevel@tonic-gate if (go[c] != tst[i] || c == tch[i]) 558*0Sstevel@tonic-gate temp[tch[i]] = tst[i]; 559*0Sstevel@tonic-gate } 560*0Sstevel@tonic-gate /* fill in error entries */ 561*0Sstevel@tonic-gate for (i = 1; i < ncg; i++) 562*0Sstevel@tonic-gate if (symbol[i]) 563*0Sstevel@tonic-gate temp[i] = -2; /* error trans */ 564*0Sstevel@tonic-gate /* count them */ 565*0Sstevel@tonic-gate k = 0; 566*0Sstevel@tonic-gate for (i = 1; i < ncg; i++) 567*0Sstevel@tonic-gate if (temp[i] != -1) 568*0Sstevel@tonic-gate k++; 569*0Sstevel@tonic-gate if (k < cnt) { /* compress by char */ 570*0Sstevel@tonic-gate #ifdef DEBUG 571*0Sstevel@tonic-gate if (debug) 572*0Sstevel@tonic-gate (void) printf( 573*0Sstevel@tonic-gate "use compression %d, %d vs %d\n", st, k, cnt); 574*0Sstevel@tonic-gate #endif 575*0Sstevel@tonic-gate k = 0; 576*0Sstevel@tonic-gate for (i = 1; i < ncg; i++) 577*0Sstevel@tonic-gate if (temp[i] != -1) { 578*0Sstevel@tonic-gate cwork[k] = i; 579*0Sstevel@tonic-gate swork[k++] = 580*0Sstevel@tonic-gate (temp[i] == -2 ? -1 : temp[i]); 581*0Sstevel@tonic-gate } 582*0Sstevel@tonic-gate cwork[k] = 0; 583*0Sstevel@tonic-gate #ifdef PC 584*0Sstevel@tonic-gate ach = cwork; 585*0Sstevel@tonic-gate ast = swork; 586*0Sstevel@tonic-gate cnt = k; 587*0Sstevel@tonic-gate cpackflg[st] = TRUE; 588*0Sstevel@tonic-gate #endif 589*0Sstevel@tonic-gate } 590*0Sstevel@tonic-gate } 591*0Sstevel@tonic-gate /* 592*0Sstevel@tonic-gate * get most similar state 593*0Sstevel@tonic-gate * reject state with more transitions, 594*0Sstevel@tonic-gate * state already represented by a third state, 595*0Sstevel@tonic-gate * and state which is compressed by char if ours is not to be 596*0Sstevel@tonic-gate */ 597*0Sstevel@tonic-gate for (i = 0; i < st; i++) { 598*0Sstevel@tonic-gate if (sfall[i] != -1) 599*0Sstevel@tonic-gate continue; 600*0Sstevel@tonic-gate if (cpackflg[st] == 1) 601*0Sstevel@tonic-gate if (!(cpackflg[i] == 1)) 602*0Sstevel@tonic-gate continue; 603*0Sstevel@tonic-gate p = gotof[i]; 604*0Sstevel@tonic-gate if (p == -1) /* no transitions */ 605*0Sstevel@tonic-gate continue; 606*0Sstevel@tonic-gate tcnt = nexts[p]; 607*0Sstevel@tonic-gate if (tcnt > cnt) 608*0Sstevel@tonic-gate continue; 609*0Sstevel@tonic-gate diff = 0; 610*0Sstevel@tonic-gate k = 0; 611*0Sstevel@tonic-gate j = 0; 612*0Sstevel@tonic-gate upper = p + tcnt; 613*0Sstevel@tonic-gate while (ach[j] && p < upper) { 614*0Sstevel@tonic-gate while (ach[j] < nchar[p] && ach[j]) { 615*0Sstevel@tonic-gate diff++; 616*0Sstevel@tonic-gate j++; 617*0Sstevel@tonic-gate } 618*0Sstevel@tonic-gate if (ach[j] == 0) 619*0Sstevel@tonic-gate break; 620*0Sstevel@tonic-gate if (ach[j] > nchar[p]) { 621*0Sstevel@tonic-gate diff = ncg; 622*0Sstevel@tonic-gate break; 623*0Sstevel@tonic-gate } 624*0Sstevel@tonic-gate /* ach[j] == nchar[p] */ 625*0Sstevel@tonic-gate if (ast[j] != nexts[++p] || 626*0Sstevel@tonic-gate ast[j] == -1 || 627*0Sstevel@tonic-gate (cpackflg[st] && ach[j] != match[ach[j]])) 628*0Sstevel@tonic-gate diff++; 629*0Sstevel@tonic-gate j++; 630*0Sstevel@tonic-gate } 631*0Sstevel@tonic-gate while (ach[j]) { 632*0Sstevel@tonic-gate diff++; 633*0Sstevel@tonic-gate j++; 634*0Sstevel@tonic-gate } 635*0Sstevel@tonic-gate if (p < upper) 636*0Sstevel@tonic-gate diff = ncg; 637*0Sstevel@tonic-gate if (diff < cval && diff < tcnt) { 638*0Sstevel@tonic-gate cval = diff; 639*0Sstevel@tonic-gate cmin = i; 640*0Sstevel@tonic-gate if (cval == 0) 641*0Sstevel@tonic-gate break; 642*0Sstevel@tonic-gate } 643*0Sstevel@tonic-gate } 644*0Sstevel@tonic-gate /* cmin = state "most like" state st */ 645*0Sstevel@tonic-gate #ifdef DEBUG 646*0Sstevel@tonic-gate if (debug) 647*0Sstevel@tonic-gate (void) printf("select st %d for st %d diff %d\n", 648*0Sstevel@tonic-gate cmin, st, cval); 649*0Sstevel@tonic-gate #endif 650*0Sstevel@tonic-gate #ifdef PS 651*0Sstevel@tonic-gate if (cmin != -1) { /* if we can use st cmin */ 652*0Sstevel@tonic-gate gotof[st] = nptr; 653*0Sstevel@tonic-gate k = 0; 654*0Sstevel@tonic-gate sfall[st] = cmin; 655*0Sstevel@tonic-gate p = gotof[cmin] + 1; 656*0Sstevel@tonic-gate j = 0; 657*0Sstevel@tonic-gate while (ach[j]) { 658*0Sstevel@tonic-gate /* if cmin has a transition on c, then so will st */ 659*0Sstevel@tonic-gate /* st may be "larger" than cmin, however */ 660*0Sstevel@tonic-gate while (ach[j] < nchar[p-1] && ach[j]) { 661*0Sstevel@tonic-gate k++; 662*0Sstevel@tonic-gate nchar[nptr] = ach[j]; 663*0Sstevel@tonic-gate nexts[++nptr] = ast[j]; 664*0Sstevel@tonic-gate j++; 665*0Sstevel@tonic-gate } 666*0Sstevel@tonic-gate if (nchar[p-1] == 0) 667*0Sstevel@tonic-gate break; 668*0Sstevel@tonic-gate if (ach[j] > nchar[p-1]) { 669*0Sstevel@tonic-gate warning("bad transition %d %d", st, cmin); 670*0Sstevel@tonic-gate goto nopack; 671*0Sstevel@tonic-gate } 672*0Sstevel@tonic-gate /* ach[j] == nchar[p-1] */ 673*0Sstevel@tonic-gate if (ast[j] != nexts[p] || 674*0Sstevel@tonic-gate ast[j] == -1 || 675*0Sstevel@tonic-gate (cpackflg[st] && ach[j] != match[ach[j]])) { 676*0Sstevel@tonic-gate k++; 677*0Sstevel@tonic-gate nchar[nptr] = ach[j]; 678*0Sstevel@tonic-gate nexts[++nptr] = ast[j]; 679*0Sstevel@tonic-gate } 680*0Sstevel@tonic-gate p++; 681*0Sstevel@tonic-gate j++; 682*0Sstevel@tonic-gate } 683*0Sstevel@tonic-gate while (ach[j]) { 684*0Sstevel@tonic-gate nchar[nptr] = ach[j]; 685*0Sstevel@tonic-gate nexts[++nptr] = ast[j++]; 686*0Sstevel@tonic-gate k++; 687*0Sstevel@tonic-gate } 688*0Sstevel@tonic-gate nexts[gotof[st]] = cnt = k; 689*0Sstevel@tonic-gate nchar[nptr++] = 0; 690*0Sstevel@tonic-gate } else { 691*0Sstevel@tonic-gate #endif 692*0Sstevel@tonic-gate nopack: 693*0Sstevel@tonic-gate /* stick it in */ 694*0Sstevel@tonic-gate gotof[st] = nptr; 695*0Sstevel@tonic-gate nexts[nptr] = cnt; 696*0Sstevel@tonic-gate for (i = 0; i < cnt; i++) { 697*0Sstevel@tonic-gate nchar[nptr] = ach[i]; 698*0Sstevel@tonic-gate nexts[++nptr] = ast[i]; 699*0Sstevel@tonic-gate } 700*0Sstevel@tonic-gate nchar[nptr++] = 0; 701*0Sstevel@tonic-gate #ifdef PS 702*0Sstevel@tonic-gate } 703*0Sstevel@tonic-gate #endif 704*0Sstevel@tonic-gate if (cnt < 1) { 705*0Sstevel@tonic-gate gotof[st] = -1; 706*0Sstevel@tonic-gate nptr--; 707*0Sstevel@tonic-gate } else 708*0Sstevel@tonic-gate if (nptr > ntrans) 709*0Sstevel@tonic-gate error( 710*0Sstevel@tonic-gate "Too many transitions %s", 711*0Sstevel@tonic-gate (ntrans == NTRANS ? "\nTry using %a num" : "")); 712*0Sstevel@tonic-gate } 713*0Sstevel@tonic-gate 714*0Sstevel@tonic-gate #ifdef DEBUG 715*0Sstevel@tonic-gate void 716*0Sstevel@tonic-gate pstate(int s) 717*0Sstevel@tonic-gate { 718*0Sstevel@tonic-gate int *p, i, j; 719*0Sstevel@tonic-gate (void) printf("State %d:\n", s); 720*0Sstevel@tonic-gate p = state[s]; 721*0Sstevel@tonic-gate i = *p++; 722*0Sstevel@tonic-gate if (i == 0) 723*0Sstevel@tonic-gate return; 724*0Sstevel@tonic-gate (void) printf("%4d", *p++); 725*0Sstevel@tonic-gate for (j = 1; j < i; j++) { 726*0Sstevel@tonic-gate (void) printf(", %4d", *p++); 727*0Sstevel@tonic-gate if (j%30 == 0) 728*0Sstevel@tonic-gate (void) putchar('\n'); 729*0Sstevel@tonic-gate } 730*0Sstevel@tonic-gate (void) putchar('\n'); 731*0Sstevel@tonic-gate } 732*0Sstevel@tonic-gate #endif 733*0Sstevel@tonic-gate 734*0Sstevel@tonic-gate static int 735*0Sstevel@tonic-gate member(int d, CHR *t) 736*0Sstevel@tonic-gate { 737*0Sstevel@tonic-gate int c; 738*0Sstevel@tonic-gate CHR *s; 739*0Sstevel@tonic-gate c = d; 740*0Sstevel@tonic-gate s = t; 741*0Sstevel@tonic-gate c = cindex[c]; 742*0Sstevel@tonic-gate while (*s) 743*0Sstevel@tonic-gate if (*s++ == c) 744*0Sstevel@tonic-gate return (1); 745*0Sstevel@tonic-gate return (0); 746*0Sstevel@tonic-gate } 747*0Sstevel@tonic-gate 748*0Sstevel@tonic-gate #ifdef DEBUG 749*0Sstevel@tonic-gate void 750*0Sstevel@tonic-gate stprt(int i) 751*0Sstevel@tonic-gate { 752*0Sstevel@tonic-gate int p, t; 753*0Sstevel@tonic-gate (void) printf("State %d:", i); 754*0Sstevel@tonic-gate /* print actions, if any */ 755*0Sstevel@tonic-gate t = atable[i]; 756*0Sstevel@tonic-gate if (t != -1) 757*0Sstevel@tonic-gate (void) printf(" final"); 758*0Sstevel@tonic-gate (void) putchar('\n'); 759*0Sstevel@tonic-gate if (cpackflg[i] == TRUE) 760*0Sstevel@tonic-gate (void) printf("backup char in use\n"); 761*0Sstevel@tonic-gate if (sfall[i] != -1) 762*0Sstevel@tonic-gate (void) printf("fall back state %d\n", sfall[i]); 763*0Sstevel@tonic-gate p = gotof[i]; 764*0Sstevel@tonic-gate if (p == -1) 765*0Sstevel@tonic-gate return; 766*0Sstevel@tonic-gate (void) printf("(%d transitions)\n", nexts[p]); 767*0Sstevel@tonic-gate while (nchar[p]) { 768*0Sstevel@tonic-gate charc = 0; 769*0Sstevel@tonic-gate if (nexts[p+1] >= 0) 770*0Sstevel@tonic-gate (void) printf("%d\t", nexts[p+1]); 771*0Sstevel@tonic-gate else 772*0Sstevel@tonic-gate (void) printf("err\t"); 773*0Sstevel@tonic-gate allprint(nchar[p++]); 774*0Sstevel@tonic-gate while (nexts[p] == nexts[p+1] && nchar[p]) { 775*0Sstevel@tonic-gate if (charc > LINESIZE) { 776*0Sstevel@tonic-gate charc = 0; 777*0Sstevel@tonic-gate (void) printf("\n\t"); 778*0Sstevel@tonic-gate } 779*0Sstevel@tonic-gate allprint(nchar[p++]); 780*0Sstevel@tonic-gate } 781*0Sstevel@tonic-gate (void) putchar('\n'); 782*0Sstevel@tonic-gate } 783*0Sstevel@tonic-gate (void) putchar('\n'); 784*0Sstevel@tonic-gate } 785*0Sstevel@tonic-gate #endif 786*0Sstevel@tonic-gate 787*0Sstevel@tonic-gate /* compute action list = set of poss. actions */ 788*0Sstevel@tonic-gate static void 789*0Sstevel@tonic-gate acompute(int s) 790*0Sstevel@tonic-gate { 791*0Sstevel@tonic-gate int *p, i, j; 792*0Sstevel@tonic-gate int q, r; 793*0Sstevel@tonic-gate int cnt, m; 794*0Sstevel@tonic-gate int temp[MAXPOSSTATE], k, neg[MAXPOSSTATE], n; 795*0Sstevel@tonic-gate k = 0; 796*0Sstevel@tonic-gate n = 0; 797*0Sstevel@tonic-gate p = state[s]; 798*0Sstevel@tonic-gate cnt = *p++; 799*0Sstevel@tonic-gate if (cnt > MAXPOSSTATE) 800*0Sstevel@tonic-gate error("Too many positions for one state - acompute"); 801*0Sstevel@tonic-gate for (i = 0; i < cnt; i++) { 802*0Sstevel@tonic-gate q = *p; 803*0Sstevel@tonic-gate if (name[q] == FINAL) 804*0Sstevel@tonic-gate temp[k++] = left[q]; 805*0Sstevel@tonic-gate else if (name[q] == S1FINAL) { 806*0Sstevel@tonic-gate temp[k++] = left[q]; 807*0Sstevel@tonic-gate if ((r = left[q]) >= NACTIONS) 808*0Sstevel@tonic-gate error( 809*0Sstevel@tonic-gate "INTERNAL ERROR:left[%d]==%d>=NACTIONS", q, r); 810*0Sstevel@tonic-gate extra[r] = 1; 811*0Sstevel@tonic-gate } else if (name[q] == S2FINAL) 812*0Sstevel@tonic-gate neg[n++] = left[q]; 813*0Sstevel@tonic-gate p++; 814*0Sstevel@tonic-gate } 815*0Sstevel@tonic-gate atable[s] = -1; 816*0Sstevel@tonic-gate if (k < 1 && n < 1) 817*0Sstevel@tonic-gate return; 818*0Sstevel@tonic-gate #ifdef DEBUG 819*0Sstevel@tonic-gate if (debug) 820*0Sstevel@tonic-gate (void) printf("final %d actions:", s); 821*0Sstevel@tonic-gate #endif 822*0Sstevel@tonic-gate /* sort action list */ 823*0Sstevel@tonic-gate for (i = 0; i < k; i++) 824*0Sstevel@tonic-gate for (j = i+1; j < k; j++) 825*0Sstevel@tonic-gate if (temp[j] < temp[i]) { 826*0Sstevel@tonic-gate m = temp[j]; 827*0Sstevel@tonic-gate temp[j] = temp[i]; 828*0Sstevel@tonic-gate temp[i] = m; 829*0Sstevel@tonic-gate } 830*0Sstevel@tonic-gate /* remove dups */ 831*0Sstevel@tonic-gate for (i = 0; i < k-1; i++) 832*0Sstevel@tonic-gate if (temp[i] == temp[i+1]) 833*0Sstevel@tonic-gate temp[i] = 0; 834*0Sstevel@tonic-gate /* copy to permanent quarters */ 835*0Sstevel@tonic-gate atable[s] = aptr; 836*0Sstevel@tonic-gate #ifdef DEBUG 837*0Sstevel@tonic-gate if (!ratfor) 838*0Sstevel@tonic-gate (void) fprintf(fout, "/* actions for state %d */", s); 839*0Sstevel@tonic-gate #endif 840*0Sstevel@tonic-gate (void) putc('\n', fout); 841*0Sstevel@tonic-gate for (i = 0; i < k; i++) 842*0Sstevel@tonic-gate if (temp[i] != 0) { 843*0Sstevel@tonic-gate ratfor ? 844*0Sstevel@tonic-gate fprintf(fout, "data vstop(%d)/%d/\n", aptr, temp[i]) : 845*0Sstevel@tonic-gate fprintf(fout, "%d,\n", temp[i]); 846*0Sstevel@tonic-gate #ifdef DEBUG 847*0Sstevel@tonic-gate if (debug) 848*0Sstevel@tonic-gate (void) printf("%d ", temp[i]); 849*0Sstevel@tonic-gate #endif 850*0Sstevel@tonic-gate aptr++; 851*0Sstevel@tonic-gate } 852*0Sstevel@tonic-gate for (i = 0; i < n; i++) { /* copy fall back actions - all neg */ 853*0Sstevel@tonic-gate ratfor ? 854*0Sstevel@tonic-gate fprintf(fout, "data vstop(%d)/%d/\n", aptr, neg[i]) : 855*0Sstevel@tonic-gate fprintf(fout, "%d,\n", neg[i]); 856*0Sstevel@tonic-gate aptr++; 857*0Sstevel@tonic-gate #ifdef DEBUG 858*0Sstevel@tonic-gate if (debug) 859*0Sstevel@tonic-gate (void) printf("%d ", neg[i]); 860*0Sstevel@tonic-gate #endif 861*0Sstevel@tonic-gate } 862*0Sstevel@tonic-gate #ifdef DEBUG 863*0Sstevel@tonic-gate if (debug) 864*0Sstevel@tonic-gate (void) putchar('\n'); 865*0Sstevel@tonic-gate #endif 866*0Sstevel@tonic-gate ratfor ? fprintf(fout, "data vstop (%d)/0/\n", aptr) : 867*0Sstevel@tonic-gate fprintf(fout, "0, \n"); 868*0Sstevel@tonic-gate aptr++; 869*0Sstevel@tonic-gate } 870*0Sstevel@tonic-gate 871*0Sstevel@tonic-gate #ifdef DEBUG 872*0Sstevel@tonic-gate void 873*0Sstevel@tonic-gate pccl(void) 874*0Sstevel@tonic-gate { 875*0Sstevel@tonic-gate /* print character class sets */ 876*0Sstevel@tonic-gate int i, j; 877*0Sstevel@tonic-gate (void) printf("char class intersection\n"); 878*0Sstevel@tonic-gate for (i = 0; i < ccount; i++) { 879*0Sstevel@tonic-gate charc = 0; 880*0Sstevel@tonic-gate (void) printf("class %d:\n\t", i); 881*0Sstevel@tonic-gate for (j = 1; j < ncg; j++) 882*0Sstevel@tonic-gate if (cindex[j] == i) { 883*0Sstevel@tonic-gate allprint(j); 884*0Sstevel@tonic-gate if (charc > LINESIZE) { 885*0Sstevel@tonic-gate (void) printf("\n\t"); 886*0Sstevel@tonic-gate charc = 0; 887*0Sstevel@tonic-gate } 888*0Sstevel@tonic-gate } 889*0Sstevel@tonic-gate (void) putchar('\n'); 890*0Sstevel@tonic-gate } 891*0Sstevel@tonic-gate charc = 0; 892*0Sstevel@tonic-gate (void) printf("match:\n"); 893*0Sstevel@tonic-gate for (i = 0; i < ncg; i++) { 894*0Sstevel@tonic-gate allprint(match[i]); 895*0Sstevel@tonic-gate if (charc > LINESIZE) { 896*0Sstevel@tonic-gate (void) putchar('\n'); 897*0Sstevel@tonic-gate charc = 0; 898*0Sstevel@tonic-gate } 899*0Sstevel@tonic-gate } 900*0Sstevel@tonic-gate (void) putchar('\n'); 901*0Sstevel@tonic-gate } 902*0Sstevel@tonic-gate #endif 903*0Sstevel@tonic-gate 904*0Sstevel@tonic-gate void 905*0Sstevel@tonic-gate mkmatch(void) 906*0Sstevel@tonic-gate { 907*0Sstevel@tonic-gate int i; 908*0Sstevel@tonic-gate CHR tab[MAXNCG]; 909*0Sstevel@tonic-gate for (i = 0; i < ccount; i++) 910*0Sstevel@tonic-gate tab[i] = 0; 911*0Sstevel@tonic-gate for (i = 1; i < ncg; i++) 912*0Sstevel@tonic-gate if (tab[cindex[i]] == 0) 913*0Sstevel@tonic-gate tab[cindex[i]] = i; 914*0Sstevel@tonic-gate /* tab[i] = principal char for new ccl i */ 915*0Sstevel@tonic-gate for (i = 1; i < ncg; i++) 916*0Sstevel@tonic-gate match[i] = tab[cindex[i]]; 917*0Sstevel@tonic-gate } 918*0Sstevel@tonic-gate 919*0Sstevel@tonic-gate void 920*0Sstevel@tonic-gate layout(void) 921*0Sstevel@tonic-gate { 922*0Sstevel@tonic-gate /* format and output final program's tables */ 923*0Sstevel@tonic-gate int i, j, k; 924*0Sstevel@tonic-gate int top, bot, startup, omin; 925*0Sstevel@tonic-gate startup = 0; 926*0Sstevel@tonic-gate for (i = 0; i < outsize; i++) 927*0Sstevel@tonic-gate verify[i] = advance[i] = 0; 928*0Sstevel@tonic-gate omin = 0; 929*0Sstevel@tonic-gate yytop = 0; 930*0Sstevel@tonic-gate for (i = 0; i <= stnum; i++) { /* for each state */ 931*0Sstevel@tonic-gate j = gotof[i]; 932*0Sstevel@tonic-gate if (j == -1) { 933*0Sstevel@tonic-gate stoff[i] = 0; 934*0Sstevel@tonic-gate continue; 935*0Sstevel@tonic-gate } 936*0Sstevel@tonic-gate bot = j; 937*0Sstevel@tonic-gate while (nchar[j]) 938*0Sstevel@tonic-gate j++; 939*0Sstevel@tonic-gate top = j - 1; 940*0Sstevel@tonic-gate #if DEBUG 941*0Sstevel@tonic-gate if (debug) { 942*0Sstevel@tonic-gate (void) printf("State %d: (layout)\n", i); 943*0Sstevel@tonic-gate for (j = bot; j <= top; j++) { 944*0Sstevel@tonic-gate (void) printf(" %o", nchar[j]); 945*0Sstevel@tonic-gate if (j % 10 == 0) 946*0Sstevel@tonic-gate (void) putchar('\n'); 947*0Sstevel@tonic-gate } 948*0Sstevel@tonic-gate (void) putchar('\n'); 949*0Sstevel@tonic-gate } 950*0Sstevel@tonic-gate #endif 951*0Sstevel@tonic-gate while (verify[omin+ZCH]) 952*0Sstevel@tonic-gate omin++; 953*0Sstevel@tonic-gate startup = omin; 954*0Sstevel@tonic-gate #if DEBUG 955*0Sstevel@tonic-gate if (debug) 956*0Sstevel@tonic-gate (void) printf( 957*0Sstevel@tonic-gate "bot,top %d, %d startup begins %d\n", 958*0Sstevel@tonic-gate bot, top, startup); 959*0Sstevel@tonic-gate #endif 960*0Sstevel@tonic-gate if (chset) { 961*0Sstevel@tonic-gate do { 962*0Sstevel@tonic-gate startup += 1; 963*0Sstevel@tonic-gate if (startup > outsize - ZCH) 964*0Sstevel@tonic-gate error("output table overflow"); 965*0Sstevel@tonic-gate for (j = bot; j <= top; j++) { 966*0Sstevel@tonic-gate k = startup+ctable[nchar[j]]; 967*0Sstevel@tonic-gate if (verify[k]) 968*0Sstevel@tonic-gate break; 969*0Sstevel@tonic-gate } 970*0Sstevel@tonic-gate } while (j <= top); 971*0Sstevel@tonic-gate #if DEBUG 972*0Sstevel@tonic-gate if (debug) 973*0Sstevel@tonic-gate (void) printf(" startup will be %d\n", 974*0Sstevel@tonic-gate startup); 975*0Sstevel@tonic-gate #endif 976*0Sstevel@tonic-gate /* have found place */ 977*0Sstevel@tonic-gate for (j = bot; j <= top; j++) { 978*0Sstevel@tonic-gate k = startup + ctable[nchar[j]]; 979*0Sstevel@tonic-gate if (ctable[nchar[j]] <= 0) 980*0Sstevel@tonic-gate (void) printf( 981*0Sstevel@tonic-gate "j %d nchar %d ctable.nch %d\n", 982*0Sstevel@tonic-gate j, nchar[j], ctable[nchar[k]]); 983*0Sstevel@tonic-gate verify[k] = i + 1; /* state number + 1 */ 984*0Sstevel@tonic-gate advance[k] = nexts[j+1]+1; 985*0Sstevel@tonic-gate if (yytop < k) 986*0Sstevel@tonic-gate yytop = k; 987*0Sstevel@tonic-gate } 988*0Sstevel@tonic-gate } else { 989*0Sstevel@tonic-gate do { 990*0Sstevel@tonic-gate startup += 1; 991*0Sstevel@tonic-gate if (startup > outsize - ZCH) 992*0Sstevel@tonic-gate error("output table overflow"); 993*0Sstevel@tonic-gate for (j = bot; j <= top; j++) { 994*0Sstevel@tonic-gate k = startup + nchar[j]; 995*0Sstevel@tonic-gate if (verify[k]) 996*0Sstevel@tonic-gate break; 997*0Sstevel@tonic-gate } 998*0Sstevel@tonic-gate } while (j <= top); 999*0Sstevel@tonic-gate /* have found place */ 1000*0Sstevel@tonic-gate #if DEBUG 1001*0Sstevel@tonic-gate if (debug) 1002*0Sstevel@tonic-gate (void) printf(" startup going to be %d\n", startup); 1003*0Sstevel@tonic-gate #endif 1004*0Sstevel@tonic-gate for (j = bot; j <= top; j++) { 1005*0Sstevel@tonic-gate k = startup + nchar[j]; 1006*0Sstevel@tonic-gate verify[k] = i+1; /* state number + 1 */ 1007*0Sstevel@tonic-gate advance[k] = nexts[j+1] + 1; 1008*0Sstevel@tonic-gate if (yytop < k) 1009*0Sstevel@tonic-gate yytop = k; 1010*0Sstevel@tonic-gate } 1011*0Sstevel@tonic-gate } 1012*0Sstevel@tonic-gate stoff[i] = startup; 1013*0Sstevel@tonic-gate } 1014*0Sstevel@tonic-gate 1015*0Sstevel@tonic-gate /* stoff[i] = offset into verify, advance for trans for state i */ 1016*0Sstevel@tonic-gate /* put out yywork */ 1017*0Sstevel@tonic-gate if (ratfor) { 1018*0Sstevel@tonic-gate (void) fprintf(fout, "define YYTOPVAL %d\n", yytop); 1019*0Sstevel@tonic-gate rprint(verify, "verif", yytop+1); 1020*0Sstevel@tonic-gate rprint(advance, "advan", yytop+1); 1021*0Sstevel@tonic-gate shiftr(stoff, stnum); 1022*0Sstevel@tonic-gate rprint(stoff, "stoff", stnum+1); 1023*0Sstevel@tonic-gate shiftr(sfall, stnum); 1024*0Sstevel@tonic-gate upone(sfall, stnum+1); 1025*0Sstevel@tonic-gate rprint(sfall, "fall", stnum+1); 1026*0Sstevel@tonic-gate bprint(extra, "extra", casecount+1); 1027*0Sstevel@tonic-gate bprint((char *)match, "match", ncg); 1028*0Sstevel@tonic-gate shiftr(atable, stnum); 1029*0Sstevel@tonic-gate rprint(atable, "atable", stnum+1); 1030*0Sstevel@tonic-gate } 1031*0Sstevel@tonic-gate (void) fprintf(fout, 1032*0Sstevel@tonic-gate "# define YYTYPE %s\n", stnum+1 >= NCH ? "int" : "unsigned char"); 1033*0Sstevel@tonic-gate (void) fprintf(fout, 1034*0Sstevel@tonic-gate "struct yywork { YYTYPE verify, advance; } yycrank[] = {\n"); 1035*0Sstevel@tonic-gate for (i = 0; i <= yytop; i += 4) { 1036*0Sstevel@tonic-gate for (j = 0; j < 4; j++) { 1037*0Sstevel@tonic-gate k = i+j; 1038*0Sstevel@tonic-gate if (verify[k]) 1039*0Sstevel@tonic-gate (void) fprintf(fout, 1040*0Sstevel@tonic-gate "%d,%d,\t", verify[k], advance[k]); 1041*0Sstevel@tonic-gate else 1042*0Sstevel@tonic-gate (void) fprintf(fout, "0,0,\t"); 1043*0Sstevel@tonic-gate } 1044*0Sstevel@tonic-gate (void) putc('\n', fout); 1045*0Sstevel@tonic-gate } 1046*0Sstevel@tonic-gate (void) fprintf(fout, "0,0};\n"); 1047*0Sstevel@tonic-gate 1048*0Sstevel@tonic-gate /* put out yysvec */ 1049*0Sstevel@tonic-gate 1050*0Sstevel@tonic-gate (void) fprintf(fout, "struct yysvf yysvec[] = {\n"); 1051*0Sstevel@tonic-gate (void) fprintf(fout, "0,\t0,\t0,\n"); 1052*0Sstevel@tonic-gate for (i = 0; i <= stnum; i++) { /* for each state */ 1053*0Sstevel@tonic-gate if (cpackflg[i]) 1054*0Sstevel@tonic-gate stoff[i] = -stoff[i]; 1055*0Sstevel@tonic-gate (void) fprintf(fout, "yycrank+%d,\t", stoff[i]); 1056*0Sstevel@tonic-gate if (sfall[i] != -1) 1057*0Sstevel@tonic-gate (void) fprintf(fout, 1058*0Sstevel@tonic-gate "yysvec+%d,\t", sfall[i]+1); /* state + 1 */ 1059*0Sstevel@tonic-gate else 1060*0Sstevel@tonic-gate (void) fprintf(fout, "0,\t\t"); 1061*0Sstevel@tonic-gate if (atable[i] != -1) 1062*0Sstevel@tonic-gate (void) fprintf(fout, "yyvstop+%d,", atable[i]); 1063*0Sstevel@tonic-gate else 1064*0Sstevel@tonic-gate (void) fprintf(fout, "0,\t"); 1065*0Sstevel@tonic-gate #ifdef DEBUG 1066*0Sstevel@tonic-gate (void) fprintf(fout, "\t\t/* state %d */", i); 1067*0Sstevel@tonic-gate #endif 1068*0Sstevel@tonic-gate (void) putc('\n', fout); 1069*0Sstevel@tonic-gate } 1070*0Sstevel@tonic-gate (void) fprintf(fout, "0,\t0,\t0};\n"); 1071*0Sstevel@tonic-gate 1072*0Sstevel@tonic-gate /* put out yymatch */ 1073*0Sstevel@tonic-gate 1074*0Sstevel@tonic-gate (void) fprintf(fout, "struct yywork *yytop = yycrank+%d;\n", yytop); 1075*0Sstevel@tonic-gate (void) fprintf(fout, "struct yysvf *yybgin = yysvec+1;\n"); 1076*0Sstevel@tonic-gate if (optim) { 1077*0Sstevel@tonic-gate if (handleeuc) { 1078*0Sstevel@tonic-gate (void) fprintf(fout, "int yymatch[] = {\n"); 1079*0Sstevel@tonic-gate } else { 1080*0Sstevel@tonic-gate (void) fprintf(fout, "char yymatch[] = {\n"); 1081*0Sstevel@tonic-gate } 1082*0Sstevel@tonic-gate if (chset == 0) { /* no chset, put out in normal order */ 1083*0Sstevel@tonic-gate for (i = 0; i < ncg; i += 8) { 1084*0Sstevel@tonic-gate for (j = 0; j < 8; j++) { 1085*0Sstevel@tonic-gate int fbch; 1086*0Sstevel@tonic-gate fbch = match[i+j]; 1087*0Sstevel@tonic-gate fprintf(fout, "%3d, ", fbch); 1088*0Sstevel@tonic-gate } 1089*0Sstevel@tonic-gate (void) putc('\n', fout); 1090*0Sstevel@tonic-gate } 1091*0Sstevel@tonic-gate } else { 1092*0Sstevel@tonic-gate int *fbarr; 1093*0Sstevel@tonic-gate fbarr = (int *)myalloc(2*MAXNCG, sizeof (*fbarr)); 1094*0Sstevel@tonic-gate if (fbarr == 0) 1095*0Sstevel@tonic-gate error("No space for char table reverse", 0); 1096*0Sstevel@tonic-gate for (i = 0; i < MAXNCG; i++) 1097*0Sstevel@tonic-gate fbarr[i] = 0; 1098*0Sstevel@tonic-gate for (i = 0; i < ncg; i++) 1099*0Sstevel@tonic-gate fbarr[ctable[i]] = ctable[match[i]]; 1100*0Sstevel@tonic-gate for (i = 0; i < ncg; i += 8) { 1101*0Sstevel@tonic-gate for (j = 0; j < 8; j++) 1102*0Sstevel@tonic-gate fprintf(fout, "0%-3o,", fbarr[i+j]); 1103*0Sstevel@tonic-gate putc('\n', fout); 1104*0Sstevel@tonic-gate } 1105*0Sstevel@tonic-gate free(fbarr); 1106*0Sstevel@tonic-gate } 1107*0Sstevel@tonic-gate (void) fprintf(fout, "0};\n"); 1108*0Sstevel@tonic-gate } 1109*0Sstevel@tonic-gate /* put out yyextra */ 1110*0Sstevel@tonic-gate (void) fprintf(fout, "char yyextra[] = {\n"); 1111*0Sstevel@tonic-gate for (i = 0; i < casecount; i += 8) { 1112*0Sstevel@tonic-gate for (j = 0; j < 8; j++) 1113*0Sstevel@tonic-gate (void) fprintf(fout, "%d,", i+j < NACTIONS ? 1114*0Sstevel@tonic-gate extra[i+j] : 0); 1115*0Sstevel@tonic-gate (void) putc('\n', fout); 1116*0Sstevel@tonic-gate } 1117*0Sstevel@tonic-gate (void) fprintf(fout, "0};\n"); 1118*0Sstevel@tonic-gate if (handleeuc) { 1119*0Sstevel@tonic-gate /* Put out yycgidtbl */ 1120*0Sstevel@tonic-gate fprintf(fout, "#define YYNCGIDTBL %d\n", ncgidtbl); 1121*0Sstevel@tonic-gate fprintf(fout, "\tunsigned long yycgidtbl[]={"); 1122*0Sstevel@tonic-gate /* 1123*0Sstevel@tonic-gate * Use "unsigned long" instead of "lchar" to minimize 1124*0Sstevel@tonic-gate * the name-space polution for the application program. 1125*0Sstevel@tonic-gate */ 1126*0Sstevel@tonic-gate for (i = 0; i < ncgidtbl; ++i) { 1127*0Sstevel@tonic-gate if (i%8 == 0) 1128*0Sstevel@tonic-gate fprintf(fout, "\n\t\t"); 1129*0Sstevel@tonic-gate fprintf(fout, "0x%08x, ", yycgidtbl[i]); 1130*0Sstevel@tonic-gate } 1131*0Sstevel@tonic-gate fprintf(fout, "\n\t0};\n"); 1132*0Sstevel@tonic-gate } 1133*0Sstevel@tonic-gate } 1134*0Sstevel@tonic-gate 1135*0Sstevel@tonic-gate static void 1136*0Sstevel@tonic-gate rprint(int *a, char *s, int n) 1137*0Sstevel@tonic-gate { 1138*0Sstevel@tonic-gate int i; 1139*0Sstevel@tonic-gate (void) fprintf(fout, "block data\n"); 1140*0Sstevel@tonic-gate (void) fprintf(fout, "common /L%s/ %s\n", s, s); 1141*0Sstevel@tonic-gate (void) fprintf(fout, "define S%s %d\n", s, n); 1142*0Sstevel@tonic-gate (void) fprintf(fout, "integer %s (S%s)\n", s, s); 1143*0Sstevel@tonic-gate for (i = 1; i <= n; i++) { 1144*0Sstevel@tonic-gate if (i%8 == 1) 1145*0Sstevel@tonic-gate (void) fprintf(fout, "data "); 1146*0Sstevel@tonic-gate (void) fprintf(fout, "%s (%d)/%d/", s, i, a[i]); 1147*0Sstevel@tonic-gate (void) fprintf(fout, (i%8 && i < n) ? ", " : "\n"); 1148*0Sstevel@tonic-gate } 1149*0Sstevel@tonic-gate (void) fprintf(fout, "end\n"); 1150*0Sstevel@tonic-gate } 1151*0Sstevel@tonic-gate 1152*0Sstevel@tonic-gate static void 1153*0Sstevel@tonic-gate shiftr(int *a, int n) 1154*0Sstevel@tonic-gate { 1155*0Sstevel@tonic-gate int i; 1156*0Sstevel@tonic-gate for (i = n; i >= 0; i--) 1157*0Sstevel@tonic-gate a[i+1] = a[i]; 1158*0Sstevel@tonic-gate } 1159*0Sstevel@tonic-gate 1160*0Sstevel@tonic-gate static void 1161*0Sstevel@tonic-gate upone(int *a, int n) 1162*0Sstevel@tonic-gate { 1163*0Sstevel@tonic-gate int i; 1164*0Sstevel@tonic-gate for (i = 0; i <= n; i++) 1165*0Sstevel@tonic-gate a[i]++; 1166*0Sstevel@tonic-gate } 1167*0Sstevel@tonic-gate 1168*0Sstevel@tonic-gate static void 1169*0Sstevel@tonic-gate bprint(char *a, char *s, int n) 1170*0Sstevel@tonic-gate { 1171*0Sstevel@tonic-gate int i, j, k; 1172*0Sstevel@tonic-gate (void) fprintf(fout, "block data\n"); 1173*0Sstevel@tonic-gate (void) fprintf(fout, "common /L%s/ %s\n", s, s); 1174*0Sstevel@tonic-gate (void) fprintf(fout, "define S%s %d\n", s, n); 1175*0Sstevel@tonic-gate (void) fprintf(fout, "integer %s (S%s)\n", s, s); 1176*0Sstevel@tonic-gate for (i = 1; i < n; i += 8) { 1177*0Sstevel@tonic-gate (void) fprintf(fout, "data %s (%d)/%d/", s, i, a[i]); 1178*0Sstevel@tonic-gate for (j = 1; j < 8; j++) { 1179*0Sstevel@tonic-gate k = i+j; 1180*0Sstevel@tonic-gate if (k < n) 1181*0Sstevel@tonic-gate (void) fprintf(fout, 1182*0Sstevel@tonic-gate ", %s (%d)/%d/", s, k, a[k]); 1183*0Sstevel@tonic-gate } 1184*0Sstevel@tonic-gate (void) putc('\n', fout); 1185*0Sstevel@tonic-gate } 1186*0Sstevel@tonic-gate (void) fprintf(fout, "end\n"); 1187*0Sstevel@tonic-gate } 1188*0Sstevel@tonic-gate 1189*0Sstevel@tonic-gate #ifdef PP 1190*0Sstevel@tonic-gate static void 1191*0Sstevel@tonic-gate padd(int **array, int n) 1192*0Sstevel@tonic-gate { 1193*0Sstevel@tonic-gate int i, *j, k; 1194*0Sstevel@tonic-gate array[n] = nxtpos; 1195*0Sstevel@tonic-gate if (count == 0) { 1196*0Sstevel@tonic-gate *nxtpos++ = 0; 1197*0Sstevel@tonic-gate return; 1198*0Sstevel@tonic-gate } 1199*0Sstevel@tonic-gate for (i = tptr-1; i >= 0; i--) { 1200*0Sstevel@tonic-gate j = array[i]; 1201*0Sstevel@tonic-gate if (j && *j++ == count) { 1202*0Sstevel@tonic-gate for (k = 0; k < count; k++) 1203*0Sstevel@tonic-gate if (!tmpstat[*j++]) 1204*0Sstevel@tonic-gate break; 1205*0Sstevel@tonic-gate if (k >= count) { 1206*0Sstevel@tonic-gate array[n] = array[i]; 1207*0Sstevel@tonic-gate return; 1208*0Sstevel@tonic-gate } 1209*0Sstevel@tonic-gate } 1210*0Sstevel@tonic-gate } 1211*0Sstevel@tonic-gate add(array, n); 1212*0Sstevel@tonic-gate } 1213*0Sstevel@tonic-gate #endif 1214