-#include "extr.h"
-#include "pathnames.h"
-
-/*
- * indx - find the index of second str in the
- * first str.
- */
-indx(s1, s2)
-char *s1;
-char *s2;
-{
- register char *t;
- register char *p;
- register char *m;
-
- for (p = s1; *p; p++) {
- for (t = p, m = s2; *m && *m == *t; m++, t++)
- ;
- if (!*m)
- return(p - s1);
- }
- return (-1);
-}
-
-/*
- * putback - push character back onto input
- *
- */
-putback (c)
-char c;
-{
- if (bp < endpbb)
- *bp++ = c;
- else
- error("m4: too many characters pushed back");
-}
-
-/*
- * pbstr - push string back onto input
- * putback is replicated to improve
- * performance.
- *
- */
-pbstr(s)
-register char *s;
-{
- register char *es;
+#include "extr.h"
+#include "ourlims.h"
+
+#ifdef DUFFCP
+
+/* This version of the ANSI standard function memcpy()
+ uses Duff's Device (tm Tom Duff) to unroll the copying loop:
+ while (count-- > 0) *to++ = *from++;
+*/
+void memcpy(to, from, count)
+ register char *from, *to;
+ register int count;
+ {
+ if (count > 0) {
+ register int loops = (count+8-1) >> 3; /* div 8 round up */
+
+ switch (count & (8-1)) { /* mod 8 */
+ case 0: do { *to++ = *from++;
+ case 7: *to++ = *from++;
+ case 6: *to++ = *from++;
+ case 5: *to++ = *from++;
+ case 4: *to++ = *from++;
+ case 3: *to++ = *from++;
+ case 2: *to++ = *from++;
+ case 1: *to++ = *from++;
+ } while (--loops > 0);
+ }
+ }
+ }
+
+#endif
+
+
+/* strsave(s)
+ return a new malloc()ed copy of s -- same as V.3's strdup().
+*/
+char *strsave(s)
+ char *s;
+ {
+ register int n = strlen(s)+1;
+ char *p = malloc(n);
+
+ if (p) memcpy(p, s, n);
+ return p;
+ }
+
+
+/* indx(s1, s2)
+ if s1 can be decomposed as alpha || s2 || omega, return the length
+ of the shortest such alpha, otherwise return -1.
+*/
+int indx(s1, s2)
+ char *s1;
+ char *s2;
+ {
+ register char *t;
+ register char *m;
+ register char *p;
+
+ for (p = s1; *p; p++) {
+ for (t = p, m = s2; *m && *m == *t; m++, t++);
+ if (!*m) return p-s1;
+ }
+ return -1;
+ }
+
+
+char pbmsg[] = "m4: too many characters pushed back";
+
+/* Xputback(c)
+ push character c back onto the input stream.
+ This is now macro putback() in misc.h
+*/
+void Xputback(c)
+ char c;
+ {
+ if (bp < endpbb) *bp++ = c; else error(pbmsg);
+ }
+
+
+/* pbstr(s)
+ push string s back onto the input stream.
+ putback() has been unfolded here to improve performance.
+ Example:
+ s = <ABC>
+ bp = <more stuff>
+ After the call:
+ bp = <more stuffCBA>
+ It would be more efficient if we ran the pushback buffer in the
+ opposite direction
+*/
+void pbstr(s)
+ register char *s;
+ {
+ register char *es;
+ register char *zp;
+
+ zp = bp;
+ for (es = s; *es; ) es++; /* now es points to terminating NUL */
+ bp += es-s; /* advance bp as far as it should go */
+ if (bp >= endpbb) error("m4: too many characters to push back");
+ while (es > s) *zp++ = *--es;
+ }
+
+
+/* pbqtd(s)
+ pushes string s back "quoted", doing whatever has to be done to it to
+ make sure that the result will evaluate to the original value. As it
+ happens, we have only to add lquote and rquote.
+*/
+void pbqtd(s)
+ register char *s;
+ {
+ register char *es;