4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
45 * macro and string routines, storage allocation
55 #define MHASH(x) ((x>>6)^x)&0177
56 struct contab
*mhash
[128]; /* 128 == the 0177 on line above */
57 #define blisti(i) (((i)-ENV_BLK*BLK) / BLK)
65 tchar corebuf
[(ENV_BLK
+ NBLIST
+ 1) * BLK
];
94 if ((i
= getrq()) == 0 || (oldmn
= findmn(i
)) < 0)
97 clrmn(findmn(j
= getrq()));
99 munhash(&contab
[oldmn
]);
100 contab
[oldmn
].rq
= j
;
101 maddhash(&contab
[oldmn
]);
115 hp
= &mhash
[MHASH(rp
->rq
)];
131 lp
= &mhash
[MHASH(mp
->rq
)];
152 for (i
=0; i
<128; i
++)
154 for (p
=contab
; p
< &contab
[NM
]; p
++)
156 for (p
=contab
; p
< &contab
[NM
]; p
++) {
173 while (!skip() && (j
= getrq()) != 0)
216 extern filep
finds();
223 if ((i
= getrq()) == 0)
225 if ((offset
= finds(i
)) == 0)
234 if (contab
[newmn
].rq
)
235 munhash(&contab
[newmn
]);
236 contab
[newmn
].rq
= i
;
237 maddhash(&contab
[newmn
]);
260 for (p
= mhash
[MHASH(i
)]; p
; p
= p
->link
)
273 ffree((filep
)contab
[i
].mx
);
289 extern filep
alloc();
290 extern filep
incoff();
295 if (app
&& oldmn
>= 0 && contab
[oldmn
].mx
) {
297 ip
= (filep
)contab
[oldmn
].mx
;
299 while ((i
= rbf()) != 0)
307 for (i
= 0; i
< NM
; i
++) {
308 if (contab
[i
].rq
== 0)
311 if (i
== NM
|| (nextb
= alloc()) == 0) {
315 errprint(gettext("Too many (%d) string/macro names"),
320 contab
[i
].mx
= (unsigned) nextb
;
327 maddhash(&contab
[i
]);
331 return(offset
= nextb
);
336 skip() /*skip over blanks; return nlflg*/
340 while (cbits(i
= getch()) == ' ')
355 if (skip() || !(j
= getrq()))
367 * state 2 look for first char of end macro
368 * state 3 look for second char of end macro
372 i
= cbits(ii
= getch());
391 if (state
== 1 && i
== '.') {
396 if ((state
== 2) && (i
== j
)) {
423 if (cbits(i
= getch()) != '"')
425 while (cbits(i
= getch()) != '\n')
435 filep
alloc() /*return free blist[] block in nextb*/
440 for (i
= 0; i
< NBLIST
; i
++) {
448 j
= (filep
)i
* BLK
+ ENV_BLK
* BLK
;
451 if (debug
& DB_ALLC
) {
453 fdprintf(stderr
, "alloc: ");
454 if (oldmn
>= 0 && oldmn
< NM
) {
455 cc1
= contab
[oldmn
].rq
& 0177;
456 if ((cc2
= (contab
[oldmn
].rq
>> BYTE
) & 0177) == 0)
458 fdprintf(stderr
, "oldmn %d %c%c, ", oldmn
, cc1
, cc2
);
460 fdprintf(stderr
, "newmn %d; nextb was %x, will be %x\n",
469 ffree(i
) /*free blist[i] and blocks pointed to*/
474 while (blist
[j
= blisti(i
)] != (unsigned) ~0) {
475 i
= (filep
) blist
[j
];
495 wbf(i
) /*store i into blist[offset] (?) */
505 wbuf
= &corebuf
[woff
]; /* INCORE only */
510 if (!((++offset
) & (BLK
- 1))) {
512 j
= blisti(--offset
);
513 if (j
< 0 || j
>= NBLIST
) {
514 errprint(gettext("Out of temp file space"));
517 if (blist
[j
] == (unsigned) ~0) {
519 errprint(gettext("Out of temp file space"));
522 blist
[j
] = (unsigned)(nextb
);
524 offset
= ((filep
)blist
[j
]);
534 wbfl() /*flush current blist[] block*/
539 lseek(ibf
, ((long)woff
) * sizeof(tchar
), 0);
540 write(ibf
, (char *)wbuf
, wbfi
* sizeof(tchar
));
542 if ((woff
& (~(BLK
- 1))) == (roff
& (~(BLK
- 1))))
550 tchar
rbf() /*return next char from blist[] block*/
554 extern filep
incoff();
556 if (ip
== NBLIST
*BLK
) { /* for rdtty */
562 /* this is an inline expansion of rbf0: dirty! */
567 lseek(ibf
, (long)j
* sizeof(tchar
), 0);
568 if (read(ibf
, (char *)rbuf
, BLK
* sizeof(tchar
)) <= 0)
571 i
= rbuf
[ip
& (BLK
-1)];
573 i
= rbuf
[ip
& (BLK
-1)];
583 /* this is an inline expansion of incoff: also dirty */
585 if ((p
& (BLK
- 1)) == 0) {
586 if ((ip
= blist
[blisti(p
-1)]) == (unsigned) ~0) {
587 errprint(gettext("Bad storage allocation"));
591 /* this was meant to protect against people removing
592 * the macro they were standing on, but it's too
593 * sensitive to block boundaries.
595 * errprint(gettext("Block removed while in use"));
610 if ((i
= p
& ~(BLK
- 1)) != roff
) {
612 lseek(ibf
, (long)roff
* sizeof(tchar
), 0);
613 if (read(ibf
, (char *)rbuf
, BLK
* sizeof(tchar
)) == 0)
616 return(rbuf
[p
& (BLK
-1)]);
623 filep
incoff(p
) /*get next blist[] block*/
627 if ((p
& (BLK
- 1)) == 0) {
628 if ((p
= blist
[blisti(p
-1)]) == (unsigned) ~0) {
629 errprint(gettext("Bad storage allocation"));
650 lastpbp
= p
->lastpbp
;
655 * test that the end of the allocation is above a certain location
658 #define SPACETEST(base, size) while ((enda - (size)) <= (char *)(base)){setbrk(DELTA);}
666 extern char *setbrk();
668 SPACETEST(nxf
, sizeof(struct s
));
674 p
->lastpbp
= lastpbp
;
682 nxf
= (struct s
*)argtop
;
694 if ((i
= sbrk(x
)) == (char *) -1) {
695 errprint(gettext("Core limit reached"));
698 if (j
= (unsigned)i
% sizeof(int)) { /*check alignment for 3B*/
699 j
= sizeof(int) - j
; /*only init calls should need this*/
700 if ((k
= sbrk(j
)) == (char *) -1) {
701 errprint("Core limit reached");
704 if (k
!= i
+ x
) { /*there must have been an intervening sbrk*/
705 errprint ("internal error in setbrk: i=%x, j=%d, k=%x",
721 if ((i
= getach()) == 0)
736 if ((i
= getsn()) == 0 || (j
= findmn(i
)) == -1 || !contab
[j
].mx
) {
740 SPACETEST(nxf
, sizeof(struct s
));
744 return pushi((filep
)contab
[j
].mx
, i
);
756 tchar
* *argpp
, **argppend
;
768 memp
= (char *)savnxf
;
770 * 1 s structure for the macro descriptor
771 * APERMAC tchar *'s for pointers into the strings
772 * space for the tchar's themselves
774 memp
+= sizeof(struct s
);
776 * CPERMAC (the total # of characters for ALL arguments)
777 * to a macros, has been carefully chosen
778 * so that the distance between stack frames is < DELTA
782 memp
+= APERMAC
* sizeof(tchar
*);
783 memp
+= CPERMAC
* sizeof(tchar
);
784 nxf
= (struct s
*)memp
;
787 argpp
= (tchar
**)(savnxf
+ 1);
788 argppend
= &argpp
[APERMAC
];
789 SPACETEST(argppend
, sizeof(tchar
*));
790 strp
= (tchar
*)argppend
;
792 * Zero out all the string pointers before filling them in.
794 for (j
= 0; j
< APERMAC
; j
++){
795 argpp
[j
] = (tchar
*)0;
798 errprint("savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x,lim=0x%x,enda=0x%x",
799 savnxf
, nxf
, argpp
, strp
, lim
, enda
);
802 while ((argpp
!= argppend
) && (!skip())) {
805 if (cbits(i
= getch()) == '"')
811 if (nlflg
|| (!quote
&& cbits(i
) == ' '))
815 && (cbits(i
= getch()) != '"')) {
820 if (strflg
&& strp
>= lim
) {
822 errprint("strp=0x%x, lim = 0x%x",
825 errprint(gettext("Macro argument too long"));
829 SPACETEST(strp
, 3 * sizeof(tchar
));
834 nxf
->nargs
= argpp
- (tchar
**)(savnxf
+ 1);
848 i
= cbits(getch()) - '0';
849 if (i
> 0 && i
<= APERMAC
&& i
<= frame
->nargs
)
850 pushback(*(((tchar
**)(frame
+ 1)) + i
- 1));
873 if (skip() || (i
= getrq()) == 0) {
877 numtab
[DN
].val
= dip
->dnl
;
878 numtab
[DL
].val
= dip
->maxl
;
884 if (++dilev
== NDI
) {
886 errprint(gettext("Diversions nested too deep"));
896 k
= (int *) & dip
->dnl
;
897 for (j
= 0; j
< 10; j
++)
898 k
[j
] = 0; /*not op and curd*/
911 dip
->dimac
= dip
->ditrap
= dip
->ditf
= 0;
913 dip
->ditrap
= vnumb((int *)0);
917 dip
->dimac
= getrq();
934 if (ismot(delim
= getch())) {
938 delim
= cbits(delim
);
941 w
[0] = w
[1] = w
[2] = 0;
943 while (cbits(i
= getch()) != '\n') {
944 if (cbits(i
) == cbits(delim
)) {
946 w
[j
] = numtab
[HP
].val
;
951 if (cbits(i
) == pagech
) {
952 setn1(numtab
[PN
].val
, numtab
[findr('%')].fmt
,
956 numtab
[HP
].val
+= width(i
);
957 if (tp
< &buf
[LNSIZE
-10])
962 w
[j
] = numtab
[HP
].val
;
973 horiz(j
= quant((lt
- w
[1]) / 2 - w
[0], HOR
));
977 horiz(lt
- w
[0] - w
[1] - w
[2] - j
);
983 if (dip
->dnl
> dip
->hnl
)
986 if (numtab
[NL
].val
> dip
->hnl
)
987 dip
->hnl
= numtab
[NL
].val
;
1008 int xx
, cnt
, tcnt
, kk
, tot
;
1012 kk
= cnt
= tcnt
= 0;
1014 for (i
= 0; i
< NM
; i
++) {
1015 if ((xx
= contab
[i
].rq
) == 0 || contab
[i
].mx
== 0)
1019 j
= (filep
) contab
[i
].mx
;
1021 while ((j
= blist
[blisti(j
)]) != (unsigned) ~0) {
1028 if (!(*p
++ = (xx
>> BYTE
) & 0177))
1031 fdprintf(stderr
, "%s %d\n", pmline
, k
);
1034 fdprintf(stderr
, "pm: total %d, macros %d, space %d\n", tcnt
, cnt
, kk
);
1040 stackdump() /* dumps stack of macros in process */
1045 for (p
= frame
; p
!= stk
; p
= p
->pframe
)
1046 fdprintf(stderr
, "%c%c ", p
->mname
&0177, (p
->mname
>>BYTE
)&0177);
1047 fdprintf(stderr
, "\n");