source: mainline/uspace/app/bdsh/cmds/mknewcmd@ 4c4ddbe9

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4c4ddbe9 was e13fb10, checked in by Tim Post <echo@…>, 17 years ago

Fix bug in mknewcmd (incorrectly prototyping entry points)

  • Property mode set to 100755
File size: 9.0 KB
Line 
1#!/bin/sh
2# Copyright (C) 2008 Tim Post - All Rights Reserved
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions are met:
5#
6# Redistributions of source code must retain the above copyright notice, this
7# list of conditions and the following disclaimer.
8#
9# Redistributions in binary form must reproduce the above copyright notice,
10# this list of conditions and the following disclaimer in the documentation
11# and/or other materials provided with the distribution.
12#
13# Neither the name of the original program's authors nor the names of its
14# contributors may be used to endorse or promote products derived from this
15# software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27# POSSIBILITY OF SUCH DAMAGE.
28
29# Script to generate skeletal files for a new command
30# Uses `getopt', not quite a bash-ism but might be
31# lacking on some legacy systems.
32
33# If your shell does not support eval, shift (x) or
34# here-now documents, sorry :)
35
36usage()
37{
38 def="$DEFAULT_COMMAND"
39 cat << EOF
40\`$PROGNAME' generates skeletal command files to simplify adding commands
41Usage: $PROGNAME [options] <location>
42Options:
43 -n, --name Name of the command (default: ${def})
44 -d, --desc Short (20 30 chars) description of the command
45 (def: "The $def command")
46 -e, --entry Entry function of the command (def: cmd_${def})
47 -h, --help-entry Entry function for command help (def: help_cmd_${def})
48 -a, --alias Alias (nickname) for this command (def: none)
49 -r, --restrict Restriction level (interactive, non-interactive, both)
50 (def: module is both, builtin is interactive only)
51 -t, --type Type of command (module or builtin) (def: module)
52 -H, --help This help summary
53 -V, --version Print $PROGNAME version and exit normally
54
55Notes:
56 You must supply at least the name of the command.
57
58 If you do not specify a location (i.e. modules/foo), the command will be
59 created in modules/command_name or builtins/command_name depending on your
60 selection.
61
62 This script will only create skeletal files and inform you what headers
63 need to be modified to incorporate the command. You will also have to
64 manually update the main Makefile.
65
66 This script is intended only to be a convenience for developers. Example use:
67 $PROGNAME -n foo -d "Foo power" -a bar -r both -t module modules/foo
68
69 The example would generate a modular command named 'foo', which is also
70 reached by typing 'bar' and available in either interactive or noninteractive
71 mode.
72
73 Skeletal files do *not* depend on the autoconf generated "config.h" unless you
74 include it. This may or may not be desirable depending on your use.
75
76Report bugs to $PROGMAINT
77
78EOF
79}
80
81# Convert a string to all uppercase
82toupper()
83{
84 local str="$1"
85
86 echo "${str}" | tr 'a-z' 'A-Z'
87}
88
89# Template stored `here-now' style, this generates all files needed
90# for a new command according to arguments passed.
91generate_code()
92{
93 echo "Creating ${OUTDIR}/${CMDNAME}_def.h ..."
94 cat << EOF > ${OUTDIR}/${CMDNAME}_def.h
95{
96 "${CMDNAME}",
97 "${CMDDESC}",
98 &${CMDENTRY},
99 &${HELPENTRY},
100 ${CMDRESTRICT}
101},
102
103EOF
104 [ -n "${CMDALIAS}" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}_def.h
105{
106 "${CMDALIAS}",
107 NULL,
108 &${CMDENTRY},
109 &${HELPENTRY},
110 ${CMDRESTRICT}
111},
112
113EOF
114 local defname=$(toupper "${CMDNAME}")
115 echo "Creating ${OUTDIR}/entry.h ..."
116 cat << EOF > ${OUTDIR}/entry.h
117#ifndef ${defname}_ENTRY_H
118#define ${defname}_ENTRY_H
119
120EOF
121 [ "${CMDTYPE}" = "module" ] && cat << EOF >> ${OUTDIR}/entry.h
122/* Entry points for the ${CMDNAME} command */
123extern int ${CMDENTRY}(char **);
124extern void ${HELPENTRY}(unsigned int);
125
126#endif /* ${defname}_ENTRY_H */
127
128EOF
129 [ "${CMDTYPE}" = "builtin" ] && cat << EOF >> ${OUTDIR}/entry.h
130/* Pick up cliuser_t */
131#include "scli.h"
132
133/* Entry points for the ${CMDNAME} command */
134extern int * ${CMDENTRY}(char **, cliuser_t *);
135extern void * ${HELPENTRY}(unsigned int);
136
137#endif /* ${defname}_ENTRY_H */
138
139EOF
140 echo "Creating ${OUTDIR}/${CMDNAME}.h ..."
141 cat << EOF > ${OUTDIR}/${CMDNAME}.h
142#ifndef ${defname}_H
143#define ${defname}_H
144
145/* Prototypes for the ${CMDNAME} command, excluding entry points */
146
147
148#endif /* ${defname}_H */
149
150EOF
151 echo "Creating ${OUTDIR}/${CMDNAME}.c ..."
152 cat << EOF > ${OUTDIR}/${CMDNAME}.c
153/* Automatically generated by ${PROGNAME} on ${TIMESTAMP}
154 * This is machine generated output. The author of ${PROGNAME} claims no
155 * copyright over the contents of this file. Where legally permitted, the
156 * contents herein are donated to the public domain.
157 *
158 * You should apply any license and copyright that you wish to this file,
159 * replacing this header in its entirety. */
160
161#include <stdio.h>
162#include <stdlib.h>
163#include "config.h"
164#include "util.h"
165#include "errors.h"
166#include "entry.h"
167#include "${CMDNAME}.h"
168#include "cmds.h"
169
170static char *cmdname = "${CMDNAME}";
171
172/* Dispays help for ${CMDNAME} in various levels */
173void ${HELPENTRY}(unsigned int level)
174{
175 printf("This is the %s help for '%s'.\n",
176 level ? EXT_HELP : SHORT_HELP, cmdname);
177 return;
178}
179
180EOF
181 [ "${CMDTYPE}" = "module" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}.c
182/* Main entry point for ${CMDNAME}, accepts an array of arguments */
183int ${CMDENTRY}(char **argv)
184EOF
185 [ "${CMDTYPE}" = "builtin" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}.c
186/* Main entry point for ${CMDNAME}, accepts an array of arguments and a
187 * pointer to the cliuser_t structure */
188int ${CMDENTRY}(char **argv, cliuser_t *usr)
189EOF
190 cat << EOF >> ${OUTDIR}/${CMDNAME}.c
191{
192 unsigned int argc;
193 unsigned int i;
194
195 /* Count the arguments */
196 for (argc = 0; argv[argc] != NULL; argc ++);
197
198 printf("%s %s\n", TEST_ANNOUNCE, cmdname);
199 printf("%d arguments passed to %s", argc - 1, cmdname);
200
201 if (argc < 2) {
202 printf("\n");
203 return CMD_SUCCESS;
204 }
205
206 printf(":\n");
207 for (i = 1; i < argc; i++)
208 printf("[%d] -> %s\n", i, argv[i]);
209
210 return CMD_SUCCESS;
211}
212
213EOF
214 printf "Done.\n\nYou should now modify %ss/%ss.h and ../Makefile" \
215 "${CMDTYPE}" "${CMDTYPE}"
216 printf " to include your new command.\n"
217 [ -n "$CMDALIAS" ] && {
218 printf "\nYou should also modify %ss/%s_aliases.h and " \
219 "${CMDTYPE}" "${CMDTYPE}"
220 printf "add %s as an alias for %s\n" \
221 "${CMDALIAS}" "${CMDNAME}"
222 }
223 printf "\nOnce completed, re-run make\n\n"
224}
225
226# Main program
227
228TIMESTAMP="$(date)"
229PROGNAME=$(basename $0)
230PROGVER="0.0.1"
231PROGMAINT="Tim Post <echo@echoreply.us>"
232DEFAULT_COMMAND="cmdname"
233
234# We need at least one
235[ $# = 0 ] && usage && exit 1;
236
237TEMP=$(getopt -o n:d:e:h:a:r:t:HV \
238--long name:,desc:,entry:,help-entry:,alias:,restrict:,type:,help,version \
239-- "$@") || {
240 echo "Try $PROGNAME --help for help"
241}
242
243eval set -- "$TEMP"
244
245while true; do
246 case "$1" in
247 -n | --name)
248 CMDNAME="$2"
249 shift 2
250 continue
251 ;;
252 -d | --desc)
253 CMDDESC="$2"
254 shift 2
255 continue
256 ;;
257 -e | --entry)
258 CMDENTRY="$2"
259 shift 2
260 continue
261 ;;
262 -h | --help-entry)
263 HELPENTRY="$2"
264 shift 2
265 continue
266 ;;
267 -a | --alias)
268 CMDALIAS="$2"
269 shift 2
270 continue
271 ;;
272 -r | --restrict)
273 CMDRESTRICT="$2"
274 shift 2
275 continue
276 ;;
277 -t | --type)
278 CMDTYPE="$2"
279 shift 2
280 continue
281 ;;
282 -H | --help)
283 usage
284 exit 0
285 ;;
286 -V | --version)
287 echo "$PROGVER"
288 exit 0
289 ;;
290 --)
291 break
292 ;;
293 esac
294done
295
296# Pick up a location if one was specified
297eval set -- "$*"
298[ -n "$2" ] && OUTDIR="$2"
299
300# Fill in defaults for whatever was not specified
301[ -n "$CMDNAME" ] || CMDNAME="$DEFAULT_COMMAND"
302[ -n "$CMDDESC" ] || CMDDESC="The $CMDNAME command"
303[ -n "$CMDENTRY" ] || CMDENTRY="cmd_${CMDNAME}"
304[ -n "$HELPENTRY" ] || HELPENTRY="help_cmd_${CMDNAME}"
305[ -n "$CMDTYPE" ] || CMDTYPE="module"
306[ -n "$OUTDIR" ] || OUTDIR="${CMDTYPE}s/${CMDNAME}"
307
308# Builtins typically only need to be available in interactive mode,
309# set the default accordingly.
310[ -n "$CMDRESTRICT" ] || {
311 [ "$CMDTYPE" = "module" ] && CMDRESTRICT="both"
312 [ "$CMDTYPE" = "builtin" ] && CMDRESTRICT="interactive"
313}
314
315# Set the restriction level as the structure expects to see it
316case "$CMDRESTRICT" in
317 0 | both)
318 CMDRESTRICT="0"
319 ;;
320 1 | non-interactive)
321 CMDRESTRICT="1"
322 ;;
323 -1 | interactive)
324 CMDRESTRICT="-1"
325 ;;
326 *)
327 usage
328 exit 1
329 ;;
330esac
331
332# Do a little sanity
333[ -d $OUTDIR ] && {
334 echo "$OUTDIR already exists, remove it to proceed."
335 exit 1
336}
337
338mkdir -p ${OUTDIR} >/dev/null 2>&1 || {
339 echo "Could not create ${OUTDIR}, aborting!"
340 exit 1
341}
342
343# Generate the files and inform on how to include them based on options
344generate_code
345
346exit 0
347
Note: See TracBrowser for help on using the repository browser.