Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / librols / getav0.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12
13 /* @(#)getav0.c 1.16 04/05/09 Copyright 1985, 1995-2004 J. Schilling */
14 /*
15  *      Get arg vector by scanning the stack
16  *
17  *      Copyright (c) 1985, 1995-2004 J. Schilling
18  */
19 /*
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License version 2
22  * as published by the Free Software Foundation.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License along with
30  * this program; see the file COPYING.  If not, write to the Free Software
31  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32  */
33
34 #include <mconfig.h>
35 #include <sigblk.h>
36 #include <avoffset.h>
37 #include <standard.h>
38 #include <schily.h>
39
40 #if     !defined(AV_OFFSET) || !defined(FP_INDIR)
41 #       ifdef   HAVE_SCANSTACK
42 #       undef   HAVE_SCANSTACK
43 #       endif
44 #endif
45
46 #ifdef  HAVE_SCANSTACK
47
48 #include <stkframe.h>
49
50 #define is_even(p)      ((((long)(p)) & 1) == 0)
51 #define even(p)         (((long)(p)) & ~1L)
52 #ifdef  __future__
53 #define even(p)         (((long)(p)) - 1) /* will this work with 64 bit ?? */
54 #endif
55
56 EXPORT  char    **getmainfp     __PR((void));
57 EXPORT  char    **getavp        __PR((void));
58 EXPORT  char    *getav0         __PR((void));
59
60
61 EXPORT char **
62 getmainfp()
63 {
64         register struct frame *fp;
65                 char    **av;
66 #if     FP_INDIR > 0
67         register int    i = 0;
68 #endif
69
70         /*
71          * As the SCO OpenServer C-Compiler has a bug that may cause
72          * the first function call to getfp() been done before the
73          * new stack frame is created, we call getfp() twice.
74          */
75         (void) getfp();
76         fp = (struct frame *)getfp();
77         if (fp == NULL)
78                 return (NULL);
79
80         while (fp->fr_savfp) {
81                 if (fp->fr_savpc == NULL)
82                         break;
83
84                 if (!is_even(fp->fr_savfp)) {
85                         fp = (struct frame *)even(fp->fr_savfp);
86                         if (fp == NULL)
87                                 break;
88                         fp = (struct frame *)((SIGBLK *)fp)->sb_savfp;
89                         continue;
90                 }
91                 fp = (struct frame *)fp->fr_savfp;
92
93 #if     FP_INDIR > 0
94                 i++;
95 #endif
96         }
97
98 #if     FP_INDIR > 0
99         i -= FP_INDIR;
100         fp = (struct frame *)getfp();
101         if (fp == NULL)
102                 return (NULL);
103
104         while (fp->fr_savfp) {
105                 if (fp->fr_savpc == NULL)
106                         break;
107
108                 if (!is_even(fp->fr_savfp)) {
109                         fp = (struct frame *)even(fp->fr_savfp);
110                         if (fp == NULL)
111                                 break;
112                         fp = (struct frame *)((SIGBLK *)fp)->sb_savfp;
113                         continue;
114                 }
115                 fp = (struct frame *)fp->fr_savfp;
116
117                 if (--i <= 0)
118                         break;
119         }
120 #endif
121
122         av = (char **)fp;
123         return (av);
124 }
125
126 EXPORT char **
127 getavp()
128 {
129         register struct frame *fp;
130                 char    **av;
131
132         fp = (struct frame *)getmainfp();
133         if (fp == NULL)
134                 return (NULL);
135
136         av = (char **)(((char *)fp) + AV_OFFSET);       /* aus avoffset.h */
137                                                         /* -> avoffset.c  */
138         return (av);
139 }
140
141 EXPORT char *
142 getav0()
143 {
144         return (getavp()[0]);
145 }
146
147 #else
148
149 EXPORT char *
150 getav0()
151 {
152         return ("???");
153 }
154
155 #endif  /* HAVE_SCANSTACK */