summaryrefslogtreecommitdiff
path: root/do/caller
blob: cb921e507d0fdba4452c4f780a8114858c1384b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
int
do_caller(arg,maxarg,gimme,arglast)
ARG *arg;
int maxarg;
int gimme;
int *arglast;
{
    STR **st = stack->ary_array;
    register int sp = arglast[0];
    register CSV *csv = curcsv;
    STR *TARG;
    int count = 0;

    if (!csv)
	fatal("There is no caller");
    if (maxarg)
	count = (int) str_gnum(st[sp+1]);
    for (;;) {
	if (!csv)
	    return sp;
	if (DBsub && csv->oldcsv && csv->oldcsv->sub == stab_sub(DBsub))
	    count++;
	if (!count--)
	    break;
	csv = csv->oldcsv;
    }
    if (gimme != G_ARRAY) {
	STR *TARG = ARGTARG;
	str_set(TARG,csv->oldcmd->c_stash->tbl_name);
	STABSET(TARG);
	st[++sp] = TARG;
	return sp;
    }

#ifndef lint
    (void)astore(stack,++sp,
      str_2mortal(str_make(csv->oldcmd->c_stash->tbl_name,0)) );
    (void)astore(stack,++sp,
      str_2mortal(str_make(stab_val(csv->oldcmd->c_filestab)->str_ptr,0)) );
    (void)astore(stack,++sp,
      str_2mortal(str_nmake((double)csv->oldcmd->c_line)) );
    if (!maxarg)
	return sp;
    TARG = Str_new(49,0);
    stab_efullname(TARG, csv->stab);
    (void)astore(stack,++sp, str_2mortal(TARG));
    (void)astore(stack,++sp,
      str_2mortal(str_nmake((double)csv->hasargs)) );
    (void)astore(stack,++sp,
      str_2mortal(str_nmake((double)csv->wantarray)) );
    if (csv->hasargs) {
	ARRAY *ary = csv->argarray;

	if (!dbargs)
	    dbargs = stab_xarray(aadd(stabent("DB'args", TRUE)));
	if (dbargs->ary_max < ary->ary_fill)
	    astore(dbargs,ary->ary_fill,Nullstr);
	Copy(ary->ary_array, dbargs->ary_array, ary->ary_fill+1, STR*);
	dbargs->ary_fill = ary->ary_fill;
    }
#else
    (void)astore(stack,++sp,
      str_2mortal(str_make("",0)));
#endif
    return sp;
}