summaryrefslogtreecommitdiff
path: root/do/grep
diff options
context:
space:
mode:
Diffstat (limited to 'do/grep')
-rw-r--r--do/grep49
1 files changed, 49 insertions, 0 deletions
diff --git a/do/grep b/do/grep
new file mode 100644
index 0000000000..94598ab6ea
--- /dev/null
+++ b/do/grep
@@ -0,0 +1,49 @@
+int
+do_grep(arg,TARG,gimme,arglast)
+register ARG *arg;
+STR *TARG;
+int gimme;
+int *arglast;
+{
+ STR **st = stack->ary_array;
+ register int dst = arglast[1];
+ register int src = dst + 1;
+ register int sp = arglast[2];
+ register int i = sp - arglast[1];
+ int oldsave = savestack->ary_fill;
+ SPAT *oldspat = curspat;
+ int oldtmps_base = tmps_base;
+
+ savesptr(&stab_val(defstab));
+ tmps_base = tmps_max;
+ if ((arg[1].arg_type & A_MASK) != A_EXPR) {
+ arg[1].arg_type &= A_MASK;
+ dehoist(arg,1);
+ arg[1].arg_type |= A_DONT;
+ }
+ arg = arg[1].arg_ptr.arg_arg;
+ while (i-- > 0) {
+ if (st[src]) {
+ st[src]->str_pok &= ~SP_TEMP;
+ stab_val(defstab) = st[src];
+ }
+ else
+ stab_val(defstab) = str_mortal(&str_undef);
+ (void)eval(arg,G_SCALAR,sp);
+ st = stack->ary_array;
+ if (str_true(st[sp+1]))
+ st[dst++] = st[src];
+ src++;
+ curspat = oldspat;
+ }
+ restorelist(oldsave);
+ tmps_base = oldtmps_base;
+ if (gimme != G_ARRAY) {
+ str_numset(TARG,(double)(dst - arglast[1]));
+ STABSET(TARG);
+ st[arglast[0]+1] = TARG;
+ return arglast[0]+1;
+ }
+ return arglast[0] + (dst - arglast[1]);
+}
+