1 /*
2 * Copyright (c) 2004 Sasha Vasko <sasha@aftercode.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #define LOCAL_DEBUG
20 #define EVENT_TRACE
21
22 #include "../../configure.h"
23 #include "../../libAfterStep/asapp.h"
24 #include <unistd.h>
25 #include "../../libAfterStep/screen.h"
26 #include "../../libAfterStep/module.h"
27 #include "../../libAfterStep/aswindata.h"
28 #include "../../libAfterStep/event.h"
29 #include "../../libAfterStep/wmprops.h"
30 #include "../../libAfterStep/parser.h"
31 #include "../../libAfterStep/session.h"
32 #include "../../libAfterStep/mystyle.h"
33 #include "../../libAfterConf/afterconf.h"
34
35 #include "ASConfig.h"
36 #include "configfile.h"
37 #include "asproperty.h"
38 #include "xmlrpc.h"
39
40 /*************************************************************************/
41
42
43 ASProperty *Root = NULL;
44
45 ASConfigTypeInfo ConfigTypeInfo[] =
46 {
47 { CONFIG_Base_ID, &BaseSyntax, 0, 1, {CONFIG_BaseFile_ID}, CONFIG_BaseOptions_ID},
48 { CONFIG_ColorScheme_ID, &ColorSyntax, 0, 1, {CONFIG_ColorSchemeFile_ID}, CONFIG_ColorSchemeOptions_ID},
49 { CONFIG_Functions_ID, &FunctionSyntax, CONFIG_FunctionsFiles_ID, 3, {CONFIG_FeelFile_ID,
50 CONFIG_AfterStepFile_ID,
51 CONFIG_AutoExecFile_ID}, 0},
52 { CONFIG_Popups_ID, &PopupSyntax, CONFIG_PopupsFiles_ID, 3, {CONFIG_FeelFile_ID,
53 CONFIG_AfterStepFile_ID,
54 CONFIG_StartDir_ID}, 0},
55 { CONFIG_Database_ID, &DatabaseSyntax, 0, 1, {CONFIG_DatabaseFile_ID}, 0},
56 {0}
57 };
58
59 int AfterStepFeelFiles[] = {CONFIG_FeelFile_ID, CONFIG_AfterStepFile_ID, -1} ;
60 int AfterStepLookFiles[] = {CONFIG_LookFile_ID, CONFIG_AfterStepFile_ID, -1} ;
61 int PagerFeelFiles[] = {CONFIG_FeelFile_ID, CONFIG_PagerFile_ID, -1} ;
62 int PagerLookFiles[] = {CONFIG_LookFile_ID, CONFIG_PagerFile_ID, -1} ;
63 int PagerPrivateFiles[] = {CONFIG_PagerFile_ID, -1} ;
64
65 int WinListFeelFiles[] = {CONFIG_FeelFile_ID, CONFIG_WinListFile_ID, -1} ;
66 int WinListLookFiles[] = {CONFIG_LookFile_ID, CONFIG_WinListFile_ID, -1} ;
67 int WinListPrivateFiles[] = {CONFIG_WinListFile_ID, -1} ;
68
69 int WharfFeelFiles[] = {CONFIG_FeelFile_ID, CONFIG_WharfFile_ID, -1} ;
70 int WharfLookFiles[] = {CONFIG_LookFile_ID, CONFIG_WharfFile_ID, -1} ;
71 int WharfPrivateFiles[] = {CONFIG_WharfFile_ID, -1} ;
72
73 ASModuleSyntax MyStylesSyntaxes[] ={{CONFIG_MyStyles_ID, &ModuleMyStyleSyntax, NULL, CONFIG_LookFiles_ID, PagerLookFiles, 0, NULL },
74 {-1, NULL, NULL, 0, NULL, 0, NULL}};
75
76 ASModuleSyntax AfterStepLookSyntaxes[] ={{CONFIG_MyStyles_ID, &ModuleMyStyleSyntax, NULL, CONFIG_LookFiles_ID, AfterStepLookFiles, 0, NULL },
77 {CONFIG_MyFrames_ID, &AfterStepMyFrameSyntax, NULL, CONFIG_LookFiles_ID, AfterStepLookFiles, 0, NULL },
78 {CONFIG_MyBackgrounds_ID, &AfterStepMyBackSyntax, NULL, CONFIG_LookFiles_ID, AfterStepLookFiles, 0, NULL },
79 {CONFIG_TitleButtons_ID, &AfterStepTitleButtonSyntax, NULL, CONFIG_LookFiles_ID, AfterStepLookFiles, 0, NULL },
80 {-1, NULL, NULL, 0, NULL, 0, NULL}};
81
82 ASModuleSyntax AfterStepFeelSyntaxes[] ={{CONFIG_Cursors_ID, &AfterStepCursorSyntax, NULL, CONFIG_FeelFiles_ID, AfterStepFeelFiles, 0, NULL },
83 {CONFIG_MouseBindings_ID, &AfterStepMouseSyntax, NULL, CONFIG_FeelFiles_ID, AfterStepFeelFiles, 0, NULL },
84 {CONFIG_KeyBindings_ID, &AfterStepKeySyntax, NULL, CONFIG_FeelFiles_ID, AfterStepFeelFiles, 0, NULL },
85 {CONFIG_WindowBoxes_ID, &AfterStepWindowBoxSyntax, NULL, CONFIG_FeelFiles_ID, AfterStepFeelFiles, 0, NULL },
86 {-1, NULL, NULL, 0, NULL, 0, NULL}};
87
88 ASModuleSyntax AfterStepSyntaxes[]={{CONFIG_AfterStepFeel_ID, &AfterStepFeelSyntax, NULL, CONFIG_FeelFiles_ID, AfterStepFeelFiles, CONFIG_FeelOptions_ID, &AfterStepFeelSyntaxes[0] },
89 {CONFIG_AfterStepLook_ID, &AfterStepLookSyntax, NULL, CONFIG_LookFiles_ID, AfterStepLookFiles, CONFIG_LookOptions_ID, &AfterStepLookSyntaxes[0] },
90 {-1, NULL, NULL, 0, NULL, 0, NULL}};
91
92
93 ASModuleSyntax PagerSyntaxes[] = { {CONFIG_PagerFeel_ID, &PagerFeelSyntax, NULL, CONFIG_FeelFiles_ID, PagerFeelFiles, CONFIG_FeelOptions_ID, NULL },
94 {CONFIG_PagerLook_ID, &PagerLookSyntax, NULL, CONFIG_LookFiles_ID, PagerLookFiles, CONFIG_LookOptions_ID, &MyStylesSyntaxes[0] },
95 {0, &PagerPrivateSyntax, NULL, 0, PagerPrivateFiles, CONFIG_PagerOptions_ID, NULL },
96 {-1, NULL, NULL, 0, NULL, 0, NULL}};
97
98 ASModuleSyntax WinListSyntaxes[] ={ {CONFIG_WinListFeel_ID, &WinListFeelSyntax, NULL, CONFIG_FeelFiles_ID, WinListFeelFiles, CONFIG_FeelOptions_ID, NULL },
99 {CONFIG_WinListLook_ID, &WinListLookSyntax, NULL, CONFIG_LookFiles_ID, WinListLookFiles, CONFIG_LookOptions_ID, &MyStylesSyntaxes[0] },
100 {0, &WinListPrivateSyntax, NULL, 0, WinListPrivateFiles, CONFIG_WinListOptions_ID, NULL },
101 {-1, NULL, NULL, 0, NULL, 0, NULL}};
102
103 ASModuleSyntax WharfSyntaxes[] ={ {CONFIG_WharfFeel_ID, &WharfFeelSyntax, NULL, CONFIG_FeelFiles_ID, WharfFeelFiles ,CONFIG_FeelOptions_ID, NULL },
104 {CONFIG_WharfLook_ID, &WharfLookSyntax, NULL, CONFIG_LookFiles_ID, WharfLookFiles ,CONFIG_LookOptions_ID, &MyStylesSyntaxes[0] },
105 {0, &WharfPrivateSyntax, NULL, 0, WharfPrivateFiles ,CONFIG_WharfOptions_ID, NULL },
106 {CONFIG_WharfFolders_ID,&WharfFolderSyntax, WharfSpecialFunc, 0, WharfPrivateFiles ,CONFIG_WharfFolders_ID, NULL },
107 {-1, NULL, NULL, 0, NULL, 0, NULL}};
108
109 ASModuleSpecs ModulesSpecs[] =
110 {{CLASS_PAGER, PagerSyntaxes},
111 {CLASS_AFTERSTEP, AfterStepSyntaxes},
112 {CLASS_WINLIST, WinListSyntaxes},
113 {CLASS_WHARF, WharfSyntaxes},
114 {NULL, NULL}
115 };
116
117 /*************************************************************************/
118 void
DeadPipe(int foo)119 DeadPipe (int foo)
120 {
121 {
122 static int already_dead = False ;
123 if( already_dead ) return;/* non-reentrant function ! */
124 already_dead = True ;
125 }
126 FreeMyAppResources();
127 #ifdef DEBUG_ALLOCS
128 print_unfreed_mem ();
129 #endif /* DEBUG_ALLOCS */
130
131 if( dpy )
132 {
133 XFlush (dpy);
134 XCloseDisplay (dpy);
135 }
136 exit (0);
137 }
138 /*************************************************************************/
139 /*************************************************************************/
140 void load_hierarchy();
141 void print_hierarchy( ASProperty *root, int level );
142 void register_special_keywords();
143 void interactive_loop();
144 /*************************************************************************/
145 /*************************************************************************/
146 int
main(int argc,char ** argv)147 main (int argc, char **argv)
148 {
149 Bool interactive = False ;
150 Bool do_print_hierarchy = True ;
151 int i ;
152 /* Save our program name - for error messages */
153 set_DeadPipe_handler(DeadPipe);
154 InitMyApp (CLASS_ASCONFIG, argc, argv, NULL, NULL, 0 );
155 for( i = 1 ; i < argc ; ++i )
156 if( argv[i] )
157 {
158 if( mystrcmp(argv[i],"-i") == 0 || mystrcmp(argv[i],"--interactive") == 0 )
159 interactive = True;
160 else if( mystrcmp(argv[i],"-p") == 0 || mystrcmp(argv[i],"--print-hierarchy") == 0 )
161 interactive = True;
162
163 }
164
165 LinkAfterStepConfig();
166
167 InitSession();
168
169 register_special_keywords();
170 init_ConfigFileInfo();
171
172 LOCAL_DEBUG_OUT("loading hierarchy%s","");
173 load_hierarchy();
174
175 if( interactive )
176 {
177 interactive_loop();
178 }else if( do_print_hierarchy )
179 print_hierarchy(Root, 0);
180
181 if( dpy )
182 XCloseDisplay (dpy);
183 return 0;
184 }
185 /**************************************************************************/
register_special_keywords()186 void register_special_keywords()
187 {
188 #define REG_SPEC_KEYWORD(k) register_keyword_id( #k, CONFIG_##k##_ID )
189
190 REG_SPEC_KEYWORD(root);
191 REG_SPEC_KEYWORD(Base);
192 REG_SPEC_KEYWORD(ColorScheme);
193 REG_SPEC_KEYWORD(Functions);
194 REG_SPEC_KEYWORD(Popups);
195 REG_SPEC_KEYWORD(Database);
196 REG_SPEC_KEYWORD(Module);
197
198 REG_SPEC_KEYWORD(AfterStep);
199 REG_SPEC_KEYWORD(Pager);
200 REG_SPEC_KEYWORD(Wharf);
201 REG_SPEC_KEYWORD(WinList);
202
203 REG_SPEC_KEYWORD(AfterStepLook);
204 REG_SPEC_KEYWORD(AfterStepFeel);
205 REG_SPEC_KEYWORD(PagerLook);
206 REG_SPEC_KEYWORD(PagerFeel);
207 REG_SPEC_KEYWORD(WharfLook);
208 REG_SPEC_KEYWORD(WharfFeel);
209 REG_SPEC_KEYWORD(WharfFolders);
210 REG_SPEC_KEYWORD(WinListLook);
211 REG_SPEC_KEYWORD(WinListFeel);
212
213 REG_SPEC_KEYWORD(LookFile);
214 REG_SPEC_KEYWORD(FeelFile);
215 REG_SPEC_KEYWORD(StartDir);
216 REG_SPEC_KEYWORD(AutoExecFile);
217 REG_SPEC_KEYWORD(PagerFile);
218 REG_SPEC_KEYWORD(WharfFile);
219 REG_SPEC_KEYWORD(WinListFile);
220 REG_SPEC_KEYWORD(AfterStepFile);
221 REG_SPEC_KEYWORD(BaseFile);
222 REG_SPEC_KEYWORD(ColorSchemeFile);
223 REG_SPEC_KEYWORD(DatabaseFile);
224
225
226 REG_SPEC_KEYWORD(FunctionsFiles);
227 REG_SPEC_KEYWORD(PopupsFiles);
228 REG_SPEC_KEYWORD(LookFiles);
229 REG_SPEC_KEYWORD(FeelFiles);
230 REG_SPEC_KEYWORD(BackgroundFiles);
231 REG_SPEC_KEYWORD(PrivateFiles);
232 REG_SPEC_KEYWORD(SharedFiles);
233
234 REG_SPEC_KEYWORD(BaseOptions);
235 REG_SPEC_KEYWORD(ColorSchemeOptions);
236 REG_SPEC_KEYWORD(MyStyles);
237 REG_SPEC_KEYWORD(MyFrames);
238 REG_SPEC_KEYWORD(MyBackgrounds);
239 REG_SPEC_KEYWORD(TitleButtons);
240 REG_SPEC_KEYWORD(Cursors);
241 REG_SPEC_KEYWORD(MouseBindings);
242 REG_SPEC_KEYWORD(KeyBindings);
243 REG_SPEC_KEYWORD(WindowBoxes);
244
245 REG_SPEC_KEYWORD(LookOptions);
246 REG_SPEC_KEYWORD(FeelOptions);
247 REG_SPEC_KEYWORD(AfterStepOptions);
248 REG_SPEC_KEYWORD(PagerOptions);
249 REG_SPEC_KEYWORD(WharfOptions);
250 REG_SPEC_KEYWORD(WinListOptions);
251
252 REG_SPEC_KEYWORD(flags);
253 REG_SPEC_KEYWORD(x);
254 REG_SPEC_KEYWORD(y);
255 REG_SPEC_KEYWORD(width);
256 REG_SPEC_KEYWORD(height);
257
258 REG_SPEC_KEYWORD(type);
259 REG_SPEC_KEYWORD(tint);
260 REG_SPEC_KEYWORD(pixmap);
261
262 REG_SPEC_KEYWORD(hotkey);
263 REG_SPEC_KEYWORD(text);
264 REG_SPEC_KEYWORD(value);
265 REG_SPEC_KEYWORD(unit);
266 REG_SPEC_KEYWORD(IncludeFile);
267
268 REG_SPEC_KEYWORD(unpressed);
269 REG_SPEC_KEYWORD(pressed);
270
271 REG_SPEC_KEYWORD(source);
272 REG_SPEC_KEYWORD(context);
273 REG_SPEC_KEYWORD(mod);
274
275 REG_SPEC_KEYWORD(left);
276 REG_SPEC_KEYWORD(right);
277 REG_SPEC_KEYWORD(top);
278 REG_SPEC_KEYWORD(bottom);
279
280 REG_SPEC_KEYWORD(image);
281 REG_SPEC_KEYWORD(mask);
282 }
283 /*************************************************************************/
284 ASProperty *
special_free_storage2property(FreeStorageElem ** pcurr)285 special_free_storage2property( FreeStorageElem **pcurr )
286 {
287 FreeStorageElem *curr = *pcurr ;
288 ASProperty *prop = NULL ;
289 ConfigItem item;
290 item.memory = NULL;
291
292 ReadConfigItem (&item, curr);
293
294 if( curr->term->id == MYSTYLE_BACKGRADIENT_ID )
295 {
296 /* TODO */
297 }else if( curr->term->id == MYSTYLE_BACKGRADIENT_ID )
298 {
299 /* TODO */
300 }else if( curr->term->id == MYSTYLE_BACKPIXMAP_ID )
301 {
302 prop = create_property( curr->term->id, ASProp_Phony, NULL, True );
303 add_integer_property( CONFIG_type_ID, item.data.integer, prop );
304
305 if (curr->argc > 1)
306 {
307 if( item.data.integer == TEXTURE_TRANSPARENT || item.data.integer == TEXTURE_TRANSPARENT_TWOWAY )
308 add_string_property( CONFIG_tint_ID, curr->argv[1], prop );
309 else
310 add_string_property( CONFIG_pixmap_ID, curr->argv[1], prop );
311 }
312 }
313
314 if( prop == NULL )
315 {
316 switch( curr->term->type )
317 {
318 case TT_GEOMETRY :
319 prop = create_property( curr->term->id, ASProp_Phony, NULL, True );
320 add_integer_property( CONFIG_flags_ID, item.data.geometry.flags, prop );
321 if( get_flags(item.data.geometry.flags, XValue ) )
322 add_integer_property( CONFIG_x_ID, item.data.geometry.x, prop );
323 if( get_flags(item.data.geometry.flags, YValue ) )
324 add_integer_property( CONFIG_y_ID, item.data.geometry.y, prop );
325 if( get_flags(item.data.geometry.flags, WidthValue ) )
326 add_integer_property( CONFIG_width_ID, item.data.geometry.width, prop );
327 if( get_flags(item.data.geometry.flags, HeightValue ) )
328 add_integer_property( CONFIG_height_ID, item.data.geometry.height, prop );
329 break ;
330 case TT_FUNCTION :
331 {
332 FunctionData *pfunc = (item.data.function);
333 ASProperty *tmp ;
334 prop = create_property( curr->term->id, ASProp_Phony, pfunc->name, True );
335 if( pfunc->hotkey != '\0' )
336 add_char_property( CONFIG_hotkey_ID, pfunc->hotkey, prop );
337 if( pfunc->text )
338 {
339 add_string_property( CONFIG_text_ID, pfunc->text, prop );
340
341 if(
342 (pfunc->func > F_REFRESH && pfunc->func <= F_MOVECURSOR ) ||
343 (pfunc->func >= F_DESK && pfunc->func < F_POPUP ) ||
344 pfunc->func == F_RESIZE || pfunc->func == F_MOVE ||
345 pfunc->func == F_SETLAYER || pfunc->func == F_REFRESH ||
346 pfunc->func == F_MAXIMIZE || pfunc->func == F_CHANGE_WINDOWS_DESK )
347 {
348 tmp = add_integer_property( CONFIG_value_ID, pfunc->func_val[0], prop );
349 set_property_index( tmp, 0 );
350 if( pfunc->unit[0] != '\0' )
351 {
352 tmp = add_char_property( CONFIG_unit_ID, pfunc->unit[0], prop );
353 set_property_index( tmp, 0 );
354 }
355 tmp = add_integer_property( CONFIG_value_ID, pfunc->func_val[1], prop );
356 set_property_index( tmp, 1 );
357 if( pfunc->unit[1] != '\0' )
358 {
359 tmp = add_char_property( CONFIG_unit_ID, pfunc->unit[1], prop );
360 set_property_index( tmp, 1 );
361 }
362 }
363 }
364 if( curr->next != NULL )
365 {
366 curr = curr->next ;
367 if( curr->term->id == F_MINIPIXMAP )
368 {
369 ReadConfigItem (&item, curr);
370 pfunc = (item.data.function);
371 if( pfunc->name != NULL )
372 add_string_property( F_MINIPIXMAP, pfunc->name, prop );
373 else
374 add_string_property( F_MINIPIXMAP, pfunc->text, prop );
375 *pcurr = curr ;
376 }
377 }
378 }
379 break ;
380 case TT_BOX :
381 prop = create_property( curr->term->id, ASProp_Phony, NULL, True );
382 add_integer_property( CONFIG_flags_ID, item.data.box.flags, prop );
383 if( get_flags(item.data.box.flags, LeftValue ) )
384 add_integer_property( CONFIG_left_ID, item.data.box.left, prop );
385 if( get_flags(item.data.box.flags, RightValue ) )
386 add_integer_property( CONFIG_right_ID, item.data.box.right, prop );
387 if( get_flags(item.data.box.flags, TopValue ) )
388 add_integer_property( CONFIG_top_ID, item.data.box.top, prop );
389 if( get_flags(item.data.box.flags, BottomValue ) )
390 add_integer_property( CONFIG_bottom_ID, item.data.box.bottom, prop );
391 break ;
392 case TT_BUTTON :
393 prop = create_property( curr->term->id, ASProp_Phony, NULL, True );
394 set_property_index( prop, item.index );
395 if( item.data.button )
396 {
397 if( item.data.button->shapes[ASB_State_Up] )
398 add_string_property( CONFIG_unpressed_ID, item.data.button->shapes[ASB_State_Up], prop );
399 if( item.data.button->shapes[ASB_State_Down] )
400 add_string_property( CONFIG_pressed_ID, item.data.button->shapes[ASB_State_Down], prop );
401 }
402 break ;
403 case TT_BINDING :
404 prop = create_property( curr->term->id, ASProp_Phony, NULL, True );
405 if( item.data.binding.sym )
406 add_string_property( CONFIG_source_ID, item.data.binding.sym, prop );
407 add_integer_property( CONFIG_context_ID, item.data.binding.context, prop );
408 add_integer_property( CONFIG_mod_ID, item.data.binding.mods, prop );
409 break ;
410 case TT_INTARRAY : /* TODO */ break ;
411 case TT_CURSOR :
412 prop = create_property( curr->term->id, ASProp_Phony, NULL, True );
413 if( item.data.cursor )
414 {
415 if( item.data.cursor->image_file )
416 add_string_property( CONFIG_image_ID, item.data.cursor->image_file, prop );
417 if( item.data.cursor->mask_file )
418 add_string_property( CONFIG_mask_ID, item.data.cursor->mask_file, prop );
419 }
420 break ;
421
422 }
423 }
424 ReadConfigItem (&item, NULL);
425
426 return prop;
427 }
428
429 ASProperty*
free_storage2property_list(FreeStorageElem * fs,ASProperty * pl)430 free_storage2property_list( FreeStorageElem *fs, ASProperty *pl )
431 {
432 FreeStorageElem *curr ;
433 ConfigItem item;
434 ASProperty *prop = NULL;
435
436 LOCAL_DEBUG_CALLER_OUT("(%p,%p)", fs, pl );
437 item.memory = NULL;
438
439 for( curr = fs ; curr ; curr = curr->next )
440 {
441 if (curr->term == NULL)
442 continue;
443 if ( get_flags( curr->term->flags, TF_SYNTAX_TERMINATOR ) )
444 continue;
445 if (!ReadConfigItem (&item, curr))
446 continue;
447 if( curr == fs && pl->id == curr->term->id )
448 continue;
449
450 if( (curr->term->type == TT_QUOTED_TEXT || curr->term->type == TT_TEXT) &&
451 curr->term->sub_syntax != NULL &&
452 !get_flags(curr->term->flags, TF_INDEXED|TF_DIRECTION_INDEXED) )
453 {
454 prop = create_property( curr->term->id, ASProp_Phony, item.data.string, (curr->sub != NULL) );
455 }else /* we actually have some data */
456 {
457 prop = special_free_storage2property( &curr );
458 if( prop == NULL )
459 {
460 int type = ASProp_Phony;
461 char *name = NULL ;
462 if( curr->sub == NULL )
463 switch( curr->term->type )
464 {
465 case TT_FLAG :
466 case TT_INTEGER :
467 case TT_UINTEGER :
468 case TT_BITLIST : type = ASProp_Integer ; break ;
469
470 case TT_COLOR :
471 case TT_FONT :
472 case TT_FILENAME :
473 case TT_PATHNAME :
474 case TT_TEXT :
475 case TT_QUOTED_TEXT :
476 case TT_OPTIONAL_PATHNAME : type = ASProp_Data ; break ;
477 default:
478 /* handled by special_ as complex datatype */ break ;
479 }
480
481 prop = create_property( curr->term->id, type, name, (curr->sub != NULL) );
482 if( type == ASProp_Data )
483 {
484 if( item.data.string == NULL )
485 prop->contents.data = 0 ;
486 else
487 prop->contents.data = encode_string( item.data.string );
488 /* LOCAL_DEBUG_OUT( "stored with id = %d, string = \"%s\"", prop->contents.data, item.data.string ); */
489 }else
490 prop->contents.integer = item.data.integer ;
491 }
492 }
493
494 if( get_flags(curr->term->flags, TF_INDEXED|TF_DIRECTION_INDEXED))
495 set_property_index( prop, item.index );
496
497 if( curr->sub != NULL )
498 free_storage2property_list( curr->sub, prop ) ;
499
500 append_property( pl, prop );
501 }
502 return prop;
503 }
504
505 Bool
merge_prop_into_prop(void * data,void * aux_data)506 merge_prop_into_prop(void *data, void *aux_data)
507 {
508 ASProperty *dst = (ASProperty*)data;
509 ASProperty *src = (ASProperty*)aux_data;
510
511 if( dst->id != src->id || dst == src )
512 return True;
513
514 if( get_flags( src->flags, ASProp_Indexed ) && get_flags( dst->flags, ASProp_Indexed ) )
515 {
516 if( src->index != dst->index )
517 return True;
518 }else if( src->name != NULL && dst->name != NULL )
519 if( strcmp( src->name, dst->name ) )
520 return True;
521
522 /* otherwise we have to merge it : */
523 dup_property_contents( src, dst, True );
524
525 set_flags( src->flags, ASProp_Merged );
526 return True;
527 }
528
529 Bool
merge_prop_into_list(void * data,void * aux_data)530 merge_prop_into_list(void *data, void *aux_data)
531 {
532 ASProperty *prop = (ASProperty*)data;
533 ASProperty *dst_prop = (ASProperty*)aux_data;
534
535 clear_flags( prop->flags, ASProp_Merged );
536 iterate_asbidirlist( dst_prop->sub_props, merge_prop_into_prop, prop, NULL, False );
537 if( !get_flags( prop->flags, ASProp_Merged ) )
538 {
539 prop = dup_property( prop, True );
540 append_property( dst_prop, prop );
541 }
542
543 return True;
544 }
545
546 void
merge_property_list(ASProperty * src,ASProperty * dst)547 merge_property_list( ASProperty *src, ASProperty *dst )
548 {
549 if( src->sub_props == NULL && dst->sub_props == NULL )
550 return;
551 LOCAL_DEBUG_CALLER_OUT("(%p,%p)", src, dst );
552 iterate_asbidirlist( src->sub_props, merge_prop_into_list, dst, NULL, False );
553 }
554 /*************************************************************************/
555 ASProperty* asmenu_dir2property( const char *dirname, const char *menu_path, ASProperty *owner_prop, int func, const char *extension, const char *mini_ext );
556 void melt_menu_props( ASProperty *file, ASProperty *opts );
557 void melt_func_props( ASProperty *file, ASProperty *opts );
558 void melt_binding_props( ASProperty *src, ASProperty *dst );
559
560
561 ASProperty*
load_current_config_fname(ASProperty * config,int id,const char * filename,const char * myname,SyntaxDef * syntax,SpecialFunc special,int files_id,int file_id,int options_id)562 load_current_config_fname( ASProperty* config, int id, const char *filename, const char *myname,
563 SyntaxDef *syntax, SpecialFunc special, int files_id, int file_id, int options_id )
564 {
565 ASConfigFile *cf = NULL ;
566 ASProperty *files = NULL ;
567 ASProperty *file ;
568 ASProperty *opts ;
569
570 if( config == NULL )
571 config = create_property( id, ASProp_Phony, NULL, True );
572
573 if( filename )
574 {
575 if( CheckDir(filename) )
576 {
577 LOCAL_DEBUG_OUT("loading file \"%s\", myname = \"%s\", syntax = %p, syntax name = \"%s\"", filename, myname, syntax, syntax->display_name );
578 cf = load_config_file(NULL, filename, myname?myname:"afterstep", syntax, special );
579 }
580 }
581
582
583 if( files_id != 0 )
584 {
585 files = find_property_by_id( config, files_id );
586 if( files == NULL )
587 {
588 files = create_property( files_id, ASProp_Phony, NULL, True );
589 append_property( config, files );
590 }
591 }
592
593 file = find_property_by_id( files?files:config, file_id );
594 if( file == NULL )
595 {
596 file = create_property( file_id, ASProp_File, NULL, True );
597 append_property( files?files:config, file );
598 }
599 file->contents.config_file = cf ;
600
601 if( cf )
602 free_storage2property_list( cf->free_storage, file );
603 else if( file_id == CONFIG_StartDir_ID )
604 asmenu_dir2property( filename, "", file, F_NOP, NULL, NULL );
605
606 if( options_id != 0 )
607 {
608 opts = find_property_by_id( config, options_id );
609 if( opts == NULL )
610 {
611 opts = create_property( options_id, ASProp_Phony, NULL, True );
612 append_property( config, opts );
613 }
614 }else
615 opts = config ;
616
617 if( file_id == CONFIG_StartDir_ID )
618 melt_menu_props( file, opts );
619 else if( syntax == &FunctionSyntax )
620 {
621 melt_func_props( file, opts );
622 }else if( id == CONFIG_KeyBindings_ID || id == CONFIG_MouseBindings_ID )
623 melt_binding_props( file, opts );
624 else
625 merge_property_list( file, opts );
626
627 return config;
628 }
629
630 ASProperty*
load_current_config(ASProperty * config,int id,const char * myname,SyntaxDef * syntax,SpecialFunc special,int files_id,int file_id,int options_id)631 load_current_config( ASProperty* config, int id, const char *myname,
632 SyntaxDef *syntax, SpecialFunc special, int files_id, int file_id, int options_id )
633 {
634 const char *filename = get_config_file_name( file_id );
635 return load_current_config_fname( config, id, filename, myname, syntax, special, files_id, file_id, options_id );
636
637 }
638
639 /*************************************************************************/
640 ASProperty*
asmenu_dir2property(const char * dirname,const char * menu_path,ASProperty * owner_prop,int func,const char * extension,const char * mini_ext)641 asmenu_dir2property( const char *dirname, const char *menu_path, ASProperty *owner_prop,
642 int func, const char *extension, const char *mini_ext )
643 {
644 struct direntry **list;
645 int list_len, i ;
646 ASProperty *popup, *include_file = NULL ;
647 const char *ptr;
648 ASConfigFile *include_cf = NULL ;
649 char *new_path ;
650 ASProperty *item = NULL ;
651 int mini_ext_len = mini_ext?strlen(mini_ext):0 ;
652 int ext_len = extension?strlen(extension):0 ;
653
654 if( dirname == NULL )
655 return NULL;
656
657 ptr = strrchr(dirname,'/');
658
659 list_len = my_scandir ((char*)dirname, &list, no_dots_except_include, NULL);
660 LOCAL_DEBUG_OUT("dir \"%s\" has %d entries", dirname, list_len );
661 if( list_len <= 0 )
662 return NULL;
663
664 if( ptr == NULL )
665 ptr = dirname ;
666 else
667 ++ptr ;
668 while( isdigit(*ptr) ) ++ptr;
669 if( *ptr == '_' )
670 ++ptr ;
671
672 new_path = make_file_name( menu_path, ptr );
673 popup = create_property( F_POPUP, ASProp_Data, new_path, True );
674 popup->contents.data = encode_string( dirname );
675 append_property( owner_prop, popup );
676
677 for (i = 0; i < list_len; i++)
678 if( list[i]->d_name[0] == '.' )
679 {
680 ASProperty *cmd ;
681 include_cf = load_config_file(dirname, list[i]->d_name, "afterstep", &includeSyntax, NULL );
682 include_file = create_property( CONFIG_IncludeFile_ID, ASProp_File, NULL, True );
683 append_property( popup, include_file );
684 include_file->contents.config_file = include_cf ;
685 free_storage2property_list( include_cf->free_storage, include_file );
686
687 cmd = find_property_by_id( include_file, INCLUDE_command_ID );
688
689 if( cmd )
690 {
691 ASProperty *cmd_func = find_property_by_id( cmd, -1 ); ;
692 if( cmd_func && cmd_func->id < F_FUNCTIONS_NUM )
693 func = cmd_func->id ;
694 }
695 break;
696 }
697 for (i = 0; i < list_len; i++)
698 {
699 char *sub_path = make_file_name( dirname, list[i]->d_name );
700 if ( S_ISDIR (list[i]->d_mode) )
701 {
702 ASProperty *sub_menu = asmenu_dir2property( sub_path, new_path, owner_prop, func, extension, mini_ext ) ;
703 item = create_property( F_POPUP, ASProp_Data, sub_menu->name, True );
704 item->contents.data = encode_string( sub_path );
705 append_property( popup, item );
706 }else if( list[i]->d_name[0] != '.' )
707 {
708 int len = strlen(list[i]->d_name);
709 char *stripped_name = NULL;
710 char *minipixmap = NULL ;
711 char hotkey = '\0' ;
712 int k ;
713 char *clean_name;
714 int order = strtol (list[i]->d_name, &clean_name, 10);
715
716 if( clean_name == list[i]->d_name )
717 {
718 if( isalpha(clean_name[0]) && clean_name[1] == '_' )
719 {
720 order = (int)(clean_name[0]) - (int)'0' ;
721 clean_name += 2 ;
722 len -= 2 ;
723 }else
724 order = -1 ;
725 }else
726 len -= (clean_name - list[i]->d_name );
727
728 if( ext_len > 0 && len > ext_len )
729 {
730 if( strcmp( clean_name + len - ext_len, extension) == 0 )
731 stripped_name = mystrndup( clean_name, len - ext_len );
732 else if( strncmp(clean_name, extension, ext_len) == 0 )
733 stripped_name = mystrdup( clean_name + ext_len );
734 }
735 if( stripped_name == NULL )
736 {
737 if( mini_ext_len > 0 && len > mini_ext_len )
738 {
739 if( strcmp( clean_name + len - mini_ext_len, mini_ext ) == 0 )
740 continue;
741 if( strncmp( clean_name, mini_ext, mini_ext_len ) == 0 )
742 continue;
743 }
744 stripped_name = mystrdup( clean_name );
745 }
746
747 if( mini_ext_len > 0 )
748 {
749 for(k = 0; k < list_len; k++)
750 if( k != i && !S_ISDIR (list[k]->d_mode))
751 {
752 int mlen = strlen(list[k]->d_name);
753 if( mlen > mini_ext_len && len - ext_len == mlen - mini_ext_len)
754 {
755 if( strcmp( list[k]->d_name + mlen - mini_ext_len, mini_ext ) == 0)
756 {
757 if( strncmp( list[k]->d_name, stripped_name, mlen - mini_ext_len ) == 0 )
758 { /* found suitable minipixmap */
759 minipixmap = make_file_name( dirname, list[k]->d_name );
760 break;
761 }
762 }else if( strncmp( list[k]->d_name, mini_ext, mini_ext_len ) == 0)
763 {
764 if( strcmp( list[k]->d_name + mini_ext_len, stripped_name ) == 0 )
765 { /* found suitable minipixmap */
766 minipixmap = make_file_name( dirname, list[k]->d_name + mini_ext_len );
767 break;
768 }
769 }
770 }
771 }
772 }
773
774 for( k = 0 ; stripped_name[k] != '\0' ; ++k )
775 {
776 if( stripped_name[k] == '_' )
777 {
778 if( stripped_name[k+1] == '_' )
779 {
780 int l ;
781 for( l = k+2 ; stripped_name[l] != '\0' ; ++l)
782 stripped_name[l-2] = stripped_name[l] ;
783 hotkey = stripped_name[k] ;
784 }else
785 stripped_name[k] = ' ' ;
786 }
787
788 }
789
790 if( func != F_NOP )
791 {
792 item = create_property( func, ASProp_Data, stripped_name, True );
793 item->contents.data = encode_string( sub_path );
794 append_property( popup, item );
795 add_string_property( CONFIG_text_ID, sub_path, item );
796 if( minipixmap )
797 add_string_property( F_MINIPIXMAP, minipixmap, item );
798 if( hotkey != '\0' )
799 add_char_property( CONFIG_hotkey_ID, hotkey, item );
800 }else
801 {
802 ASConfigFile *cf = NULL ;
803
804 cf = load_config_file(dirname, list[i]->d_name, "afterstep", pFuncSyntax, NULL );
805 item = free_storage2property_list( cf->free_storage, popup );
806 if( item )
807 {
808 item->type = ASProp_File ;
809 item->contents.config_file = cf ;
810 if( item->name == NULL )
811 {
812 item->name = stripped_name ;
813 stripped_name = NULL ;
814 }else
815 hotkey = scan_for_hotkey (stripped_name);
816
817 if( minipixmap )
818 if( find_property_by_id( item, F_MINIPIXMAP ) == NULL )
819 add_string_property( F_MINIPIXMAP, minipixmap, item );
820 if( hotkey != '\0' )
821 if( find_property_by_id( item, CONFIG_hotkey_ID ) == NULL )
822 add_char_property( CONFIG_hotkey_ID, hotkey, item );
823
824 }else
825 destroy_config_file( cf );
826 }
827 if( item )
828 item->order = order ;
829 if( stripped_name)
830 free( stripped_name );
831 if(minipixmap)
832 free(minipixmap);
833 }
834 free( sub_path );
835 free (list[i]);
836 }
837 if( list )
838 free( list );
839 free( new_path );
840 return popup;
841 }
842
compare_menuitems_handler(void * data1,void * data2)843 int compare_menuitems_handler(void *data1, void *data2)
844 {
845 ASProperty *item1 = (ASProperty*)data1 ;
846 ASProperty *item2 = (ASProperty*)data2 ;
847 static char buffer1[512], buffer2[512] ;
848 int stored_len1 = 0, stored_len2 = 0 ;
849 LOCAL_DEBUG_OUT( "comparing items with order %d and %d", item1->order, item2->order );
850 if( item2->id == F_POPUP && item1->id != F_POPUP)
851 return 1 ;
852 else if( item1->id == F_POPUP && item2->id != F_POPUP)
853 return 0;
854 if( item2->order >= 0 )
855 {
856 if( item1->order < 0 )
857 return 1;
858 return item1->order - item2->order;
859 }
860 if( item1->order >= 0 )
861 return 0;
862
863 if( item1->type == ASProp_File && item2->type == ASProp_File )
864 return mystrcmp( item1->contents.config_file->filename, item2->contents.config_file->filename );
865 else if( item1->type == ASProp_File && item2->type == ASProp_Data )
866 {
867 decode_string( item2->contents.data, &(buffer1[0]), 512, &stored_len1 );
868 return mystrcmp( item1->contents.config_file->filename, &buffer1[0] );
869 }else if( item2->type == ASProp_File && item1->type == ASProp_Data )
870 {
871 decode_string( item1->contents.data, &(buffer1[0]), 512, &stored_len1 );
872 return mystrcmp( &buffer1[0], item2->contents.config_file->filename );
873 }else if( item2->type == ASProp_Data && item1->type == ASProp_Data )
874 {
875 decode_string( item1->contents.data, &(buffer1[0]), 512, &stored_len1 );
876 decode_string( item2->contents.data, &(buffer2[0]), 512, &stored_len2 );
877 return mystrcmp( &buffer1[0], &buffer2[0] );
878 }
879 return 0;
880 }
881
882 Bool
melt_menu_props_into_list(void * data,void * aux_data)883 melt_menu_props_into_list(void *data, void *aux_data)
884 {
885 ASProperty *popup = (ASProperty*)data;
886 ASProperty *dst = (ASProperty*)aux_data ;
887 ASProperty *incl ;
888 ASProperty *dst_popup ;
889 char *name = NULL ;
890
891 incl = find_property_by_id( popup, CONFIG_IncludeFile_ID );
892 dst_popup = find_property_by_id_name( dst, popup->id, popup->name );
893 if( dst_popup == NULL )
894 {
895 dst_popup = dup_property( popup, True );
896 append_property( dst, dst_popup );
897 }else
898 merge_property_list( popup, dst_popup );
899
900 if( incl )
901 {
902 int func = F_NOP ;
903 #define MAX_EXTENTION 256
904 char *extension = NULL ;
905 char *mini_ext = NULL ;
906 ASBiDirElem *curr ;
907 ASProperty *phony = NULL;
908
909 remove_property_by_id( dst_popup, CONFIG_IncludeFile_ID );
910 /* Pass 1 : collecting settings first : */
911 for( curr = LIST_START(incl->sub_props); curr != NULL ; LIST_GOTO_NEXT(curr) )
912 {
913 ASProperty *prop = (ASProperty*)LISTELEM_DATA(curr) ;
914 switch( prop->id )
915 {
916 case INCLUDE_keepname_ID : /* OBSOLETE */ break ;
917 case INCLUDE_extension_ID :
918 if( extension ) free( extension );
919 extension = decode_string_alloc( prop->contents.data );
920 break ;
921 case INCLUDE_miniextension_ID :
922 if( mini_ext ) free( mini_ext );
923 mini_ext = decode_string_alloc( prop->contents.data );
924 break ;
925
926 case INCLUDE_minipixmap_ID : /* OBSOLETE */ break ;
927 case INCLUDE_command_ID : /* TODO */ break ;
928 case INCLUDE_order_ID :
929 dst_popup->order = prop->contents.integer ; break ;
930 case INCLUDE_RecentSubmenuItems_ID : /* TODO */ break ;
931 case INCLUDE_name_ID :
932 if( name ) free( name );
933 name = decode_string_alloc( prop->contents.data );
934 break ;
935 }
936 }
937 /* Pass 2 : including submenus : */
938 for( curr = LIST_START(incl->sub_props); curr != NULL ; LIST_GOTO_NEXT(curr) )
939 {
940 ASProperty *prop = (ASProperty*)LISTELEM_DATA(curr) ;
941 if( prop->id == INCLUDE_include_ID )
942 {
943 ASProperty *text_prop = find_property_by_id( prop, CONFIG_text_ID );
944 char *fullfilename = PutHome( prop->name );
945 int incl_func = func ;
946 ASProperty *sub_popup ;
947
948 LOCAL_DEBUG_OUT( "include \"%s\" with text_prop = %p", fullfilename, text_prop );
949
950 if( text_prop != NULL )
951 {
952 char *txt = decode_string_alloc( text_prop->contents.data );
953 if( txt )
954 {
955 TermDef *fd ;
956 if( (fd = txt2fterm( txt, False)) != NULL )
957 incl_func = fd->id ;
958 free( txt );
959 }
960 }
961 if( phony == NULL )
962 phony = create_property( CONFIG_StartDir_ID, ASProp_File, NULL, True );
963 LOCAL_DEBUG_OUT( "func = (%d) phony = %p, popup = %p", incl_func, phony, popup );
964 LOCAL_DEBUG_OUT( "popup->name = \"%s\"", popup->name );
965 sub_popup = asmenu_dir2property( fullfilename, popup->name, phony,
966 incl_func, extension, mini_ext );
967
968 LOCAL_DEBUG_OUT( "sub_popup = %p", sub_popup );
969 print_hierarchy( sub_popup, 0 );
970 if( sub_popup != NULL )
971 {
972 merge_property_list( sub_popup, dst_popup );
973 discard_bidirelem( phony->sub_props, sub_popup );
974 if( phony->sub_props->count > 0 )
975 {
976 melt_menu_props( phony, dst );
977 purge_asbidirlist( phony->sub_props );
978 }
979 }
980 free( fullfilename );
981 }
982 }
983 if( phony != NULL )
984 destroy_property( phony );
985 if( extension )
986 free( extension );
987 if( mini_ext )
988 free( mini_ext );
989 }
990 /* now we need to sort items according to order */
991 bubblesort_asbidirlist( dst_popup->sub_props, compare_menuitems_handler );
992 LOCAL_DEBUG_OUT( "sorted menu \"%s\"", dst_popup->name );
993 print_hierarchy( dst_popup, 0 );
994 /* and now we need to add F_TITLE item for menu name */
995 if( name == NULL )
996 {
997 int i = -1;
998 parse_file_name( dst_popup->name, NULL, &name );
999 if( name )
1000 while( name[++i] ) if( name[i] == '_' ) name[i] = ' ' ;
1001 }
1002 if( name )
1003 {
1004 ASProperty *title ;
1005 title = create_property( F_TITLE, ASProp_Phony, name, True );
1006 prepend_property( dst_popup, title );
1007 free( name );
1008 }
1009
1010 return True;
1011 }
1012
1013 void
melt_menu_props(ASProperty * src,ASProperty * dst)1014 melt_menu_props( ASProperty *src, ASProperty *dst )
1015 {
1016 if( src->sub_props == NULL || dst == NULL )
1017 return;
1018 LOCAL_DEBUG_CALLER_OUT("(%p,%p)", src, dst );
1019 iterate_asbidirlist( src->sub_props, melt_menu_props_into_list, dst, NULL, False );
1020 }
1021
1022 /*************************************************************************/
1023 Bool
melt_func_props_into_list(void * data,void * aux_data)1024 melt_func_props_into_list(void *data, void *aux_data)
1025 {
1026 ASProperty *func = (ASProperty*)data;
1027 ASProperty *dst = (ASProperty*)aux_data ;
1028 ASProperty *dst_func ;
1029 int index = 0 ;
1030 ASBiDirElem *curr = LIST_START(func->sub_props);
1031
1032
1033 dst_func = find_property_by_id_name( dst, func->id, func->name );
1034
1035 if( dst_func == NULL )
1036 {
1037 dst_func = dup_property( func, False );
1038 append_property( dst, dst_func );
1039 }
1040
1041 while( curr )
1042 {
1043 ASProperty *prop = (ASProperty*)LISTELEM_DATA(curr) ;
1044 ASProperty *copy ;
1045 copy = dup_property( prop, True );
1046 set_property_index( copy, index );
1047 append_property( dst_func, copy );
1048
1049 ++index ;
1050
1051 LIST_GOTO_NEXT(curr);
1052 }
1053 return True;
1054 }
1055
1056 void
melt_func_props(ASProperty * src,ASProperty * dst)1057 melt_func_props( ASProperty *src, ASProperty *dst )
1058 {
1059 if( src->sub_props == NULL || dst == NULL )
1060 return;
1061 LOCAL_DEBUG_CALLER_OUT("(%p,%p)", src, dst );
1062 iterate_asbidirlist( src->sub_props, melt_func_props_into_list, dst, NULL, False );
1063 }
1064 /*************************************************************************/
1065 void
melt_binding_props(ASProperty * src,ASProperty * dst)1066 melt_binding_props( ASProperty *src, ASProperty *dst )
1067 {
1068 LOCAL_DEBUG_CALLER_OUT("(%p,%p)", src, dst );
1069 if( src->sub_props != NULL && dst != NULL )
1070 {
1071 int index = 0 ;
1072 ASBiDirElem *curr = LIST_START(src->sub_props);
1073 while( curr )
1074 {
1075 ASProperty *prop = (ASProperty*)LISTELEM_DATA(curr) ;
1076 ASProperty *copy ;
1077 copy = dup_property( prop, True );
1078 set_property_index( copy, index );
1079 append_property( dst, copy );
1080
1081 ++index ;
1082
1083 LIST_GOTO_NEXT(curr);
1084 }
1085 }
1086 }
1087 /*************************************************************************/
1088 void load_global_configs();
1089 void add_module_config( const char *module_class, const char *module_name );
1090
1091
1092 void
load_hierarchy()1093 load_hierarchy()
1094 {
1095 Root = create_property( CONFIG_root_ID, ASProp_Phony, "", True );
1096
1097 load_global_configs();
1098 add_module_config( CLASS_AFTERSTEP, "afterstep" );
1099 add_module_config( CLASS_PAGER, "Pager" );
1100 add_module_config( CLASS_WINLIST, "WinList" );
1101 add_module_config( CLASS_WHARF, "Wharf" );
1102 }
1103
1104 /*************************************************************************/
1105 void
load_global_configs()1106 load_global_configs()
1107 {
1108 int i ;
1109 ASProperty *tmp ;
1110
1111 for( i = 0 ; ConfigTypeInfo[i].config_id != 0 ; ++i )
1112 {
1113 int k ;
1114 tmp = NULL ;
1115 for( k = 0 ; k < ConfigTypeInfo[i].config_file_ids_count ; ++k )
1116 {
1117 tmp = load_current_config( tmp,
1118 ConfigTypeInfo[i].config_id, NULL,
1119 ConfigTypeInfo[i].syntax,
1120 NULL,
1121 ConfigTypeInfo[i].config_files_id,
1122 ConfigTypeInfo[i].config_file_ids[k],
1123 ConfigTypeInfo[i].config_options_id);
1124 }
1125 if( tmp )
1126 append_property( Root, tmp );
1127 }
1128 }
1129
handle_module_syntaxes(ASProperty * owner,const char * module_name,ASModuleSyntax * syntaxes)1130 void handle_module_syntaxes( ASProperty *owner, const char *module_name, ASModuleSyntax *syntaxes )
1131 {
1132 int k ;
1133 ASProperty *tmp ;
1134 for( k = 0 ; syntaxes[k].config_id >= 0 ; ++k )
1135 {
1136 ASModuleSyntax *ms = &(syntaxes[k]);
1137 int l ;
1138
1139 if( ms->config_id == 0 )
1140 {
1141 load_current_config( owner,
1142 ms->config_id, module_name,
1143 ms->syntax,
1144 ms->special,
1145 0,
1146 ms->files[0],
1147 ms->config_options_id);
1148 }else
1149 {
1150 tmp = NULL ;
1151 for( l = 0 ; ms->files[l] >= 0 ; ++l )
1152 {
1153 tmp = load_current_config( tmp,
1154 ms->config_id, module_name,
1155 ms->syntax,
1156 ms->special,
1157 ms->config_files_id,
1158 ms->files[l],
1159 ms->config_options_id);
1160 }
1161 if( tmp )
1162 append_property( owner, tmp );
1163
1164 if( ms->subsyntaxes )
1165 handle_module_syntaxes( tmp, module_name, ms->subsyntaxes );
1166 }
1167 }
1168 }
1169
1170 void
add_module_config(const char * module_class,const char * module_name)1171 add_module_config( const char *module_class, const char *module_name )
1172 {
1173 int i ;
1174 ASProperty *config;
1175
1176 for( i = 0 ; ModulesSpecs[i].module_class != NULL ; ++i )
1177 if( mystrcmp( ModulesSpecs[i].module_class, module_class ) == 0 )
1178 {
1179 config = create_property( CONFIG_Module_ID, ASProp_Phony, module_name, True );
1180 append_property( Root, config );
1181
1182 handle_module_syntaxes( config, module_name, ModulesSpecs[i].syntaxes );
1183 }
1184 }
1185
1186
1187
1188 /*************************************************************************/
1189 void print_hierarchy( ASProperty *root, int level );
1190
1191 Bool
print_hierarchy_iter_func(void * data,void * aux_data)1192 print_hierarchy_iter_func(void *data, void *aux_data)
1193 {
1194 ASProperty *prop = (ASProperty*)data;
1195 int level = (int)aux_data ;
1196 print_hierarchy( prop, level );
1197 return True;
1198 }
1199
1200 void
print_hierarchy(ASProperty * root,int level)1201 print_hierarchy( ASProperty *root, int level )
1202 {
1203 int i ;
1204
1205 //LOCAL_DEBUG_CALLER_OUT("(%p,%d)",root, level );
1206
1207 if( root == NULL )
1208 return ;
1209
1210 for( i = 0 ; i < level ; ++i )
1211 fputc( '\t', stderr);
1212 fprintf( stderr, "%s(%ld) ", get_property_keyword( root ), root->id );
1213 if( root->order >= 0 )
1214 fprintf( stderr, "order=%d ", root->order );
1215 if( get_flags( root->flags, ASProp_Indexed ) )
1216 fprintf( stderr, "[%d] ", root->index );
1217 else if( root->name )
1218 fprintf( stderr, "\"%s\" ", root->name );
1219
1220 if( root->type == ASProp_Integer )
1221 fprintf( stderr, "= %d;", root->contents.integer );
1222 else if( root->type == ASProp_Data )
1223 {
1224 static char string[128] ;
1225 int bytes_out, orig_bytes ;
1226 /*LOCAL_DEBUG_OUT( "fetching data with id = %d", root->contents.data ); */
1227 bytes_out = decode_string( root->contents.data, &string[0], 128, &orig_bytes );
1228 /* LOCAL_DEBUG_OUT( "fetched %d bytes", bytes_out ); */
1229 if( bytes_out < orig_bytes )
1230 fprintf( stderr, "= %d of %d chars:", bytes_out, orig_bytes );
1231 else
1232 fprintf( stderr, "= ");
1233 fprintf( stderr, "\"%s\"", string );
1234 fputc( ';', stderr);
1235 }else if( root->type == ASProp_File )
1236 {
1237 if( root->contents.config_file )
1238 fprintf( stderr, "loaded from [%s]", root->contents.config_file->fullname );
1239 else
1240 fprintf( stderr, "not loaded" );
1241 }
1242
1243 fputc( '\n', stderr);
1244 if( root->sub_props )
1245 {
1246 iterate_asbidirlist( root->sub_props, print_hierarchy_iter_func, (void*)(level+1), NULL, False );
1247 }
1248
1249 }
1250
1251 void
handle_asconfig_command(char * buffer,int buffer_len,FILE * out_stream)1252 handle_asconfig_command(char *buffer, int buffer_len, FILE *out_stream)
1253 {
1254 ASXmlRPCPacket *packet = safecalloc( 1, sizeof(ASXmlRPCPacket) );
1255
1256 packet->xml = mystrndup(buffer, buffer_len) ;
1257 packet->size = packet->allocated_size = buffer_len ;
1258
1259 if( xml2rpc_packet( packet ) )
1260 {
1261 }else
1262 show_warning( "failed to parse rpc packet" );
1263 print_rpc_packet( packet ) ;
1264 destroy_rpc_packet( &packet );
1265 }
1266
interactive_loop()1267 void interactive_loop()
1268 {
1269 #define BUFFER_SIZE 8192
1270 char buffer[BUFFER_SIZE] ;
1271
1272 fprintf( stdout, "#" );
1273 while( fgets( &buffer[0], BUFFER_SIZE, stdin ) != NULL )
1274 {
1275 /* now we need to process the command */
1276 handle_asconfig_command(buffer, strlen(buffer)-1, stdout);
1277 fprintf( stdout, "#" );
1278 }
1279 }
1280