added way to request unique resource name.
[dyninst.git] / paradynd / src / resource.C
1 /*
2  *  Copyright 1993 Jeff Hollingsworth.  All rights reserved.
3  *
4  */
5
6 #ifndef lint
7 static char Copyright[] = "@(#) Copyright (c) 1993 Jeff Hollingsowrth\
8     All rights reserved.";
9
10 static char rcsid[] = "@(#) $Header: /home/jaw/CVSROOT_20081103/CVSROOT/core/paradynd/src/resource.C,v 1.4 1994/05/16 22:31:54 hollings Exp $";
11 #endif
12
13 /*
14  * resource.C - handle resource creation and queries.
15  *
16  * $Log: resource.C,v $
17  * Revision 1.4  1994/05/16 22:31:54  hollings
18  * added way to request unique resource name.
19  *
20  * Revision 1.3  1994/02/24  04:32:36  markc
21  * Changed header files to reflect igen changes.  main.C does not look at the number of command line arguments now.
22  *
23  * Revision 1.2  1994/02/01  18:46:55  hollings
24  * Changes for adding perfConsult thread.
25  *
26  * Revision 1.1  1994/01/27  20:31:41  hollings
27  * Iinital version of paradynd speaking dynRPC igend protocol.
28  *
29  * Revision 1.3  1993/07/13  18:30:02  hollings
30  * new include file syntax.
31  * expanded tempName to 255 chars for c++ support.
32  *
33  * Revision 1.2  1993/06/08  20:14:34  hollings
34  * state prior to bc net ptrace replacement.
35  *
36  * Revision 1.1  1993/03/19  22:45:45  hollings
37  * Initial revision
38  *
39  *
40  */
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "symtab.h"
46 #include "process.h"
47 #include "dyninstP.h"
48 #include "util.h"
49 #include "dyninstRPC.SRVR.h"
50
51 extern dynRPC *tp;
52 HTable <resource>       allResources;
53
54 /*
55  * handle the notification of resource creation and deletion.
56  *
57  */
58
59 _resourceRec rootNode(False);
60
61 resource rootResource = &rootNode;
62
63 resourceList getRootResources()
64 {
65     return(rootResource->children);
66 }
67
68 char *getResourceName(resource r)
69 {
70     return(r->info.name);
71 }
72
73 resource getResourceParent(resource r)
74 {
75     return(r->parent);
76 }
77
78 resourceList getResourceChildren(resource r)
79 {
80     return(r->children);
81 }
82
83 int getResourceCount(resourceList rl)
84 {
85     return(rl ? rl->count: 0);
86 }
87
88 resource getNthResource(resourceList rl, int n)
89 {
90     if (n < rl->count) {
91         return(rl->elements[n]);
92     } else {
93         return(NULL);
94     }
95 }
96
97 resourceInfo *getResourceInfo(resource r)
98 {
99     return(&r->info);
100 }
101
102 resourceList createResourceList()
103 {
104     resourceList ret;
105
106     ret = (resourceList) xcalloc(sizeof(struct _resourceListRec), 1);
107     return(ret);
108 }
109
110 Boolean addResourceList(resourceList rl, resource r)
111 {
112
113     if (rl->count == rl->maxItems) {
114         rl->maxItems += 10;
115         if (rl->elements) {
116             rl->elements = (resource *) 
117                 xrealloc(rl->elements, sizeof(resource) * rl->maxItems);
118         } else {
119             rl->elements = (resource *) xmalloc(sizeof(resource) * rl->maxItems);
120         }
121     }
122     rl->elements[rl->count] = r;
123     rl->count++;
124     return(True);
125 }
126
127 Boolean initResourceRoot;
128
129 resource newResource(resource parent, 
130                      void *handle, 
131                      char *name, 
132                      timeStamp creation,
133                      Boolean unique)
134 {
135     int c;
136     char *iName;
137     resource ret;
138     resource *curr;
139     char tempName[255];
140
141     if (unique) {
142         // ask paradyn for unqiue name.
143         name = tp->getUniqueResource(0, parent->info.fullName, name);
144     }
145
146     if (!initResourceRoot) {
147         initResourceRoot = True;
148         rootNode.info.name = "";
149         rootNode.info.fullName = "";
150         rootNode.info.creation = 0.0;
151         rootNode.parent = NULL;
152         rootNode.handle = NULL;
153         rootNode.children = NULL;
154     }
155
156     iName = pool.findAndAdd(name);
157
158     /* first check to see if the resource has already been defined */
159     if (parent->children) {
160         for (curr=parent->children->elements, c=0;
161              c < parent->children->count; c++) {
162              if (curr[c]->info.name == iName) {
163                  return(curr[c]);
164              }
165         }
166     } else {
167         parent->children = (resourceList) 
168             xcalloc(sizeof(struct _resourceListRec), 1);
169     }
170
171     ret = new(_resourceRec);
172     ret->parent = parent;
173     ret->handle = handle;
174
175     sprintf(tempName, "%s/%s", parent->info.fullName, name);
176     ret->info.fullName = pool.findAndAdd(tempName);
177     ret->info.name = iName;
178
179     ret->info.creation = creation;
180
181     addResourceList(parent->children, ret);
182     allResources.add(ret, (void *) ret->info.fullName);
183
184     /* call notification upcall */
185     tp->resourceInfoCallback(0, parent->info.fullName, ret->info.name, 
186          ret->info.name);
187
188     return(ret);
189 }
190
191 resource findChildResource(resource parent, char *name)
192 {
193     int c;
194     char *iName;
195     resource *curr;
196
197     iName = pool.findAndAdd(name);
198
199     if (!parent || !parent->children) return(NULL);
200     for (curr=parent->children->elements, c=0;
201          c < parent->children->count; c++) {
202          if (curr[c]->info.name == iName) {
203              return(curr[c]);
204          }
205     }
206     return(NULL);
207 }
208
209 void printResources(resource r)
210 {
211     int c;
212     resource *curr;
213
214     if (r) {
215         printf("%s\n", r->info.fullName);
216         if (r->children) {
217             for (curr=r->children->elements, c=0;
218                  c < r->children->count; c++) {
219                  printResources(curr[c]);
220             }
221         }
222     }
223 }
224
225 void printResourceList(resourceList rl)
226 {
227     int i;
228
229     printf("<");
230     for (i=0; i < rl->count; i++) {
231         printf(rl->elements[i]->info.fullName);
232         if (i!= rl->count-1) printf(",");
233     }
234     printf(">");
235 }
236
237 /*
238  * Convinence function.
239  *
240  */
241 Boolean isResourceDescendent(resource parent, resource child)
242 {
243     while (child) {
244         if (child == parent) {
245             return(True);
246         } else {
247             child = getResourceParent(child);
248         }
249     }
250     return(False);
251 }
252
253 //
254 // Find this passed focus if its resource components are valid for paradynd.
255 //    We treat "unknown" top level resources as a specical case since the
256 //    meaning is that we are at the top level of refinement of an unsupported
257 //    resource hierarchy.  In this case, we simply create the resource, and
258 //    the focus is valid.  Any other resource that can't be found results in
259 //    an invalid focus.  jkh 1/29/94.
260 //
261 resourceList findFocus(int count, char **data)
262 {
263     int i;
264     char *iName;
265     resource res;
266     resourceList rl;
267
268     rl = createResourceList();
269     for (i=0; i < count; i++) {
270         iName = pool.findAndAdd(data[i]);
271         res = allResources.find(iName);
272         if (!res && (strchr(iName, '/') == strrchr(iName, '/'))) {
273             res = newResource(rootResource, NULL, ++iName, 0.0, FALSE);
274         } else if (!res) {
275             return(NULL);
276         }
277         addResourceList(rl, res);
278     }
279     return(rl);
280 }
281
282 resource findResource(char *name)
283 {
284     char *iName;
285     resource res;
286
287     if (*name == '\0') {
288         return(rootResource);
289     } else {
290         iName = pool.findAndAdd(name);
291         res = allResources.find(iName);
292         return(res);
293     }
294 }