1 /*
2  * Copyright (C) 2000 Sasha Vasko <sasha at 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  */
19 
20 /**************************************************************************
21  *
22  * styledb management functionality
23  *
24  **************************************************************************/
25 
26 #define LOCAL_DEBUG
27 
28 #include "../configure.h"
29 #include "asapp.h"
30 #include "asdatabase.h"
31 
make_asdb_record(name_list * nl,struct wild_reg_exp * regexp,ASDatabaseRecord * reusable_memory)32 ASDatabaseRecord *make_asdb_record (name_list * nl,
33 																		struct wild_reg_exp *regexp,
34 																		ASDatabaseRecord * reusable_memory)
35 {
36 	ASDatabaseRecord *db_rec = NULL;
37 	register int i;
38 
39 	if (nl) {
40 		if (reusable_memory) {
41 			db_rec = reusable_memory;
42 			memset (db_rec, 0x00, sizeof (ASDatabaseRecord));
43 		} else
44 			db_rec =
45 					(ASDatabaseRecord *) safecalloc (1, sizeof (ASDatabaseRecord));
46 
47 		db_rec->magic = MAGIC_ASDBRECORD;
48 
49 		db_rec->regexp = regexp;
50 
51 		db_rec->set_flags = nl->set_flags;
52 		db_rec->flags = nl->flags;
53 		db_rec->set_data_flags = nl->set_data_flags;
54 		/* TODO: implement set_buttons/buttons in name_list as well */
55 		db_rec->set_buttons = nl->on_buttons | nl->off_buttons;
56 		db_rec->buttons = nl->on_buttons;
57 
58 		if (db_rec->set_buttons != 0)
59 			set_flags (db_rec->set_flags, STYLE_BUTTONS);
60 
61 		db_rec->default_geometry = nl->default_geometry;
62 		db_rec->desk = nl->Desk;
63 		db_rec->layer = nl->layer;
64 		db_rec->viewport_x = nl->ViewportX;
65 		LOCAL_DEBUG_OUT ("nl->name = \"%s\", nl->ViewportX = %d", nl->name,
66 										 nl->ViewportX);
67 		db_rec->viewport_y = nl->ViewportY;
68 		db_rec->border_width = nl->border_width;
69 		db_rec->resize_width = nl->resize_width;
70 		db_rec->gravity = nl->gravity;
71 		db_rec->window_opacity = nl->window_opacity;
72 
73 		if (nl->icon_file) {
74 			db_rec->icon_file = nl->icon_file;
75 			nl->icon_file = NULL;
76 		}
77 		if (nl->frame_name) {
78 			db_rec->frame_name = nl->frame_name;
79 			nl->frame_name = NULL;
80 		}
81 		if (nl->windowbox_name) {
82 			db_rec->windowbox_name = nl->windowbox_name;
83 			nl->windowbox_name = NULL;
84 		}
85 		for (i = 0; i < BACK_STYLES; i++)
86 			if (nl->window_styles[i]) {
87 				db_rec->window_styles[i] = nl->window_styles[i];
88 				nl->window_styles[i] = NULL;
89 				set_flags (db_rec->set_flags, STYLE_MYSTYLES);
90 			}
91 		db_rec->own_strings = True;
92 	}
93 	return db_rec;
94 }
95 
build_matching_list(ASDatabase * db,char ** names)96 static Bool build_matching_list (ASDatabase * db, char **names)
97 {
98 	int last = 0;
99 
100 	if (db && names && db->match_list) {
101 		register int i = 0;
102 
103 		for (; i < db->styles_num; ++i) {
104 			register int k = 0;
105 
106 			if (i == db->default_styles_idx)
107 				db->match_list[last++] = db->styles_num;	/* for the default style */
108 			for (; names[k]; ++k)
109 				if (match_wild_reg_exp (names[k], db->styles_table[i].regexp) == 0) {
110 					db->match_list[last++] = i;
111 					break;
112 				}
113 		}
114 		if (i <= db->default_styles_idx)
115 			db->match_list[last++] = db->styles_num;	/* for the default style */
116 		db->match_list[last] = -1;
117 	}
118 	return (last > 0);
119 }
120 
121 typedef enum {
122 	MATCH_Flags = STYLE_FLAGS,
123 	MATCH_Buttons = STYLE_BUTTONS,
124 
125 	MATCH_Desk = STYLE_STARTUP_DESK,
126 	MATCH_layer = STYLE_LAYER,
127 	MATCH_ViewportX = STYLE_VIEWPORTX,
128 	MATCH_ViewportY = STYLE_VIEWPORTY,
129 	MATCH_border_width = STYLE_BORDER_WIDTH,
130 	MATCH_resize_width = STYLE_HANDLE_WIDTH,
131 	MATCH_gravity = STYLE_GRAVITY,
132 	MATCH_window_opacity = STYLE_WINDOW_OPACITY,
133 	MATCH_DefaultGeometry = STYLE_DEFAULT_GEOMETRY,
134 
135 	MATCH_Icon = STYLE_ICON,
136 	MATCH_Frame = STYLE_FRAME,
137 	MATCH_Windowbox = STYLE_WINDOWBOX,
138 	MATCH_MyStyle = STYLE_MYSTYLES
139 } DBMatchType;
140 
get_asdb_record(ASDatabase * db,int index)141 ASDatabaseRecord *get_asdb_record (ASDatabase * db, int index)
142 {
143 	if (db) {
144 		if (index < 0 || index >= db->styles_num)
145 			return &(db->style_default);
146 		return &(db->styles_table[index]);
147 	}
148 	return NULL;
149 }
150 
is_default_asdb_record(ASDatabase * db,ASDatabaseRecord * db_rec)151 Bool is_default_asdb_record (ASDatabase * db, ASDatabaseRecord * db_rec)
152 {
153 	return (db && &(db->style_default) == db_rec);
154 }
155 
156 static void
match_flags(unsigned long * pset_flags,unsigned long * pflags,ASDatabase * db,DBMatchType type)157 match_flags (unsigned long *pset_flags, unsigned long *pflags,
158 						 ASDatabase * db, DBMatchType type)
159 {
160 	if (pset_flags && pflags) {
161 		unsigned long curr_set_flags, on_flags;
162 		register ASDatabaseRecord *db_rec;
163 		register int i = 0;
164 
165 		for (i = 0; db->match_list[i] >= 0; ++i) {
166 			db_rec = get_asdb_record (db, db->match_list[i]);
167 			curr_set_flags =
168 					(type ==
169 					 MATCH_Buttons) ? db_rec->set_buttons : db_rec->set_flags;
170 			on_flags = (type == MATCH_Buttons) ? db_rec->buttons : db_rec->flags;
171 			/* we should not touch flags that are already set - sure we do ! */
172 /* 			clear_flags (*pflags, get_flags (off_flags, ~(*pset_flags)));
173 			set_flags (*pflags, get_flags (on_flags, ~(*pset_flags)));
174 */
175 			clear_flags (*pflags, curr_set_flags);
176 			set_flags (*pflags, on_flags);
177 			set_flags (*pset_flags, curr_set_flags);
178 		}
179 	}
180 }
181 
match_data_flags(unsigned long * pset_flags,ASDatabase * db)182 static void match_data_flags (unsigned long *pset_flags, ASDatabase * db)
183 {
184 	if (pset_flags) {
185 		register ASDatabaseRecord *db_rec;
186 		register int i = 0;
187 
188 		for (i = 0; db->match_list[i] >= 0; ++i) {
189 			db_rec = get_asdb_record (db, db->match_list[i]);
190 			set_flags (*pset_flags, db_rec->set_data_flags);
191 		}
192 	}
193 }
194 
195 
match_int(ASDatabase * db,DBMatchType type)196 static int match_int (ASDatabase * db, DBMatchType type)
197 {
198 	register ASDatabaseRecord *db_rec;
199 	register int i = 0;
200 	int value = 0;
201 
202 	for (i = 0; db->match_list[i] >= 0; ++i) {
203 		db_rec = get_asdb_record (db, db->match_list[i]);
204 		if (get_flags (db_rec->set_data_flags, type)) {
205 			switch (type) {
206 			case MATCH_Desk:
207 				value = db_rec->desk;
208 				break;
209 			case MATCH_layer:
210 				value = db_rec->layer;
211 				break;
212 			case MATCH_ViewportX:
213 				LOCAL_DEBUG_OUT ("viewport_x = %d", db_rec->viewport_x);
214 				value = db_rec->viewport_x;
215 				break;
216 			case MATCH_ViewportY:
217 				value = db_rec->viewport_y;
218 				break;
219 			case MATCH_border_width:
220 				value = db_rec->border_width;
221 				break;
222 			case MATCH_resize_width:
223 				value = db_rec->resize_width;
224 				break;
225 			case MATCH_gravity:
226 				value = db_rec->gravity;
227 				break;
228 			case MATCH_window_opacity:
229 				value = db_rec->window_opacity;
230 				break;
231 			default:
232 				break;
233 			}
234 		}
235 	}
236 	return value;
237 }
238 
match_struct(ASDatabase * db,DBMatchType type)239 static void *match_struct (ASDatabase * db, DBMatchType type)
240 {
241 	register ASDatabaseRecord *db_rec;
242 	register int i = 0;
243 	void *value = NULL;
244 
245 	for (i = 0; db->match_list[i] >= 0; ++i) {
246 		db_rec = get_asdb_record (db, db->match_list[i]);
247 		if (get_flags (db_rec->set_data_flags, type)) {
248 			switch (type) {
249 			case MATCH_DefaultGeometry:
250 				value = &(db_rec->default_geometry);
251 				break;
252 			default:
253 				break;
254 			}
255 		}
256 	}
257 	return value;
258 }
259 
260 
match_string(ASDatabase * db,DBMatchType type,unsigned int index,Bool dup_strings)261 static char *match_string (ASDatabase * db, DBMatchType type,
262 													 unsigned int index, Bool dup_strings)
263 {
264 	char *res = NULL;
265 	register ASDatabaseRecord *db_rec;
266 	register int i = 0;
267 
268 	for (i = 0; db->match_list[i] >= 0; ++i) {
269 		db_rec = get_asdb_record (db, db->match_list[i]);
270 		if (get_flags (db_rec->set_data_flags, type)) {
271 			switch (type) {
272 			case MATCH_Icon:
273 				res = db_rec->icon_file;
274 				break;
275 			case MATCH_Frame:
276 				res = db_rec->frame_name;
277 				break;
278 			case MATCH_Windowbox:
279 				res = db_rec->windowbox_name;
280 				break;
281 			case MATCH_MyStyle:
282 				res = db_rec->window_styles[(index < BACK_STYLES) ? index : 0];
283 				break;
284 			default:
285 				break;
286 			}
287 		}
288 	}
289 	if (res != NULL && dup_strings)
290 		res = mystrdup (res);
291 	return res;
292 }
293 
294 /* NULL terminated list of names/aliases sorted in order of descending importance */
fill_asdb_record(ASDatabase * db,char ** names,ASDatabaseRecord * reusable_memory,Bool dup_strings)295 ASDatabaseRecord *fill_asdb_record (ASDatabase * db, char **names,
296 																		ASDatabaseRecord * reusable_memory,
297 																		Bool dup_strings)
298 {
299 	ASDatabaseRecord *db_rec = NULL;
300 
301 	if (db && names) {
302 		if (reusable_memory) {
303 			db_rec = reusable_memory;
304 			memset (db_rec, 0x00, sizeof (ASDatabaseRecord));
305 		} else
306 			db_rec =
307 					(ASDatabaseRecord *) safecalloc (1, sizeof (ASDatabaseRecord));
308 
309 		db_rec->magic = MAGIC_ASDBRECORD;
310 
311 		/* TODO : */
312 		/* build list of matching styles in order of descending importance */
313 		if (build_matching_list (db, names)) {	/* go through the list trying to extract as much data as possible  */
314 			register int i;
315 
316 			match_flags (&(db_rec->set_flags), &(db_rec->flags), db,
317 									 MATCH_Flags);
318 			if (get_flags (db_rec->set_flags, STYLE_BUTTONS))
319 				match_flags (&(db_rec->set_buttons), &(db_rec->buttons), db,
320 										 MATCH_Buttons);
321 
322 			match_data_flags (&(db_rec->set_data_flags), db);
323 
324 			if (get_flags (db_rec->set_data_flags, STYLE_STARTUP_DESK))
325 				db_rec->desk = match_int (db, MATCH_Desk);
326 			if (get_flags (db_rec->set_data_flags, STYLE_LAYER))
327 				db_rec->layer = match_int (db, MATCH_layer);
328 			if (get_flags (db_rec->set_data_flags, STYLE_VIEWPORTX)) {
329 				LOCAL_DEBUG_OUT ("Matching viewport_x%s", "");
330 				db_rec->viewport_x = match_int (db, MATCH_ViewportX);
331 			}
332 			if (get_flags (db_rec->set_data_flags, STYLE_VIEWPORTY))
333 				db_rec->viewport_y = match_int (db, MATCH_ViewportY);
334 			if (get_flags (db_rec->set_data_flags, STYLE_BORDER_WIDTH))
335 				db_rec->border_width = match_int (db, MATCH_border_width);
336 			if (get_flags (db_rec->set_data_flags, STYLE_HANDLE_WIDTH))
337 				db_rec->resize_width = match_int (db, MATCH_resize_width);
338 			if (get_flags (db_rec->set_data_flags, STYLE_GRAVITY))
339 				db_rec->gravity = match_int (db, MATCH_gravity);
340 			if (get_flags (db_rec->set_data_flags, STYLE_WINDOW_OPACITY))
341 				db_rec->window_opacity = match_int (db, MATCH_window_opacity);
342 
343 			if (get_flags (db_rec->set_data_flags, STYLE_DEFAULT_GEOMETRY))
344 				db_rec->default_geometry =
345 						*((ASGeometry *) match_struct (db, MATCH_DefaultGeometry));
346 
347 			if (get_flags (db_rec->set_data_flags, STYLE_ICON))
348 				db_rec->icon_file = match_string (db, MATCH_Icon, 0, dup_strings);
349 			if (get_flags (db_rec->set_data_flags, STYLE_FRAME))
350 				db_rec->frame_name =
351 						match_string (db, MATCH_Frame, 0, dup_strings);
352 			if (get_flags (db_rec->set_data_flags, STYLE_WINDOWBOX))
353 				db_rec->windowbox_name =
354 						match_string (db, MATCH_Windowbox, 0, dup_strings);
355 			if (get_flags (db_rec->set_flags, STYLE_MYSTYLES))
356 				for (i = 0; i < BACK_STYLES; i++)
357 					if (db_rec->window_styles[i])
358 						db_rec->window_styles[i] =
359 								match_string (db, MATCH_MyStyle, i, dup_strings);
360 		}
361 	}
362 	return db_rec;
363 }
364 
destroy_asdb_record(ASDatabaseRecord * rec,Bool reusable)365 void destroy_asdb_record (ASDatabaseRecord * rec, Bool reusable)
366 {
367 	if (rec == NULL)
368 		return;
369 	if (rec->magic == MAGIC_ASDBRECORD && rec->own_strings) {
370 		register int i;
371 
372 		rec->magic = 0;
373 
374 		if (rec->regexp)
375 			destroy_wild_reg_exp (rec->regexp);
376 
377 		if (rec->icon_file)
378 			free (rec->icon_file);
379 		if (rec->frame_name)
380 			free (rec->frame_name);
381 		if (rec->windowbox_name)
382 			free (rec->windowbox_name);
383 		for (i = 0; i < BACK_STYLES; i++)
384 			if (rec->window_styles[i])
385 				free (rec->window_styles[i]);
386 	}
387 	if (reusable)
388 		memset (rec, 0x00, sizeof (ASDatabaseRecord));	/* we are being paranoid */
389 	else
390 		free (rec);
391 }
392 
393 static Bool											/* returns True if record is completely new */
replace_record(ASDatabaseRecord * trg,name_list * nl,wild_reg_exp * regexp)394 replace_record (ASDatabaseRecord * trg, name_list * nl,
395 								wild_reg_exp * regexp)
396 {
397 	Bool res = True;
398 
399 	if (trg->magic == MAGIC_ASDBRECORD) {
400 		destroy_asdb_record (trg, True);
401 		res = False;
402 	}
403 
404 	trg = make_asdb_record (nl, regexp, trg);
405 	return res;
406 }
407 
place_new_record(ASDatabase * db,wild_reg_exp * regexp)408 static int place_new_record (ASDatabase * db, wild_reg_exp * regexp)
409 {
410 	int res = -1;
411 
412 	if (db && regexp) {
413 		register int i;
414 		ASDatabaseRecord *tmp;
415 
416 		/* we have to find a location for regexp, by comparing it to others.
417 		 * longer regexps should go first.
418 		 * If we find exactly the same regexp - then we replace record.
419 		 * Otherwise we reallocate space as needed.
420 		 */
421 		/* No we fucking don't! DB entries should be stored in the same order
422 		   as they are in the file ! I can't belive I was so fucking stupid !
423 		   All we should check for is if the regexp is already in the list. */
424 
425 		for (i = 0; i < db->styles_num; i++) {
426 			res = compare_wild_reg_exp (db->styles_table[i].regexp, regexp);
427 			if (res == 0)
428 				return i;
429 			/* see above comment else if (res < 0)
430 			   break;
431 			 */
432 		}
433 
434 		res = i;
435 
436 		if (db->allocated_num < db->styles_num + 1) {	/* reallocating memory as needed : */
437 			db->allocated_num = db->styles_num + 1;
438 			/* we always want to allocate a little more space to prevent too many reallocs */
439 			db->allocated_num += db->allocated_num >> 1;
440 			tmp =
441 					(ASDatabaseRecord *) safecalloc (db->allocated_num,
442 																					 sizeof (ASDatabaseRecord));
443 			if (db->styles_table && res > 0)
444 				memcpy (tmp, db->styles_table, sizeof (ASDatabaseRecord) * res);
445 		} else											/* we can use the same memory */
446 			tmp = db->styles_table;
447 
448 		/* freeing up space by shifting elements ahead by 1 : */
449 		if (db->styles_table) {
450 			register int k;
451 
452 			for (k = db->styles_num; k > i; k--)
453 				memcpy (&(tmp[k]), &(db->styles_table[k - 1]),
454 								sizeof (ASDatabaseRecord));
455 			if (k < db->styles_num)
456 				tmp[k].magic = 0;				/* invalidating record */
457 		}
458 
459 		if (db->styles_table != tmp) {
460 			if (db->styles_table != NULL)
461 				free (db->styles_table);
462 			db->styles_table = tmp;
463 		}
464 	}
465 	return res;
466 }
467 
build_asdb(name_list * nl)468 ASDatabase *build_asdb (name_list * nl)
469 {
470 	ASDatabase *db = NULL;
471 
472 	if (nl)
473 		db = (ASDatabase *) safecalloc (1, sizeof (ASDatabase));
474 
475 	while (nl) {
476 		wild_reg_exp *regexp;
477 
478 		if ((regexp = compile_wild_reg_exp (nl->name)) != NULL) {
479 			/* First check if that is the default style */
480 			if (strcmp ((char *)regexp->raw, "*") == 0) {
481 				destroy_wild_reg_exp (regexp);
482 				replace_record (&(db->style_default), nl, NULL);
483 				db->default_styles_idx = db->styles_num;
484 			} else {
485 				int where;
486 
487 				/* we have to find the place of this regexp among other
488 				 * in order of decreasing length
489 				 */
490 				where = place_new_record (db, regexp);
491 				if (where >= 0)
492 					if (replace_record (&(db->styles_table[where]), nl, regexp))
493 						db->styles_num++;
494 			}
495 		}
496 		nl = nl->next;
497 	}
498 	if (db) {
499 		if (db->styles_num < db->allocated_num) {
500 			db->allocated_num = db->styles_num;
501 			if (db->styles_num == 0) {
502 				free (db->styles_table);
503 				db->styles_table = NULL;
504 			} else
505 				db->styles_table = (ASDatabaseRecord *) realloc (db->styles_table,
506 																												 db->allocated_num
507 																												 *
508 																												 sizeof
509 																												 (ASDatabaseRecord));
510 		}
511 		db->match_list =
512 				(int *)safecalloc (1 + db->styles_num + 1, sizeof (int));
513 		db->match_list[0] = -1;
514 	}
515 	return db;
516 }
517 
destroy_asdb(ASDatabase ** db)518 void destroy_asdb (ASDatabase ** db)
519 {
520 	if (*db) {
521 		if ((*db)->styles_table) {
522 			register int i;
523 
524 			for (i = 0; i < (*db)->styles_num; i++)
525 				destroy_asdb_record (&((*db)->styles_table[i]), True);
526 			free ((*db)->styles_table);
527 		}
528 		destroy_asdb_record (&((*db)->style_default), True);
529 		free ((*db)->match_list);
530 		free (*db);
531 		*db = NULL;
532 	}
533 }
534 
535 /************************************************************************************
536  * Printing functions
537  ************************************************************************************/
538 void
print_asgeometry(stream_func func,void * stream,ASGeometry * g,const char * prompt1,const char * prompt2)539 print_asgeometry (stream_func func, void *stream, ASGeometry * g,
540 									const char *prompt1, const char *prompt2)
541 {
542 	if (!pre_print_check (&func, &stream, g, NULL))
543 		return;
544 	func (stream, "%s.%s.flags = 0x%lX;\n", prompt1, prompt2, g->flags);
545 	if (get_flags (g->flags, XValue))
546 		func (stream, "%s.%s.x = %d;\n", prompt1, prompt2, g->x);
547 	if (get_flags (g->flags, YValue))
548 		func (stream, "%s.%s.y = %d;\n", prompt1, prompt2, g->y);
549 	if (get_flags (g->flags, WidthValue))
550 		func (stream, "%s.%s.width = %d;\n", prompt1, prompt2, g->width);
551 	if (get_flags (g->flags, HeightValue))
552 		func (stream, "%s.%s.width = %d;\n", prompt1, prompt2, g->height);
553 }
554 
555 void
print_asdb_record(stream_func func,void * stream,ASDatabaseRecord * db_rec,const char * prompt)556 print_asdb_record (stream_func func, void *stream,
557 									 ASDatabaseRecord * db_rec, const char *prompt)
558 {
559 	register int i;
560 
561 	if (!pre_print_check (&func, &stream, db_rec, NULL))
562 		return;
563 	if (db_rec->regexp)
564 		func (stream, "%s.regexp = \"%s\";\n", prompt, db_rec->regexp->raw);
565 	else
566 		func (stream, "%s.regexp = \"*\";\n", prompt);
567 
568 	func (stream, "%s.set_flags = 0x%lX;\n", prompt, db_rec->set_flags);
569 	func (stream, "%s.flags = 0x%lX;\n", prompt, db_rec->flags);
570 	if (get_flags (db_rec->set_flags, STYLE_BUTTONS)) {
571 		func (stream, "%s.set_buttons = 0x%lX;\n", prompt,
572 					db_rec->set_buttons);
573 		func (stream, "%s.buttons = 0x%lX;\n", prompt, db_rec->buttons);
574 	}
575 	func (stream, "%s.set_data_flags = 0x%lX;\n", prompt,
576 				db_rec->set_data_flags);
577 
578 	if (get_flags (db_rec->set_data_flags, STYLE_DEFAULT_GEOMETRY))
579 		print_asgeometry (func, stream, &(db_rec->default_geometry), prompt,
580 											"default_geometry");
581 
582 	if (get_flags (db_rec->set_data_flags, STYLE_STARTUP_DESK))
583 		func (stream, "%s.desk = %d;\n", prompt, db_rec->desk);
584 	if (get_flags (db_rec->set_data_flags, STYLE_LAYER))
585 		func (stream, "%s.layer = %d;\n", prompt, db_rec->layer);
586 	if (get_flags (db_rec->set_data_flags, STYLE_VIEWPORTX))
587 		func (stream, "%s.viewport_x = %d;\n", prompt, db_rec->viewport_x);
588 	if (get_flags (db_rec->set_data_flags, STYLE_VIEWPORTY))
589 		func (stream, "%s.viewport_y = %d;\n", prompt, db_rec->viewport_y);
590 	if (get_flags (db_rec->set_data_flags, STYLE_BORDER_WIDTH))
591 		func (stream, "%s.border_width = %u;\n", prompt, db_rec->border_width);
592 	if (get_flags (db_rec->set_data_flags, STYLE_HANDLE_WIDTH))
593 		func (stream, "%s.resize_width = %u;\n", prompt, db_rec->resize_width);
594 	if (get_flags (db_rec->set_data_flags, STYLE_GRAVITY))
595 		func (stream, "%s.gravity = %u;\n", prompt, db_rec->gravity);
596 	if (get_flags (db_rec->set_data_flags, STYLE_WINDOW_OPACITY))
597 		func (stream, "%s.window_opacity = %u;\n", prompt,
598 					db_rec->window_opacity);
599 
600 	if (db_rec->icon_file)
601 		func (stream, "%s.icon_file = \"%s\";\n", prompt, db_rec->icon_file);
602 	if (db_rec->frame_name)
603 		func (stream, "%s.frame_name = \"%s\";\n", prompt, db_rec->frame_name);
604 	if (db_rec->windowbox_name)
605 		func (stream, "%s.windowbox_name = \"%s\";\n", prompt,
606 					db_rec->windowbox_name);
607 	for (i = 0; i < BACK_STYLES; i++)
608 		if (db_rec->window_styles[i])
609 			func (stream, "%s.MyStyle[%d] = \"%s\";\n", prompt, i,
610 						db_rec->window_styles[i]);
611 
612 	func (stream, "%s.own_strings = %d;\n", prompt, db_rec->own_strings);
613 }
614 
615 void
print_asdb_match_list(stream_func func,void * stream,ASDatabase * db)616 print_asdb_match_list (stream_func func, void *stream, ASDatabase * db)
617 {
618 	register ASDatabaseRecord *db_rec;
619 	register int i;
620 
621 	if (!pre_print_check
622 			(&func, &stream, db, "ASDatabase unavailable(NULL)!"))
623 		return;
624 
625 	for (i = 0; db->match_list[i] >= 0; i++) {
626 		db_rec = get_asdb_record (db, db->match_list[i]);
627 		if (db_rec->regexp)
628 			func (stream, "ASDB.match_list[%d].regexp = \"%s\";\n", i,
629 						db_rec->regexp->raw);
630 		else if (is_default_asdb_record (db, db_rec))
631 			func (stream, "ASDB.match_list[%d].regexp = \"*\";\n", i);
632 	}
633 }
634 
print_asdb(stream_func func,void * stream,ASDatabase * db)635 void print_asdb (stream_func func, void *stream, ASDatabase * db)
636 {
637 	char prompt[128];
638 	register int i;
639 
640 	if (!pre_print_check
641 			(&func, &stream, db, "ASDatabase unavailable(NULL)!"))
642 		return;
643 
644 	func (stream, "ASDB.allocated_num = %d;\n", db->allocated_num);
645 	func (stream, "ASDB.styles_num = %d;\n", db->styles_num);
646 
647 	for (i = 0; i < db->styles_num; i++) {
648 		sprintf (prompt, "ASDB.styles_table[%d]", i);
649 		print_asdb_record (func, stream, &(db->styles_table[i]), prompt);
650 	}
651 	print_asdb_record (func, stream, &(db->style_default),
652 										 "ASDB.style_default");
653 	print_asdb_match_list (func, stream, db);
654 }
655 
656 void
print_asdb_matched_rec(stream_func func,void * stream,ASDatabase * db,ASDatabaseRecord * db_rec)657 print_asdb_matched_rec (stream_func func, void *stream, ASDatabase * db,
658 												ASDatabaseRecord * db_rec)
659 {
660 	if (db == NULL || !pre_print_check (&func, &stream, db, "No matches!"))
661 		return;
662 	print_asdb_record (func, stream, db_rec, "MATCHED_RECORD");
663 	print_asdb_match_list (func, stream, db);
664 }
665