Subject: DestroyStyle command patch

From: Neil Bird <[email-masked]>
Date: Wed, 08 Sep 1999 12:34:09 +0100

In top-level dir:

  patch -p0 -b < DestroyPatch.patch

  I recommend trying it out for a couple of hours, just in case, but I've
not had any problems with it, so I'm pretty certain that my Style memory
free()s are OK.

  If 'DestroyStyle *' doesn't stuff things up, I doubt anything will :-)

-- 
=====================- http://www.racaldefence.com/ -===================
 Neil Bird                   |   This is who we are     The time is near
                             |
 mailto:[email-masked] |        There are 115 days remaining

--- ChangeLog.orig	Mon Sep  6 12:30:07 1999
+++ ChangeLog	Wed Sep  8 10:07:01 1999
@@ -1,3 +1,8 @@
+1999-09-08  Neil Bird  <[email-masked]>
+
+	* fvwm/{functions.c,functions.h,fvwm2.1,style.c,style.h}:
+	  Add DestroyStyle command, and [try to] remove Style memory leaks.
+
 1999-09-06  Dominik Vogt  <[email-masked]>
 
 	* fvwm/fvwm.h: add check for gcc specific stuff (bug #454)
--- AUTHORS.orig	Tue Aug 17 12:30:05 1999
+++ AUTHORS	Wed Sep  8 10:10:06 1999
@@ -16,6 +16,11 @@
 Echo. Improve modules: Make FvwmM4 pass args on to m4, font-related
 seg-fault bug fix in FvwmButtons
 
+Neil Bird:
+Add $c, $r, $n variables for Functions.
+Add Next/Prev conditions to WindowId and WindowList.
+Attempted fix of OLDecor hints use for decorations. Add DestroyStyle command.
+
 Matthias Clasen:
 Session management, layered stacking order, maximized shaded windows,
 FvwmGtk module, colored and xpm cursors.
@@ -115,7 +120,6 @@
 John Aughey
 Graham Barr
 David Barth
-Neil Bird
 Mike Blatchley
 Mark Boyns
 Eli Burke
--- fvwm/functions.c.orig	Wed Aug 18 12:30:21 1999
+++ fvwm/functions.c	Wed Sep  8 09:47:20 1999
@@ -147,6 +147,7 @@
   {"destroymenu",  destroy_menu,     F_DESTROY_MENU,        0},
   {"destroymenustyle", DestroyMenuStyle, F_DESTROY_MENUSTYLE,0},
   {"destroymoduleconfig", DestroyModConfig, F_DESTROY_MOD,  0},
+  {"destroystyle", ProcessDestroyStyle,  F_DESTROY_STYLE,   0},
   {"direction",    DirectionFunc,    F_DIRECTION,           0},
   {"echo",         echo_func,        F_ECHO,                0},
   {"edgeresistance",SetEdgeResistance,F_EDGE_RES,           0},
--- fvwm/functions.h.orig	Wed Aug 18 12:30:21 1999
+++ fvwm/functions.h	Tue Sep  7 16:20:56 1999
@@ -114,6 +114,7 @@
   F_DESTROY_FUNCTION,
   F_DESTROY_MENU,
   F_DESTROY_MENUSTYLE,
+  F_DESTROY_STYLE,
   F_DFLT_COLORS,
   F_DFLT_FONT,
   F_DFLT_ICON,
--- fvwm/fvwm2.1.orig	Mon Sep  6 12:30:22 1999
+++ fvwm/fvwm2.1	Wed Sep  8 10:03:01 1999
@@ -3374,6 +3374,24 @@

 .TP
+.B "DestroyStyle" "\fIstyle\fP"
+Deletes the style named "\fIstyle\fP". This will not affect currently visible
+windows (they each have a copy of their styles, which will remain unaffected).
+Note that \fPstyle\fP is not a wild-carded search string, but rather a
+case-sensitive string that should exactly match the original \fBStyle\fP
+command.
+
+Destroying style \fI*\fP can be done, but isn't really to be recommended!
+For example:
+.EX
+DestroyStyle Application*
+.EE
+
+This will remove all settings for the style named "\fIApplication*\fP", NOT all
+styles starting with "Application".
+
+
+.TP
 .B "TitleStyle" "[\fIjustification\fP] [\fIheight num\fP]"
 Sets attributes for the title bar.  Justifications can be "Centered",
 "RightJustified," or "LeftJustified."  \fIheight\fP sets the title
--- fvwm/style.c.orig	Thu Sep  2 12:30:23 1999
+++ fvwm/style.c	Wed Sep  8 09:48:53 1999
@@ -178,6 +178,7 @@
   return;
 }
 
+
 static void add_style_to_list(window_style *new_style)
 {
   window_style *nptr;
@@ -201,6 +202,77 @@
   last_style_in_list = nptr;
 } /* end function */
 
