File: | libs/apr-util/hooks/apr_hooks.c |
Location: | line 183, column 17 |
Description: | Access to field 'pNext' results in a dereference of a null pointer (loaded from variable 'pTail') |
1 | /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as | |||
2 | * applicable. | |||
3 | * | |||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |||
5 | * you may not use this file except in compliance with the License. | |||
6 | * You may obtain a copy of the License at | |||
7 | * | |||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |||
9 | * | |||
10 | * Unless required by applicable law or agreed to in writing, software | |||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
13 | * See the License for the specific language governing permissions and | |||
14 | * limitations under the License. | |||
15 | */ | |||
16 | ||||
17 | #include <assert.h> | |||
18 | #include <stdio.h> | |||
19 | #include <stdlib.h> | |||
20 | ||||
21 | #include "apr_pools.h" | |||
22 | #include "apr_tables.h" | |||
23 | #include "apr.h" | |||
24 | #include "apr_hooks.h" | |||
25 | #include "apr_hash.h" | |||
26 | #include "apr_optional_hooks.h" | |||
27 | #include "apr_optional.h" | |||
28 | #define APR_WANT_MEMFUNC | |||
29 | #define APR_WANT_STRFUNC | |||
30 | #include "apr_want.h" | |||
31 | ||||
32 | #if 0 | |||
33 | #define apr_palloc(pool,size) malloc(size) | |||
34 | #endif | |||
35 | ||||
36 | APU_DECLARE_DATA apr_pool_t *apr_hook_global_pool = NULL((void*)0); | |||
37 | APU_DECLARE_DATA int apr_hook_debug_enabled = 0; | |||
38 | APU_DECLARE_DATA const char *apr_hook_debug_current = NULL((void*)0); | |||
39 | ||||
40 | /** @deprecated @see apr_hook_global_pool */ | |||
41 | APU_DECLARE_DATA apr_pool_t *apr_global_hook_pool = NULL((void*)0); | |||
42 | ||||
43 | /** @deprecated @see apr_hook_debug_enabled */ | |||
44 | APU_DECLARE_DATA int apr_debug_module_hooks = 0; | |||
45 | ||||
46 | /** @deprecated @see apr_hook_debug_current */ | |||
47 | APU_DECLARE_DATA const char *apr_current_hooking_module = NULL((void*)0); | |||
48 | ||||
49 | /* NB: This must echo the LINK_##name structure */ | |||
50 | typedef struct | |||
51 | { | |||
52 | void (*dummy)(void *); | |||
53 | const char *szName; | |||
54 | const char * const *aszPredecessors; | |||
55 | const char * const *aszSuccessors; | |||
56 | int nOrder; | |||
57 | } TSortData; | |||
58 | ||||
59 | typedef struct tsort_ | |||
60 | { | |||
61 | void *pData; | |||
62 | int nPredecessors; | |||
63 | struct tsort_ **ppPredecessors; | |||
64 | struct tsort_ *pNext; | |||
65 | } TSort; | |||
66 | ||||
67 | #ifdef NETWARE | |||
68 | #include "apr_private.h" | |||
69 | #define get_apd APP_DATA* apd = (APP_DATA*)get_app_data(gLibId); | |||
70 | #define s_aHooksToSort ((apr_array_header_t *)(apd->gs_aHooksToSort)) | |||
71 | #define s_phOptionalHooks ((apr_hash_t *)(apd->gs_phOptionalHooks)) | |||
72 | #define s_phOptionalFunctions ((apr_hash_t *)(apd->gs_phOptionalFunctions)) | |||
73 | #endif | |||
74 | ||||
75 | static int crude_order(const void *a_,const void *b_) | |||
76 | { | |||
77 | const TSortData *a=a_; | |||
78 | const TSortData *b=b_; | |||
79 | ||||
80 | return a->nOrder-b->nOrder; | |||
81 | } | |||
82 | ||||
83 | static TSort *prepare(apr_pool_t *p,TSortData *pItems,int nItems) | |||
84 | { | |||
85 | TSort *pData=apr_palloc(p,nItems*sizeof *pData); | |||
86 | int n; | |||
87 | ||||
88 | qsort(pItems,nItems,sizeof *pItems,crude_order); | |||
89 | for(n=0 ; n < nItems ; ++n) { | |||
90 | pData[n].nPredecessors=0; | |||
91 | pData[n].ppPredecessors=apr_pcalloc(p,nItems*sizeof *pData[n].ppPredecessors)memset(apr_palloc(p, nItems*sizeof *pData[n].ppPredecessors), 0, nItems*sizeof *pData[n].ppPredecessors); | |||
92 | pData[n].pNext=NULL((void*)0); | |||
93 | pData[n].pData=&pItems[n]; | |||
94 | } | |||
95 | ||||
96 | for(n=0 ; n < nItems ; ++n) { | |||
97 | int i,k; | |||
98 | ||||
99 | for(i=0 ; pItems[n].aszPredecessors && pItems[n].aszPredecessors[i] ; ++i) | |||
100 | for(k=0 ; k < nItems ; ++k) | |||
101 | if(!strcmp(pItems[k].szName,pItems[n].aszPredecessors[i])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (pItems[k].szName) && __builtin_constant_p (pItems[n ].aszPredecessors[i]) && (__s1_len = __builtin_strlen (pItems[k].szName), __s2_len = __builtin_strlen (pItems[n].aszPredecessors [i]), (!((size_t)(const void *)((pItems[k].szName) + 1) - (size_t )(const void *)(pItems[k].szName) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((pItems[n].aszPredecessors[i]) + 1 ) - (size_t)(const void *)(pItems[n].aszPredecessors[i]) == 1 ) || __s2_len >= 4)) ? __builtin_strcmp (pItems[k].szName, pItems[n].aszPredecessors[i]) : (__builtin_constant_p (pItems [k].szName) && ((size_t)(const void *)((pItems[k].szName ) + 1) - (size_t)(const void *)(pItems[k].szName) == 1) && (__s1_len = __builtin_strlen (pItems[k].szName), __s1_len < 4) ? (__builtin_constant_p (pItems[n].aszPredecessors[i]) && ((size_t)(const void *)((pItems[n].aszPredecessors[i]) + 1) - (size_t)(const void *)(pItems[n].aszPredecessors[i]) == 1) ? __builtin_strcmp (pItems[k].szName, pItems[n].aszPredecessors [i]) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (pItems[n].aszPredecessors[i]); int __result = (((const unsigned char *) (const char *) (pItems[k].szName ))[0] - __s2[0]); if (__s1_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (pItems [k].szName))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( pItems[k].szName))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (pItems[k].szName))[3] - __s2[3]); } } __result; }))) : ( __builtin_constant_p (pItems[n].aszPredecessors[i]) && ((size_t)(const void *)((pItems[n].aszPredecessors[i]) + 1) - (size_t)(const void *)(pItems[n].aszPredecessors[i]) == 1) && (__s2_len = __builtin_strlen (pItems[n].aszPredecessors[i]), __s2_len < 4) ? (__builtin_constant_p (pItems[k].szName) && ((size_t)(const void *)((pItems[k].szName) + 1) - (size_t)(const void *)(pItems[k].szName) == 1) ? __builtin_strcmp (pItems[k ].szName, pItems[n].aszPredecessors[i]) : (- (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (pItems[k].szName); int __result = (((const unsigned char *) (const char *) (pItems[n].aszPredecessors[i]))[0] - __s2[ 0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (pItems[n].aszPredecessors [i]))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (pItems [n].aszPredecessors[i]))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (pItems[n].aszPredecessors[i]))[3] - __s2[3]); } } __result ; })))) : __builtin_strcmp (pItems[k].szName, pItems[n].aszPredecessors [i])))); })) { | |||
102 | int l; | |||
103 | ||||
104 | for(l=0 ; l < pData[n].nPredecessors ; ++l) | |||
105 | if(pData[n].ppPredecessors[l] == &pData[k]) | |||
106 | goto got_it; | |||
107 | pData[n].ppPredecessors[pData[n].nPredecessors]=&pData[k]; | |||
108 | ++pData[n].nPredecessors; | |||
109 | got_it: | |||
110 | break; | |||
111 | } | |||
112 | for(i=0 ; pItems[n].aszSuccessors && pItems[n].aszSuccessors[i] ; ++i) | |||
113 | for(k=0 ; k < nItems ; ++k) | |||
114 | if(!strcmp(pItems[k].szName,pItems[n].aszSuccessors[i])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (pItems[k].szName) && __builtin_constant_p (pItems[n ].aszSuccessors[i]) && (__s1_len = __builtin_strlen ( pItems[k].szName), __s2_len = __builtin_strlen (pItems[n].aszSuccessors [i]), (!((size_t)(const void *)((pItems[k].szName) + 1) - (size_t )(const void *)(pItems[k].szName) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((pItems[n].aszSuccessors[i]) + 1) - (size_t)(const void *)(pItems[n].aszSuccessors[i]) == 1) || __s2_len >= 4)) ? __builtin_strcmp (pItems[k].szName, pItems[n].aszSuccessors [i]) : (__builtin_constant_p (pItems[k].szName) && (( size_t)(const void *)((pItems[k].szName) + 1) - (size_t)(const void *)(pItems[k].szName) == 1) && (__s1_len = __builtin_strlen (pItems[k].szName), __s1_len < 4) ? (__builtin_constant_p (pItems[n].aszSuccessors[i]) && ((size_t)(const void *)((pItems[n].aszSuccessors[i]) + 1) - (size_t)(const void * )(pItems[n].aszSuccessors[i]) == 1) ? __builtin_strcmp (pItems [k].szName, pItems[n].aszSuccessors[i]) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (pItems[n].aszSuccessors[i]); int __result = (((const unsigned char *) (const char *) (pItems[k].szName))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (pItems[k].szName))[1] - __s2 [1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (pItems[k].szName ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (pItems [k].szName))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (pItems[n].aszSuccessors[i]) && ((size_t)(const void *)((pItems[n].aszSuccessors[i]) + 1) - (size_t)(const void * )(pItems[n].aszSuccessors[i]) == 1) && (__s2_len = __builtin_strlen (pItems[n].aszSuccessors[i]), __s2_len < 4) ? (__builtin_constant_p (pItems[k].szName) && ((size_t)(const void *)((pItems [k].szName) + 1) - (size_t)(const void *)(pItems[k].szName) == 1) ? __builtin_strcmp (pItems[k].szName, pItems[n].aszSuccessors [i]) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (pItems[k].szName); int __result = (((const unsigned char *) (const char *) (pItems[n].aszSuccessors [i]))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (pItems [n].aszSuccessors[i]))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (pItems[n].aszSuccessors[i]))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (pItems[n].aszSuccessors[i]))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (pItems[k].szName , pItems[n].aszSuccessors[i])))); })) { | |||
115 | int l; | |||
116 | ||||
117 | for(l=0 ; l < pData[k].nPredecessors ; ++l) | |||
118 | if(pData[k].ppPredecessors[l] == &pData[n]) | |||
119 | goto got_it2; | |||
120 | pData[k].ppPredecessors[pData[k].nPredecessors]=&pData[n]; | |||
121 | ++pData[k].nPredecessors; | |||
122 | got_it2: | |||
123 | break; | |||
124 | } | |||
125 | } | |||
126 | ||||
127 | return pData; | |||
128 | } | |||
129 | ||||
130 | /* Topologically sort, dragging out-of-order items to the front. Note that | |||
131 | this tends to preserve things that want to be near the front better, and | |||
132 | changing that behaviour might compromise some of Apache's behaviour (in | |||
133 | particular, mod_log_forensic might otherwise get pushed to the end, and | |||
134 | core.c's log open function used to end up at the end when pushing items | |||
135 | to the back was the methedology). Also note that the algorithm could | |||
136 | go back to its original simplicity by sorting from the back instead of | |||
137 | the front. | |||
138 | */ | |||
139 | static TSort *tsort(TSort *pData,int nItems) | |||
140 | { | |||
141 | int nTotal; | |||
142 | TSort *pHead=NULL((void*)0); | |||
143 | TSort *pTail=NULL((void*)0); | |||
144 | ||||
145 | for(nTotal=0 ; nTotal < nItems ; ++nTotal) { | |||
146 | int n,i,k; | |||
147 | ||||
148 | for(n=0 ; ; ++n) { | |||
149 | if(n == nItems) | |||
150 | assert(0)((0) ? (void) (0) : __assert_fail ("0", "hooks/apr_hooks.c", 150 , __PRETTY_FUNCTION__)); /* we have a loop... */ | |||
151 | if(!pData[n].pNext) { | |||
152 | if(pData[n].nPredecessors) { | |||
153 | for(k=0 ; ; ++k) { | |||
154 | assert(k < nItems)((k < nItems) ? (void) (0) : __assert_fail ("k < nItems" , "hooks/apr_hooks.c", 154, __PRETTY_FUNCTION__)); | |||
155 | if(pData[n].ppPredecessors[k]) | |||
156 | break; | |||
157 | } | |||
158 | for(i=0 ; ; ++i) { | |||
159 | assert(i < nItems)((i < nItems) ? (void) (0) : __assert_fail ("i < nItems" , "hooks/apr_hooks.c", 159, __PRETTY_FUNCTION__)); | |||
160 | if(&pData[i] == pData[n].ppPredecessors[k]) { | |||
161 | n=i-1; | |||
162 | break; | |||
163 | } | |||
164 | } | |||
165 | } else | |||
166 | break; | |||
167 | } | |||
168 | } | |||
169 | if(pTail) | |||
170 | pTail->pNext=&pData[n]; | |||
171 | else | |||
172 | pHead=&pData[n]; | |||
173 | pTail=&pData[n]; | |||
174 | pTail->pNext=pTail; /* fudge it so it looks linked */ | |||
175 | for(i=0 ; i < nItems ; ++i) | |||
176 | for(k=0 ; k < nItems ; ++k) | |||
177 | if(pData[i].ppPredecessors[k] == &pData[n]) { | |||
178 | --pData[i].nPredecessors; | |||
179 | pData[i].ppPredecessors[k]=NULL((void*)0); | |||
180 | break; | |||
181 | } | |||
182 | } | |||
183 | pTail->pNext=NULL((void*)0); /* unfudge the tail */ | |||
| ||||
184 | return pHead; | |||
185 | } | |||
186 | ||||
187 | static apr_array_header_t *sort_hook(apr_array_header_t *pHooks, | |||
188 | const char *szName) | |||
189 | { | |||
190 | apr_pool_t *p; | |||
191 | TSort *pSort; | |||
192 | apr_array_header_t *pNew; | |||
193 | int n; | |||
194 | ||||
195 | apr_pool_create(&p, apr_hook_global_pool)apr_pool_create_ex(&p, apr_hook_global_pool, ((void*)0), ( (void*)0)); | |||
196 | pSort=prepare(p,(TSortData *)pHooks->elts,pHooks->nelts); | |||
197 | pSort=tsort(pSort,pHooks->nelts); | |||
198 | pNew=apr_array_make(apr_hook_global_pool,pHooks->nelts,sizeof(TSortData)); | |||
199 | if(apr_hook_debug_enabled) | |||
200 | printf("Sorting %s:",szName); | |||
201 | for(n=0 ; pSort ; pSort=pSort->pNext,++n) { | |||
202 | TSortData *pHook; | |||
203 | assert(n < pHooks->nelts)((n < pHooks->nelts) ? (void) (0) : __assert_fail ("n < pHooks->nelts" , "hooks/apr_hooks.c", 203, __PRETTY_FUNCTION__)); | |||
204 | pHook=apr_array_push(pNew); | |||
205 | memcpy(pHook,pSort->pData,sizeof *pHook); | |||
206 | if(apr_hook_debug_enabled) | |||
207 | printf(" %s",pHook->szName); | |||
208 | } | |||
209 | if(apr_hook_debug_enabled) | |||
210 | fputc('\n',stdoutstdout); | |||
211 | return pNew; | |||
212 | } | |||
213 | ||||
214 | #ifndef NETWARE | |||
215 | static apr_array_header_t *s_aHooksToSort; | |||
216 | #endif | |||
217 | ||||
218 | typedef struct | |||
219 | { | |||
220 | const char *szHookName; | |||
221 | apr_array_header_t **paHooks; | |||
222 | } HookSortEntry; | |||
223 | ||||
224 | APU_DECLARE(void)void apr_hook_sort_register(const char *szHookName, | |||
225 | apr_array_header_t **paHooks) | |||
226 | { | |||
227 | #ifdef NETWARE | |||
228 | get_apd | |||
229 | #endif | |||
230 | HookSortEntry *pEntry; | |||
231 | ||||
232 | if(!s_aHooksToSort) | |||
233 | s_aHooksToSort=apr_array_make(apr_hook_global_pool,1,sizeof(HookSortEntry)); | |||
234 | pEntry=apr_array_push(s_aHooksToSort); | |||
235 | pEntry->szHookName=szHookName; | |||
236 | pEntry->paHooks=paHooks; | |||
237 | } | |||
238 | ||||
239 | APU_DECLARE(void)void apr_hook_sort_all(void) | |||
240 | { | |||
241 | #ifdef NETWARE | |||
242 | get_apd | |||
243 | #endif | |||
244 | int n; | |||
245 | ||||
246 | for(n=0 ; n < s_aHooksToSort->nelts ; ++n) { | |||
| ||||
247 | HookSortEntry *pEntry=&((HookSortEntry *)s_aHooksToSort->elts)[n]; | |||
248 | *pEntry->paHooks=sort_hook(*pEntry->paHooks,pEntry->szHookName); | |||
249 | } | |||
250 | } | |||
251 | ||||
252 | #ifndef NETWARE | |||
253 | static apr_hash_t *s_phOptionalHooks; | |||
254 | static apr_hash_t *s_phOptionalFunctions; | |||
255 | #endif | |||
256 | ||||
257 | APU_DECLARE(void)void apr_hook_deregister_all(void) | |||
258 | { | |||
259 | #ifdef NETWARE | |||
260 | get_apd | |||
261 | #endif | |||
262 | int n; | |||
263 | ||||
264 | for(n=0 ; n < s_aHooksToSort->nelts ; ++n) { | |||
265 | HookSortEntry *pEntry=&((HookSortEntry *)s_aHooksToSort->elts)[n]; | |||
266 | *pEntry->paHooks=NULL((void*)0); | |||
267 | } | |||
268 | s_aHooksToSort=NULL((void*)0); | |||
269 | s_phOptionalHooks=NULL((void*)0); | |||
270 | s_phOptionalFunctions=NULL((void*)0); | |||
271 | } | |||
272 | ||||
273 | APU_DECLARE(void)void apr_hook_debug_show(const char *szName, | |||
274 | const char * const *aszPre, | |||
275 | const char * const *aszSucc) | |||
276 | { | |||
277 | int nFirst; | |||
278 | ||||
279 | printf(" Hooked %s",szName); | |||
280 | if(aszPre) { | |||
281 | fputs(" pre(",stdoutstdout); | |||
282 | nFirst=1; | |||
283 | while(*aszPre) { | |||
284 | if(!nFirst) | |||
285 | fputc(',',stdoutstdout); | |||
286 | nFirst=0; | |||
287 | fputs(*aszPre,stdoutstdout); | |||
288 | ++aszPre; | |||
289 | } | |||
290 | fputc(')',stdoutstdout); | |||
291 | } | |||
292 | if(aszSucc) { | |||
293 | fputs(" succ(",stdoutstdout); | |||
294 | nFirst=1; | |||
295 | while(*aszSucc) { | |||
296 | if(!nFirst) | |||
297 | fputc(',',stdoutstdout); | |||
298 | nFirst=0; | |||
299 | fputs(*aszSucc,stdoutstdout); | |||
300 | ++aszSucc; | |||
301 | } | |||
302 | fputc(')',stdoutstdout); | |||
303 | } | |||
304 | fputc('\n',stdoutstdout); | |||
305 | } | |||
306 | ||||
307 | /* Optional hook support */ | |||
308 | ||||
309 | APR_DECLARE_EXTERNAL_HOOK(apr,APU,void,_optional,(void))typedef void apr_HOOK__optional_t (void); void apr_hook__optional (apr_HOOK__optional_t *pf, const char * const *aszPre, const char * const *aszSucc, int nOrder); void apr_run__optional (void) ; apr_array_header_t * apr_hook_get__optional(void); typedef struct apr_LINK__optional_t { apr_HOOK__optional_t *pFunc; const char *szName; const char * const *aszPredecessors; const char * const *aszSuccessors; int nOrder; } apr_LINK__optional_t; | |||
310 | ||||
311 | APU_DECLARE(apr_array_header_t *)apr_array_header_t * apr_optional_hook_get(const char *szName) | |||
312 | { | |||
313 | #ifdef NETWARE | |||
314 | get_apd | |||
315 | #endif | |||
316 | apr_array_header_t **ppArray; | |||
317 | ||||
318 | if(!s_phOptionalHooks) | |||
319 | return NULL((void*)0); | |||
320 | ppArray=apr_hash_get(s_phOptionalHooks,szName,strlen(szName)); | |||
321 | if(!ppArray) | |||
322 | return NULL((void*)0); | |||
323 | return *ppArray; | |||
324 | } | |||
325 | ||||
326 | APU_DECLARE(void)void apr_optional_hook_add(const char *szName,void (*pfn)(void), | |||
327 | const char * const *aszPre, | |||
328 | const char * const *aszSucc,int nOrder) | |||
329 | { | |||
330 | #ifdef NETWARE | |||
331 | get_apd | |||
332 | #endif | |||
333 | apr_array_header_t *pArray=apr_optional_hook_get(szName); | |||
334 | apr_LINK__optional_t *pHook; | |||
335 | ||||
336 | if(!pArray) { | |||
337 | apr_array_header_t **ppArray; | |||
338 | ||||
339 | pArray=apr_array_make(apr_hook_global_pool,1, | |||
340 | sizeof(apr_LINK__optional_t)); | |||
341 | if(!s_phOptionalHooks) | |||
342 | s_phOptionalHooks=apr_hash_make(apr_hook_global_pool); | |||
343 | ppArray=apr_palloc(apr_hook_global_pool,sizeof *ppArray); | |||
344 | *ppArray=pArray; | |||
345 | apr_hash_set(s_phOptionalHooks,szName,strlen(szName),ppArray); | |||
346 | apr_hook_sort_register(szName,ppArray); | |||
347 | } | |||
348 | pHook=apr_array_push(pArray); | |||
349 | pHook->pFunc=pfn; | |||
350 | pHook->aszPredecessors=aszPre; | |||
351 | pHook->aszSuccessors=aszSucc; | |||
352 | pHook->nOrder=nOrder; | |||
353 | pHook->szName=apr_hook_debug_current; | |||
354 | if(apr_hook_debug_enabled) | |||
355 | apr_hook_debug_show(szName,aszPre,aszSucc); | |||
356 | } | |||
357 | ||||
358 | /* optional function support */ | |||
359 | ||||
360 | APU_DECLARE(apr_opt_fn_t *)apr_opt_fn_t * apr_dynamic_fn_retrieve(const char *szName) | |||
361 | { | |||
362 | #ifdef NETWARE | |||
363 | get_apd | |||
364 | #endif | |||
365 | if(!s_phOptionalFunctions) | |||
366 | return NULL((void*)0); | |||
367 | return (void(*)(void))apr_hash_get(s_phOptionalFunctions,szName,strlen(szName)); | |||
368 | } | |||
369 | ||||
370 | /* Deprecated */ | |||
371 | APU_DECLARE_NONSTD(void)void apr_dynamic_fn_register(const char *szName, | |||
372 | apr_opt_fn_t *pfn) | |||
373 | { | |||
374 | #ifdef NETWARE | |||
375 | get_apd | |||
376 | #endif | |||
377 | if(!s_phOptionalFunctions) | |||
378 | s_phOptionalFunctions=apr_hash_make(apr_hook_global_pool); | |||
379 | apr_hash_set(s_phOptionalFunctions,szName,strlen(szName),(void *)pfn); | |||
380 | } | |||
381 | ||||
382 | #if 0 | |||
383 | void main() | |||
384 | { | |||
385 | const char *aszAPre[]={"b","c",NULL((void*)0)}; | |||
386 | const char *aszBPost[]={"a",NULL((void*)0)}; | |||
387 | const char *aszCPost[]={"b",NULL((void*)0)}; | |||
388 | TSortData t1[]= | |||
389 | { | |||
390 | { "a",aszAPre,NULL((void*)0) }, | |||
391 | { "b",NULL((void*)0),aszBPost }, | |||
392 | { "c",NULL((void*)0),aszCPost } | |||
393 | }; | |||
394 | TSort *pResult; | |||
395 | ||||
396 | pResult=prepare(t1,3); | |||
397 | pResult=tsort(pResult,3); | |||
398 | ||||
399 | for( ; pResult ; pResult=pResult->pNext) | |||
400 | printf("%s\n",pResult->pData->szName); | |||
401 | } | |||
402 | #endif |