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