+
+#define SAFEFREE( p )  {if (p)  free(p);}
+
+static void remove_all_of_style_from_list(char *style_ref)
+{
+  window_style *nptr = all_styles, *lptr = NULL;
+
+  /* loop though styles */
+  while (nptr)
+  {
+    /* Check if it's to be wiped */
+    if (!strcmp( nptr->name, style_ref ))
+    {
+      window_style *tmp_ptr = nptr;
+
+      /* Reset nptr now */
+      nptr = nptr->next;
+
+      /* Is it the first one? */
+      if (NULL == lptr)
+      {
+        /* Yup - reset all_styles */
+        all_styles = nptr;
+      }
+      else
+      {
+        /* Middle of list */
+        lptr->next = nptr;
+      }
+
+      /* Free contents of style */
+      SAFEFREE( tmp_ptr->name );
+      SAFEFREE( tmp_ptr->back_color_name );
+      SAFEFREE( tmp_ptr->fore_color_name );
+      SAFEFREE( tmp_ptr->mini_icon_name );
+      SAFEFREE( tmp_ptr->decor_name );
+      SAFEFREE( tmp_ptr->icon_name );
+
+      /* Free style */
+      free( tmp_ptr );
+    }
+    else
+    {
+      /* No match - move on */
+      lptr = nptr;
+      nptr = nptr->next;
+    }
+  }
+
+} /* end function */
+
+
+/* Remove a style. */
+void ProcessDestroyStyle( XEvent *eventp, Window w, FvwmWindow *tmp_win,
+                          unsigned long context,char *action, int *Module )
+{
+  char *name;
+
+  /* parse style name */
+  action = GetNextToken(action, &name);
+
+  /* in case there was no argument! */
+  if(name == NULL)
+    return;
+
+  /* Do it */
+  remove_all_of_style_from_list( name );
+  free( name );
+}
+
+
 /***********************************************************************
  *
  *  Procedure:
@@ -282,7 +354,7 @@
 /* Process a style command.  First built up in a temp area.
    If valid, added to the list in a malloced area. */
 void ProcessNewStyle(XEvent *eventp, Window w, FvwmWindow *tmp_win,
-		     unsigned long context, char *action, int *Module)
+                     unsigned long context,char *action, int *Module )
 {
   char *line;
   char *option;
@@ -316,9 +388,7 @@
     return;
   if(action == NULL)
     {
-#if 0
       free(tmpstyle.name);
-#endif
       return;
     }
   while (isspace((unsigned char)*action))
@@ -333,9 +403,7 @@
     token = PeekToken(option, &rest);
     if (!token)
     {
-#if 0
       free(option);
-#endif
       break;
     }
 
@@ -343,6 +411,7 @@
      * case, and use strcmp, but there aren't many caseless compares
      * because of this "switch" on the first letter. */
     found = False;
+
     switch (tolower(token[0]))
     {
       case 'a':
@@ -617,7 +686,7 @@
         }
         else if(StrEquals(token, "IconBox"))
         {
-          icon_boxes *IconBoxes = 0;
+          icon_boxes *IconBoxes = NULL;
 
 	  found = True;
           IconBoxes = (icon_boxes *)safemalloc(sizeof(icon_boxes));
@@ -679,9 +748,7 @@
                 "IconBox requires 4 numbers or geometry! Invalid string <%s>.",
                          token);
 		/* Drop the box */
-#if 0
                 free(IconBoxes);
-#endif
 		/* forget about it */
                 IconBoxes = 0;
               } else {
@@ -713,9 +780,7 @@
                        "IconBox requires 4 numbers or geometry! Too long (%d).",
                        l);
 	      /* Drop the box */
-#if 0
               free(IconBoxes);
-#endif
 	      /* forget about it */
               IconBoxes = 0;
             } /* end word found, not too long */
@@ -1363,10 +1428,14 @@
       fvwm_msg(ERR,"ProcessNewStyle", "bad style command: %s", option);
       /* Can't return here since all malloced memory will be lost. Ignore rest
        * of line instead. */
-#if 0
+
+      /* No, I think we /can/ return here.
+       * In fact, /not/ bombing out leaves a half-done style in the list!
+       * N.Bird 07-Sep-1999
+       */
+      free(tmpstyle.name);
       free(option);
-#endif
-      break;
+      return;
     }
     free(option);
   } /* end while still stuff on command */
--- fvwm/style.h.orig	Thu Sep  2 12:30:24 1999
+++ fvwm/style.h	Tue Sep  7 16:46:55 1999
@@ -101,6 +101,7 @@
 
 /* function prototypes */
 void ProcessNewStyle(F_CMD_ARGS);
+void ProcessDestroyStyle(F_CMD_ARGS);
 void lookup_style(FvwmWindow *tmp_win, window_style *styles);
 void merge_styles(window_style *, window_style *);
 int cmp_masked_flags(void *flags1, void *flags2, void *mask, int len);