+ rmake ruby script
[opsoft.git] / silentbob / plugins / plugin_compile.cxx
blob93614b1dda293c451eb98b17df9d94b1735903eb
1 /*
2 * (c) Oleg Puchinin 2006
3 * graycardinalster@gmail.com
5 */
7 #include <gclib/gclib.h>
8 #include <sys/wait.h>
9 #include <mod.h>
10 #include <head.h>
11 #include <dbg.h>
13 extern "C" DArray * plugin_init (struct env_t *env);
14 struct env_t *ENV;
15 EHash * __hv_compile_env;
16 bool __cc_script;
17 bool __compile_env;
18 char * __cc_shared;
19 char * __cc_program;
21 void __aa (EArray * a, DArray * b)
23 int count;
24 int i;
26 if (! a || ! b)
27 return;
29 count = b->get_size ();
30 for (i = 0; i < count; ++i)
31 a->add (strdup (LPCHAR (b->get (i))));
34 void __astr (EArray * a, char *str)
36 DArray * d_split;
38 if (! a || ! str)
39 return;
41 d_split = Dsplit (str, (char *) " ");
42 if (! d_split)
43 return;
45 __aa (a, d_split);
46 d_split->foreach (free);
47 delete d_split;
50 void __array_log (EArray * a)
52 int i;
53 if (! a)
54 return;
55 for (i = 0; i < a->get_size (); ++i) {
56 if (a->get (i))
57 printf ("%s ", a->get (i));
59 printf ("\n");
62 int compile_cppfile (char * name)
64 int pid;
65 int status;
66 char * oname = name2obj (name);
67 EArray * d_param;
69 if (! oname)
70 return -1;
72 if (__cc_script) {
73 printf ("$CXX $CXXFLAGS $OPTS $INCLUDE -c -o %s %s\n", oname, name);
74 return 0;
77 d_param = new EArray(32);
78 d_param->add ( (*__hv_compile_env)["CXX"] );
79 __astr (d_param, (*__hv_compile_env)["CXXFLAGS"]);
80 if (strlen ((*__hv_compile_env)["OPTS"]))
81 __astr (d_param, (*__hv_compile_env)["OPTS"]);
82 if (strlen ((*__hv_compile_env)["INCLUDE"]))
83 __astr (d_param, (*__hv_compile_env)["INCLUDE"]);
85 *d_param << (char *) "-c" << (char *) "-o" << oname << name << NULL;
87 if (SB_FLGET (SB_FLVERBOSE))
88 __array_log (d_param);
89 else
90 printf ("\tCXX\t%s\n", oname);
92 pid = fork ();
93 if (pid == 0)
94 execvp ((*__hv_compile_env)["CXX"], d_param->get_skeleton ());
95 else
96 waitpid (pid, &status, 0);
98 free (oname);
99 return 0;
102 int compile_cfile (char * name)
104 char * oname = name2obj (name);
105 EArray * d_param;
106 int status;
107 int pid;
109 if (! oname)
110 return -1;
112 if (__cc_script) {
113 printf ("$CC $CFLAGS $OPTS $INCLUDE -c -o %s %s\n", oname, name);
114 return 0;
117 d_param = new EArray(32);
118 *d_param << (*__hv_compile_env)["CC"];
119 __astr (d_param, (*__hv_compile_env)["CFLAGS"]);
120 if (strlen ((*__hv_compile_env)["OPTS"]))
121 __astr (d_param, (*__hv_compile_env)["OPTS"]);
122 if (strlen ( (*__hv_compile_env)["INCLUDE"] ))
123 __astr (d_param, (*__hv_compile_env)["INCLUDE"]);
125 *d_param << (char *) "-c" << (char *) "-o" << oname << name << NULL;
127 if (SB_FLGET (SB_FLVERBOSE))
128 __array_log (d_param);
129 else
130 printf ("\tCC\t%s\n", oname);
132 pid = fork ();
133 if (pid == 0)
134 execvp ((*__hv_compile_env)["CC"], d_param->get_skeleton ());
135 else
136 waitpid (pid, &status, 0);
138 free (oname);
139 return 0;
142 int __cc_build_target ()
144 EArray * cmd;
145 int status;
146 char * oname;
147 int count;
148 pid_t pid;
149 int i;
151 count = ENV->d_files->get_size ();
152 cmd = new EArray (ENV->d_files->get_size ()+32);
153 *cmd << (*__hv_compile_env)["CC"];
155 if (! __cc_script) {
156 __astr (cmd, (*__hv_compile_env)["LDFLAGS"]);
157 __astr (cmd, (*__hv_compile_env)["LIBS"]);
158 } else {
159 *cmd << (char *) "$LDFLAGS";
160 *cmd << (char *) "$LIBS";
163 if (__cc_shared)
164 *cmd << (char *) "-shared";
166 for (i = 0; i < count; ++i)
167 cmd->add (name2obj (ENV->d_files->get (i)));
169 if (__cc_shared && __cc_program) {
170 fprintf (stderr, "only one --program or --shared option can be used,\n");
171 exit (1);
174 *cmd << (char *) "-o";
175 if (__cc_shared)
176 oname = __cc_shared;
177 else
178 oname = __cc_program;
180 *cmd << oname;
181 *cmd << LPCHAR(NULL);
183 if (__cc_script || SB_FLGET (SB_FLVERBOSE)) {
184 __array_log (cmd);
185 return 0;
186 } else
187 printf ("\tLD\t%s\n", oname);
189 pid = fork ();
190 if (pid < 0)
191 return -1;
193 if (pid == 0)
194 execvp ((*cmd)[0], cmd->get_skeleton ());
195 else
196 waitpid (pid, &status, 0);
198 return 0;
201 int compile_files ()
203 char *S;
204 char opts_buf[256];
205 int count;
206 int i;
208 opts_buf[0] = '\0';
209 if (__cc_shared && ! strstr ((*__hv_compile_env)["OPTS"], "-fPIC")) {
210 strcpy (opts_buf, "-fPIC -DPIC");
211 strcat (opts_buf, (*__hv_compile_env)["OPTS"]);
212 free ((*__hv_compile_env)["OPTS"]);
213 __hv_compile_env->set ((char *) "OPTS", opts_buf);
216 if (__compile_env) {
217 printf ("export CC=\"%s\"\n", (*__hv_compile_env)["CC"]);
218 printf ("export CXX=\"%s\"\n", (*__hv_compile_env)["CXX"]);
219 printf ("export CFLAGS=\"%s\"\n", (*__hv_compile_env)["CFLAGS"]);
220 printf ("export CXXFLAGS=\"%s\"\n", (*__hv_compile_env)["CXXFLAGS"]);
221 printf ("export INCLUDE=\"%s\"\n", (*__hv_compile_env)["INCLUDE"]);
222 printf ("export OPTS=\"%s\"\n", (*__hv_compile_env)["OPTS"]);
223 printf ("export LDFLAGS=\"%s\"\n", (*__hv_compile_env)["LDFLAGS"]);
224 printf ("export LIBS=\"%s\"\n\n", (*__hv_compile_env)["LIBS"]);
227 count = ENV->d_files->get_size ();
228 for (i = 0; i < count; ++i) {
229 S = rindex (ENV->d_files->get (i), '.');
230 if (! S)
231 continue;
232 if (EQ (S, ".cpp") || EQ (S, ".cxx"))
233 compile_cppfile (ENV->d_files->get (i));
234 if (EQ (S, ".c"))
235 compile_cfile (ENV->d_files->get (i));
238 if (__cc_shared || __cc_program)
239 __cc_build_target ();
241 return 0;
244 char compile_opt (DArray * d_opts, int * pos)
246 int count;
247 char *opt;
248 if (! d_opts || ! pos)
249 return 0;
251 opt = d_opts->get (*pos);
252 count = d_opts->get_size ();
253 if (EQ (opt, "--cc-script")) {
254 __cc_script = true;
255 return 1;
258 if (EQ (opt, "--cc-shared") ||
259 EQ (opt, "--compile-shared")) {
260 ++(*pos);
261 if (*pos >= count)
262 return 0;
263 __cc_shared = d_opts->get (*pos);
264 return 1;
267 if (EQ (opt, "--cc-program") ||
268 EQ (opt, "--compile-program")) {
269 ++(*pos);
270 if (*pos >= count)
271 return 0;
272 __cc_program = d_opts->get (*pos);
273 return 1;
276 if (EQ (opt, "--cc-env") ||
277 EQ (opt, "--compile-env")) {
278 __compile_env = true;
279 return 1;
282 return 0;
285 char compile_opt2 (DArray * d_opts, int * pos)
287 char * S;
289 if (! d_opts || ! pos)
290 return 0;
292 S = d_opts->get (*pos);
293 if (EQ (S, "--compile") ||
294 EQ (S, "-cc")) {
295 __hv_compile_env = bob_init_compile_env ();
296 compile_files ();
297 exit (0);
300 return 0;
303 void compile_short_info ()
305 printf ("C/C++ compilation plugin.");
308 void compile_long_info ()
310 printf ("C/C++ compilation plugin.\n");
311 printf ("Version: 0.3\n");
312 printf ("options: -cc --cc-script --cc-shared --cc-program) \n");
315 DArray * plugin_init (struct env_t *env)
317 DArray * Ret;
318 struct mod_t * pm;
320 __compile_env = false;
321 ENV = env;
322 Ret = new DArray (1);
323 pm = CNEW (mod_t, 1);
324 memset (pm, 0, sizeof (mod_t));
325 pm->Version = strdup ("1.0");
326 pm->short_info = compile_short_info;
327 pm->long_info = compile_long_info;
328 pm->opt = compile_opt;
329 pm->opt2 = compile_opt2;
331 __cc_script = false;
332 __cc_shared = NULL;
334 ENV->listOptions->add ("--cc-script");
335 ENV->listOptions->add ("-compile");
336 ENV->listOptions->add ("-cc");
337 ENV->listOptions->add ("--cc-shared");
338 ENV->listOptions->add ("--compile-shared");
339 ENV->listOptions->add ("--cc-program");
340 ENV->listOptions->add ("--compile-program");
341 ENV->listOptions->add ("--cc-env");
342 ENV->listOptions->add ("--compile-env");
344 Ret->add (LPCHAR (pm));
345 return Ret;