1/*
2 * example.c - an example module for zsh
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 1996-1997 Zoltán Hidvégi
7 * All rights reserved.
8 *
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
14 *
15 * In no event shall Zoltán Hidvégi or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Zoltán Hidvégi and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Zoltán Hidvégi and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose.  The software
24 * provided hereunder is on an "as is" basis, and Zoltán Hidvégi and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 *
28 */
29
30#include "example.mdh"
31#include "example.pro"
32
33/* parameters */
34
35static zlong intparam;
36static char *strparam;
37static char **arrparam;
38
39
40/**/
41static int
42bin_example(char *nam, char **args, Options ops, UNUSED(int func))
43{
44    unsigned char c;
45    char **oargs = args, **p = arrparam;
46    long i = 0;
47
48    printf("Options: ");
49    for (c = 32; ++c < 128;)
50	if (OPT_ISSET(ops,c))
51	    putchar(c);
52    printf("\nArguments:");
53    for (; *args; i++, args++) {
54	putchar(' ');
55	fputs(*args, stdout);
56    }
57    printf("\nName: %s\n", nam);
58#ifdef ZSH_64_BIT_TYPE
59    printf("\nInteger Parameter: %s\n", output64(intparam));
60#else
61    printf("\nInteger Parameter: %ld\n", intparam);
62#endif
63    printf("String Parameter: %s\n", strparam ? strparam : "");
64    printf("Array Parameter:");
65    if (p)
66	while (*p) printf(" %s", *p++);
67    printf("\n");
68
69    intparam = i;
70    zsfree(strparam);
71    strparam = ztrdup(*oargs ? *oargs : "");
72    freearray(arrparam);
73    arrparam = zarrdup(oargs);
74    return 0;
75}
76
77/**/
78static int
79cond_p_len(char **a, UNUSED(int id))
80{
81    char *s1 = cond_str(a, 0, 0);
82
83    if (a[1]) {
84	zlong v = cond_val(a, 1);
85
86	return strlen(s1) == v;
87    } else {
88	return !s1[0];
89    }
90}
91
92/**/
93static int
94cond_i_ex(char **a, UNUSED(int id))
95{
96    char *s1 = cond_str(a, 0, 0), *s2 = cond_str(a, 1, 0);
97
98    return !strcmp("example", dyncat(s1, s2));
99}
100
101/**/
102static mnumber
103math_sum(UNUSED(char *name), int argc, mnumber *argv, UNUSED(int id))
104{
105    mnumber ret;
106    int f = 0;
107
108    ret.u.l = 0;
109    while (argc--) {
110	if (argv->type == MN_INTEGER) {
111	    if (f)
112		ret.u.d += (double) argv->u.l;
113	    else
114		ret.u.l += argv->u.l;
115	} else {
116	    if (f)
117		ret.u.d += argv->u.d;
118	    else {
119		ret.u.d = ((double) ret.u.l) + ((double) argv->u.d);
120		f = 1;
121	    }
122	}
123	argv++;
124    }
125    ret.type = (f ? MN_FLOAT : MN_INTEGER);
126
127    return ret;
128}
129
130/**/
131static mnumber
132math_length(UNUSED(char *name), char *arg, UNUSED(int id))
133{
134    mnumber ret;
135
136    ret.type = MN_INTEGER;
137    ret.u.l = strlen(arg);
138
139    return ret;
140}
141
142/**/
143static int
144ex_wrapper(Eprog prog, FuncWrap w, char *name)
145{
146    if (strncmp(name, "example", 7))
147	return 1;
148    else {
149	int ogd = opts[GLOBDOTS];
150
151	opts[GLOBDOTS] = 1;
152	runshfunc(prog, w, name);
153	opts[GLOBDOTS] = ogd;
154
155	return 0;
156    }
157}
158
159/*
160 * boot_ is executed when the module is loaded.
161 */
162
163static struct builtin bintab[] = {
164    BUILTIN("example", 0, bin_example, 0, -1, 0, "flags", NULL),
165};
166
167static struct conddef cotab[] = {
168    CONDDEF("ex", CONDF_INFIX, cond_i_ex, 0, 0, 0),
169    CONDDEF("len", 0, cond_p_len, 1, 2, 0),
170};
171
172static struct paramdef patab[] = {
173    ARRPARAMDEF("exarr", &arrparam),
174    INTPARAMDEF("exint", &intparam),
175    STRPARAMDEF("exstr", &strparam),
176};
177
178static struct mathfunc mftab[] = {
179    STRMATHFUNC("length", math_length, 0),
180    NUMMATHFUNC("sum", math_sum, 1, -1, 0),
181};
182
183static struct funcwrap wrapper[] = {
184    WRAPDEF(ex_wrapper),
185};
186
187static struct features module_features = {
188    bintab, sizeof(bintab)/sizeof(*bintab),
189    cotab, sizeof(cotab)/sizeof(*cotab),
190    mftab, sizeof(mftab)/sizeof(*mftab),
191    patab, sizeof(patab)/sizeof(*patab),
192    0
193};
194
195/**/
196int
197setup_(UNUSED(Module m))
198{
199    printf("The example module has now been set up.\n");
200    fflush(stdout);
201    return 0;
202}
203
204/**/
205int
206features_(Module m, char ***features)
207{
208    *features = featuresarray(m, &module_features);
209    return 0;
210}
211
212/**/
213int
214enables_(Module m, int **enables)
215{
216    return handlefeatures(m, &module_features, enables);
217}
218
219/**/
220int
221boot_(Module m)
222{
223    intparam = 42;
224    strparam = ztrdup("example");
225    arrparam = (char **) zalloc(3 * sizeof(char *));
226    arrparam[0] = ztrdup("example");
227    arrparam[1] = ztrdup("array");
228    arrparam[2] = NULL;
229    return addwrapper(m, wrapper);
230}
231
232/**/
233int
234cleanup_(Module m)
235{
236    deletewrapper(m, wrapper);
237    return setfeatureenables(m, &module_features, NULL);
238}
239
240/**/
241int
242finish_(UNUSED(Module m))
243{
244    printf("Thank you for using the example module.  Have a nice day.\n");
245    fflush(stdout);
246    return 0;
247}
248