Add very old versions (for history).
[opsoft_archive.git] / silentbob / silentbob-1.4.1 / src / modding.cxx
blob8515bee3b421a16a6cd5a6a0edd4fbc190faa621
1 /*
2 * (c) Oleg Puchinin 2006
3 * graycardinalster@gmail.com
5 */
7 #include <dlfcn.h>
8 #include "head.h"
9 #include "mod.h"
10 #include "the_tt.h"
11 #include "dbg.h"
12 #include "bugs.h"
14 #define PLUGINS_MASK "find ~/plugins/ -name \"libplugin_*.so.*\""
16 typedef struct DArray *(*plug_init_t) (struct env_t *env);
18 env_t * sb_getenv (void)
20 return ENV;
23 char modding_optparse (int * i, int step)
25 int pos;
26 mod_t * plug;
27 mod_feature * f;
29 for (pos = 0; pos < ENV->modding->get_size (); pos++) {
30 plug = (mod_t *) ENV->modding->get (pos);
31 if (plug->Type == TYPE_FEATURE) {
32 f = (mod_feature *) plug;
34 if (step == 1) {
35 if (f->opt && f->opt (ENV->d_opts, i))
36 return 1;
39 if (step == 2) {
40 if (f->opt2 && f->opt2 (ENV->d_opts, i))
41 return 1;
46 return 0;
49 struct mod_language * find_language (char *S)
51 struct mod_language *pm = NULL;
52 int i;
54 //printf ("Plugins count : %i\n", ENV->modding->get_size ());
55 for (i = 0; i < ENV->modding->get_size (); i++) {
56 pm = (struct mod_language *) ENV->modding->get (i);
57 if (! pm)
58 continue;
60 if (pm->mod.Type != TYPE_LANGUAGE)
61 continue;
63 if (EQ (pm->language, S))
64 break;
67 if (i < ENV->modding->get_size ())
68 return pm;
70 return NULL;
73 void mods_info ()
75 struct mod_t *pm = NULL;
76 int i;
78 printf ("Available plugins: \n");
79 for (i = 0; i < ENV->modding->get_size (); i++) {
80 pm = (mod_t *) ENV->modding->get (i);
81 if (! pm)
82 continue;
84 if (! pm->short_info)
85 continue;
87 pm->short_info ();
88 printf ("\n");
92 FILE * mkctags_prepare ()
94 FILE * ofile;
96 if (SB_FLGET (SB_FLCTAGSAPPEND)) {
97 if (rename ("./tags", ENV->tmp_tags) < 0) {
98 fprintf (stderr, "$ rename: ./tags %s\n", ENV->tmp_tags);
99 perror ("rename");
100 exit (1);
102 ofile = fopen (ENV->tmp_tags, "a");
103 } else {
104 unlink (ENV->tmp_tags);
105 unlink ("./tags");
106 ofile = fopen (ENV->tmp_tags, "w");
109 if (ofile == NULL) {
110 fprintf (stderr, "fopen (\"%s\", \"w\")\n", ENV->tmp_tags);
111 perror ("fopen");
112 exit (1);
115 return ofile;
118 int modding_start (int i_cmd)
120 struct mod_language *pm = NULL;
121 struct tt_state_t * tt;
122 int i;
123 int size;
124 FILE * ofile = NULL;
126 pm = find_language (ENV->language);
127 if (pm == NULL || pm->the == NULL) {
128 assert (true, "Language plugin not found !\n");
129 return 1;
132 if (i_cmd == cmd_makectags)
133 ofile = mkctags_prepare ();
135 size = ENV->d_files->get_size ();
136 if (! size) {
137 switch (i_cmd) {
138 case cmd_makectags:
139 if (! pm->make_ctags)
140 return 2;
141 pm->make_ctags (NULL, ofile);
143 goto mod_out;
146 for (i = 0; i < size; i++) {
147 if (S_ISDIR (DLSTAT (ENV->d_files->get (i))->st_mode))
148 continue;
150 switch (i_cmd) {
151 case cmd_the_tt:
152 tt = CNEW (tt_state_t, 1);
153 memset (tt, 0, sizeof (struct tt_state_t));
154 tt->d_file_name = ENV->d_files->get (i);
156 if (! pm->the)
157 return 2;
159 pm->the (tt);
160 if (! SB_FLGET (SB_FLSIMULATE)) {
161 write (fileno (stdout), tt->d_output,
162 tt->d_output_size);
163 printf ("\n");
166 free_tt_state (tt);
167 break;
169 case cmd_makectags:
170 if (! pm->make_ctags || !pm->the)
171 return 2;
173 pm->make_ctags (ENV->d_files->get (i), ofile);
174 break;
176 case cmd_call_tags:
177 if (! pm->call_tags)
178 return 2;
180 pm->call_tags (ENV->d_files->get (i));
181 break;
183 default:
184 bug_notsupported ();
185 i = size;
186 break;
190 mod_out:
191 if (ofile)
192 fclose (ofile);
194 if (i_cmd == cmd_makectags)
195 mk_tags ("tags", NULL);
197 return 0;
200 int modding_load_dir (char * path)
202 int i;
203 DArray * files;
205 files = Dfiles (path);
206 if (! files)
207 return -1;
209 for (i = 0; i < files->get_size (); i++) {
210 if (EQ (files->get (i), "."))
211 continue;
212 if (EQ (files->get (i), ".."))
213 continue;
214 modding_load_plugin (files->get (i), path);
217 files->foreach (free);
218 delete files;
219 return 0;
222 int modding_init ()
224 ENV->modding = new EArray(32);
225 modding_load_dir (ENV->home_plugins);
226 modding_load_dir (ENV->shared_plugins);
227 return 0;
230 int modding_load_plugin (char * name, char * path)
232 int n;
233 struct stat st;
234 char * s_dlerror;
235 void * lib_handle;
236 DArray *plug_list;
237 struct mod_t * sb_plugin;
238 plug_init_t func_handle;
239 char m_buf[512];
241 if (! path || ! name)
242 return -1;
244 if (*stail (path) == '/')
245 *stail(m_buf) = '\0';
247 m_buf[511] = 0;
248 snprintf (m_buf, 511, "%s/%s", path, name);
250 stat (m_buf, &st);
251 if (! S_ISREG (st.st_mode))
252 return -1;
254 dlerror ();
255 lib_handle = dlopen (m_buf, RTLD_NOW);
256 s_dlerror = dlerror ();
257 if (s_dlerror) {
258 bug_plugin (s_dlerror);
259 return -1;
262 func_handle = (plug_init_t) dlsym (lib_handle, "plugin_init");
263 s_dlerror = dlerror ();
264 if (s_dlerror) {
265 bug_plugin (s_dlerror);
266 return -1;
269 plug_list = func_handle (ENV);
270 if (plug_list == NULL)
271 return -1;
273 for (n = 0; n < plug_list->get_size (); n++) {
274 sb_plugin = (struct mod_t *) plug_list->get (n);
275 sb_plugin->mod_file = strdup (m_buf);
276 if (sb_plugin)
277 ENV->modding->add (LPCHAR (sb_plugin));
280 return 0;