1 /*
2 ******************************************************************************
3 *
4 *   Copyright (C) 2009-2015, International Business Machines
5 *   Corporation and others.  All Rights Reserved.
6 *
7 ******************************************************************************
8 *
9 *  FILE NAME : testplug.c
10 *
11 *   Date         Name        Description
12 *   10/29/2009   srl          New.
13 ******************************************************************************
14 *
15 *
16 * This file implements a number of example ICU plugins.
17 *
18 */
19 
20 #include "unicode/icuplug.h"
21 
22 #if UCONFIG_ENABLE_PLUGINS
23 /* This file isn't usually compiled except on Windows. Guard it. */
24 
25 #include <stdio.h> /* for fprintf */
26 #include <stdlib.h> /* for malloc */
27 #include "udbgutil.h"
28 #include "unicode/uclean.h"
29 #include "cmemory.h"
30 
31 /**
32  * Prototypes
33  */
34 #define DECLARE_PLUGIN(x) U_CAPI UPlugTokenReturn U_EXPORT2 x (UPlugData *data, UPlugReason reason, UErrorCode *status)
35 
36 DECLARE_PLUGIN(myPlugin);
37 DECLARE_PLUGIN(myPluginLow);
38 DECLARE_PLUGIN(myPluginFailQuery);
39 DECLARE_PLUGIN(myPluginFailToken);
40 DECLARE_PLUGIN(myPluginBad);
41 DECLARE_PLUGIN(myPluginHigh);
42 DECLARE_PLUGIN(debugMemoryPlugin);
43 
44 /**
45  * A simple, trivial plugin.
46  */
47 
48 U_CAPI
myPlugin(UPlugData * data,UPlugReason reason,UErrorCode * status)49 UPlugTokenReturn U_EXPORT2 myPlugin (
50                   UPlugData *data,
51                   UPlugReason reason,
52                   UErrorCode *status) {
53 	/* Just print this for debugging */
54     fprintf(stderr,"MyPlugin: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
55 
56     if(reason==UPLUG_REASON_QUERY) {
57         uplug_setPlugName(data, "Just a Test High-Level Plugin"); /* This call is optional in response to UPLUG_REASON_QUERY, but is a good idea. */
58         uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH); /* This call is Mandatory in response to UPLUG_REASON_QUERY */
59     }
60 
61     return UPLUG_TOKEN; /* This must always be returned, to indicate that the entrypoint was actually a plugin. */
62 }
63 
64 
65 U_CAPI
myPluginLow(UPlugData * data,UPlugReason reason,UErrorCode * status)66 UPlugTokenReturn U_EXPORT2 myPluginLow (
67                   UPlugData *data,
68                   UPlugReason reason,
69                   UErrorCode *status) {
70     fprintf(stderr,"MyPluginLow: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
71 
72     if(reason==UPLUG_REASON_QUERY) {
73         uplug_setPlugName(data, "Low Plugin");
74         uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
75     }
76 
77     return UPLUG_TOKEN;
78 }
79 
80 /**
81  * Doesn't respond to QUERY properly.
82  */
83 U_CAPI
myPluginFailQuery(UPlugData * data,UPlugReason reason,UErrorCode * status)84 UPlugTokenReturn U_EXPORT2 myPluginFailQuery (
85                   UPlugData *data,
86                   UPlugReason reason,
87                   UErrorCode *status) {
88     fprintf(stderr,"MyPluginFailQuery: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
89 
90 	/* Should respond to UPLUG_REASON_QUERY here. */
91 
92     return UPLUG_TOKEN;
93 }
94 
95 /**
96  * Doesn't return the proper token.
97  */
98 U_CAPI
myPluginFailToken(UPlugData * data,UPlugReason reason,UErrorCode * status)99 UPlugTokenReturn U_EXPORT2 myPluginFailToken (
100                   UPlugData *data,
101                   UPlugReason reason,
102                   UErrorCode *status) {
103     fprintf(stderr,"MyPluginFailToken: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
104 
105     if(reason==UPLUG_REASON_QUERY) {
106         uplug_setPlugName(data, "myPluginFailToken Plugin");
107         uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
108     }
109 
110     return 0; /* Wrong. */
111 }
112 
113 
114 
115 /**
116  * Says it's low, but isn't.
117  */
118 U_CAPI
myPluginBad(UPlugData * data,UPlugReason reason,UErrorCode * status)119 UPlugTokenReturn U_EXPORT2 myPluginBad (
120                   UPlugData *data,
121                   UPlugReason reason,
122                   UErrorCode *status) {
123     fprintf(stderr,"MyPluginLow: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
124 
125     if(reason==UPLUG_REASON_QUERY) {
126         uplug_setPlugName(data, "Bad Plugin");
127         uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
128     } else if(reason == UPLUG_REASON_LOAD) {
129         void *ctx = uprv_malloc(12345);
130 
131         uplug_setContext(data, ctx);
132         fprintf(stderr,"I'm %p and I did a bad thing and malloced %p\n", (void*)data, (void*)ctx);
133     } else if(reason == UPLUG_REASON_UNLOAD) {
134         void * ctx = uplug_getContext(data);
135 
136         uprv_free(ctx);
137     }
138 
139 
140     return UPLUG_TOKEN;
141 }
142 
143 U_CAPI
myPluginHigh(UPlugData * data,UPlugReason reason,UErrorCode * status)144 UPlugTokenReturn U_EXPORT2 myPluginHigh (
145                   UPlugData *data,
146                   UPlugReason reason,
147                   UErrorCode *status) {
148     fprintf(stderr,"MyPluginHigh: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
149 
150     if(reason==UPLUG_REASON_QUERY) {
151         uplug_setPlugName(data, "High Plugin");
152         uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH);
153     }
154 
155     return UPLUG_TOKEN;
156 }
157 
158 
159 /*  Debug Memory Plugin (see hpmufn.c) */
myMemAlloc(const void * context,size_t size)160 static void * U_CALLCONV myMemAlloc(const void *context, size_t size) {
161   void *retPtr = (void *)malloc(size);
162   (void)context; /* unused */
163   fprintf(stderr, "MEM: malloc(%d) = %p\n", (int32_t)size, retPtr);
164   return retPtr;
165 }
166 
myMemFree(const void * context,void * mem)167 static void U_CALLCONV myMemFree(const void *context, void *mem) {
168   (void)context; /* unused */
169 
170   free(mem);
171   fprintf(stderr, "MEM: free(%p)\n", mem);
172 }
173 
myMemRealloc(const void * context,void * mem,size_t size)174 static void * U_CALLCONV myMemRealloc(const void *context, void *mem, size_t size) {
175     void *retPtr;
176     (void)context; /* unused */
177 
178 
179     if(mem==NULL) {
180         retPtr = NULL;
181     } else {
182         retPtr = realloc(mem, size);
183     }
184     fprintf(stderr, "MEM: realloc(%p, %d) = %p\n", mem, (int32_t)size, retPtr);
185     return retPtr;
186 }
187 
188 U_CAPI
debugMemoryPlugin(UPlugData * data,UPlugReason reason,UErrorCode * status)189 UPlugTokenReturn U_EXPORT2 debugMemoryPlugin (
190                   UPlugData *data,
191                   UPlugReason reason,
192                   UErrorCode *status) {
193     fprintf(stderr,"debugMemoryPlugin: data=%p, reason=%s, status=%s\n", (void*)data, udbg_enumName(UDBG_UPlugReason,(int32_t)reason), u_errorName(*status));
194 
195     if(reason==UPLUG_REASON_QUERY) {
196         uplug_setPlugLevel(data, UPLUG_LEVEL_LOW);
197         uplug_setPlugName(data, "Memory Plugin");
198     } else if(reason==UPLUG_REASON_LOAD) {
199         u_setMemoryFunctions(uplug_getContext(data), &myMemAlloc, &myMemRealloc, &myMemFree, status);
200         fprintf(stderr, "MEM: status now %s\n", u_errorName(*status));
201     } else if(reason==UPLUG_REASON_UNLOAD) {
202         fprintf(stderr, "MEM: not possible to unload this plugin (no way to reset memory functions)...\n");
203         uplug_setPlugNoUnload(data, TRUE);
204     }
205 
206     return UPLUG_TOKEN;
207 }
208 
209 #endif
210