]>
code.delx.au - gnu-emacs/blob - modules/modhelp.py
3 # Module helper script.
5 # Copyright 2015 Free Software Foundation, Inc.
7 # This file is part of GNU Emacs.
9 # GNU Emacs is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
14 # GNU Emacs is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
24 import subprocess
as sp
28 EMACS
= os
.path
.join('..', 'src', 'emacs')
32 for (dirname
, dirs
, files
) in os
.walk('.'):
33 if 'Makefile' in files
:
34 modpaths
.append(dirname
)
48 print '[*] %s: ------- start -------' % m
49 print '[*] %s: running make' % m
50 r
= sp
.call(make_cmd
, cwd
=m
)
52 print '[E] %s: make failed' % m
56 print '[*] %s: running test' % m
57 testpath
= os
.path
.join(m
, 'test.el')
58 if os
.path
.isfile(testpath
):
59 emacs_cmd
= [EMACS
, '-batch', '-L', '.', '-l', 'ert', '-l', testpath
, '-f', 'ert-run-tests-batch-and-exit']
60 print ' '.join(emacs_cmd
)
61 r
= sp
.call(emacs_cmd
)
63 print '[E] %s: test failed' % m
67 print '[W] %s: no test to run' % m
69 print '\n[*] %d/%d MODULES OK' % (len(mods
)-len(failed
), len(mods
))
71 print '\tfailed: %s' % m
74 sym
= re
.sub('[_ ]', '-', sym
)
78 sym
= re
.sub('[- ]', '_', sym
)
82 if os
.path
.exists(args
.module
):
83 print "%s: file/dir '%s' already exists" % (__file__
, args
.module
)
89 'module': args
.module
,
91 'c_file': '%s.c' % args
.module
,
92 'c_func': 'F%s_%s' % (to_c_sym(args
.module
), to_c_sym(args
.fun
)),
93 'lisp_func': '%s-%s' % (args
.module
, to_lisp_sym(args
.fun
)),
96 for path
, t
in TEMPLATES
.items():
97 if isinstance(path
, string
.Template
):
98 path
= path
.substitute(template_vars
)
99 path
= os
.path
.join(args
.module
, path
)
100 print "writing %s..." % path
101 with
open(path
, "w+") as f
:
102 f
.write(t
.substitute(template_vars
))
103 print "done! you can run %s test %s" % (__file__
, args
.module
)
107 # path always written relative to this file
108 os
.chdir(os
.path
.dirname(os
.path
.realpath(__file__
)))
110 mainp
= argparse
.ArgumentParser()
111 subp
= mainp
.add_subparsers()
113 testp
= subp
.add_parser('test', help='run tests')
114 testp
.add_argument('-f', '--force', action
='store_true', help='force regeneration (make -B)')
115 testp
.add_argument('module', nargs
='*', help='path to module to test (default all)')
116 testp
.set_defaults(func
=cmd_test
)
118 initp
= subp
.add_parser('init', help='create a test module from a template')
119 initp
.add_argument('module', help='name of the new module')
120 initp
.add_argument('-f', '--fun', default
='fun', help='overide name of the default function')
121 initp
.set_defaults(func
=cmd_init
)
123 args
= mainp
.parse_args()
127 # double the $ to escape python template syntax
129 'Makefile': string
.Template('''
134 CFLAGS = -ggdb3 -Wall
137 all: ${module}.so ${module}.doc
140 $$(LD) -shared $$(LDFLAGS) -o $$@ $$<
143 $$(CC) $$(CFLAGS) -I$$(ROOT)/src -fPIC -c $$<
147 string
.Template('${c_file}'): string
.Template('''
150 int plugin_is_GPL_compatible;
152 static emacs_value ${c_func} (emacs_env *env, int nargs, emacs_value args[], void *data)
154 return env->intern (env, "t");
157 /* Binds NAME to FUN */
158 static void bind_function (emacs_env *env, const char *name, emacs_value Sfun)
160 emacs_value Qfset = env->intern (env, "fset");
161 emacs_value Qsym = env->intern (env, name);
162 emacs_value args[] = { Qsym, Sfun };
164 env->funcall (env, Qfset, 2, args);
167 /* Provide FEATURE to Emacs */
168 static void provide (emacs_env *env, const char *feature)
170 emacs_value Qfeat = env->intern (env, feature);
171 emacs_value Qprovide = env->intern (env, "provide");
172 emacs_value args[] = { Qfeat };
174 env->funcall (env, Qprovide, 1, args);
177 int emacs_module_init (struct emacs_runtime *ert)
179 emacs_env *env = ert->get_environment (ert);
180 bind_function (env, "${lisp_func}", env->make_function (env, 1, 1, ${c_func}, "doc", NULL));
181 provide (env, "${module}");
185 'test.el': string
.Template('''
187 (require 'module-test-common)
189 ;; #$$ works when loading, buffer-file-name when evaluating from emacs
190 (module-load (module-path (or #$$ (expand-file-name (buffer-file-name)))))
192 (ert-deftest ${lisp_func}-test ()
193 (should (eq (${lisp_func} 42) t)))
197 if __name__
== '__main__':