summaryrefslogtreecommitdiff
path: root/do/study
diff options
context:
space:
mode:
Diffstat (limited to 'do/study')
-rw-r--r--do/study73
1 files changed, 73 insertions, 0 deletions
diff --git a/do/study b/do/study
new file mode 100644
index 0000000000..14c2e067c0
--- /dev/null
+++ b/do/study
@@ -0,0 +1,73 @@
+int /*SUPPRESS 590*/
+do_study(TARG,arg,gimme,arglast)
+STR *TARG;
+ARG *arg;
+int gimme;
+int *arglast;
+{
+ register unsigned char *s;
+ register int pos = TARG->str_cur;
+ register int ch;
+ register int *sfirst;
+ register int *snext;
+ int retval;
+ int retarg = arglast[0] + 1;
+
+#ifndef lint
+ s = (unsigned char*)(str_get(TARG));
+#else
+ s = Null(unsigned char*);
+#endif
+ if (lastscream)
+ lastscream->str_pok &= ~SP_STUDIED;
+ lastscream = TARG;
+ if (pos <= 0) {
+ retval = 0;
+ goto ret;
+ }
+ if (pos > maxscream) {
+ if (maxscream < 0) {
+ maxscream = pos + 80;
+ New(301,screamfirst, 256, int);
+ New(302,screamnext, maxscream, int);
+ }
+ else {
+ maxscream = pos + pos / 4;
+ Renew(screamnext, maxscream, int);
+ }
+ }
+
+ sfirst = screamfirst;
+ snext = screamnext;
+
+ if (!sfirst || !snext)
+ fatal("do_study: out of memory");
+
+ for (ch = 256; ch; --ch)
+ *sfirst++ = -1;
+ sfirst -= 256;
+
+ while (--pos >= 0) {
+ ch = s[pos];
+ if (sfirst[ch] >= 0)
+ snext[pos] = sfirst[ch] - pos;
+ else
+ snext[pos] = -pos;
+ sfirst[ch] = pos;
+
+ /* If there were any case insensitive searches, we must assume they
+ * all are. This speeds up insensitive searches much more than
+ * it slows down sensitive ones.
+ */
+ if (sawi)
+ sfirst[fold[ch]] = pos;
+ }
+
+ TARG->str_pok |= SP_STUDIED;
+ retval = 1;
+ ret:
+ str_numset(ARGTARG,(double)retval);
+ stack->ary_array[retarg] = ARGTARG;
+ return retarg;
+}
+