/* * File: fscan.c * Contents: move, pos, tab. */ #include "..\h\config.h" #include "..\h\rt.h" #include "rproto.h" /* * move(i) - move &pos by i, return substring of &subject spanned. * Reverses effects if resumed. */ FncDcl(move,1) { register word i, j; word oldpos; /* * Arg1 must be a (non-long) integer. */ switch (cvint(&Arg1)) { case T_Integer: j = (word)IntVal(Arg1); break; default: RunErr(101, &Arg1); } /* * Save old &pos. Local variable i holds &pos before the move. */ oldpos = i = k_pos; /* * If attempted move is past either end of the string, fail. */ if (i + j <= 0 || i + j > StrLen(k_subject) + 1) Fail; /* * Set new &pos. */ k_pos += j; /* * Make sure j >= 0. */ if (j < 0) { i += j; j = -j; } /* * Suspend substring of &subject that was moved over. */ StrLen(Arg0) = j; StrLoc(Arg0) = StrLoc(k_subject) + i - 1; Suspend; /* * If move is resumed, restore the old position and fail. */ if (oldpos > StrLen(k_subject) + 1) { RunErr(205, &tvky_pos.kyval) } else k_pos = oldpos; Fail; } /* * pos(i) - test if &pos is at position i in &subject. */ FncDcl(pos,1) { register word i; /* * Arg1 must be an integer. */ if (cvint(&Arg1) == CvtFail) RunErr(101, &Arg1); /* * Fail if &pos is not equivalent to Arg1, return Arg1 otherwise. */ if ((i = cvpos(IntVal(Arg1), StrLen(k_subject))) != k_pos) Fail; MakeInt(i, &Arg0); Return; } /* * tab(i) - set &pos to i, return substring of &subject spanned. * Reverses effects if resumed.. */ FncDcl(tab,1) { register word i, j; word t, oldpos; /* * Arg1 must be an integer. */ if (cvint(&Arg1) == CvtFail) RunErr(101, &Arg1); /* * Convert it to an absolute position. */ j = cvpos(IntVal(Arg1), StrLen(k_subject)); if (j == CvtFail) Fail; /* * Save old &pos. Local variable i holds &pos before the tab. */ oldpos = i = k_pos; /* * Set new &pos. */ k_pos = j; /* * Make j the length of the substring &subject[i:j] */ if (i > j) { t = i; i = j; j = t - j; } else j = j - i; /* * Suspend the portion of &subject that was tabbed over. */ StrLoc(Arg0) = StrLoc(k_subject) + i - 1; StrLen(Arg0) = j; Suspend; /* * If tab is resumed, restore the old position and fail. */ if (oldpos > StrLen(k_subject) + 1) { RunErr(205, &tvky_pos.kyval); } else k_pos = oldpos; Fail; }