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