Browse Source

Use single function to parse sequences to keep the order

Martin Duquesnoy 12 years ago
parent
commit
554952cc57
5 changed files with 89 additions and 105 deletions
  1. 1 5
      src/config.c
  2. 1 5
      src/infobar.c
  3. 79 95
      src/status.c
  4. 1 0
      src/status.h
  5. 7 0
      src/util.h

+ 1 - 5
src/config.c

@@ -63,11 +63,7 @@ config_theme(void)
           t->client_titlebar_width = fetch_opt_first(ks[i], "12", "client_titlebar_width").num;
           t->client_border_width   = fetch_opt_first(ks[i], "1", "client_border_width").num;
 
-          /* insert_tail with SLIST */
-          if(SLIST_EMPTY(&W->h.theme))
-               SLIST_INSERT_HEAD(&W->h.theme, t, next);
-          else
-               SLIST_INSERT_AFTER(p, t, next);
+          SLIST_INSERT_TAIL(&W->h.theme, t, next, p);
 
           p = t;
      }

+ 1 - 5
src/infobar.c

@@ -71,11 +71,7 @@ infobar_elem_tag_init(struct element *e)
           barwin_mousebind_new(b, Button4, false, g, uicb_tag_next, NULL);
           barwin_mousebind_new(b, Button5, false, g, uicb_tag_prev, NULL);
 
-          /* insert_tail with SLIST */
-          if(SLIST_EMPTY(&e->bars))
-               SLIST_INSERT_HEAD(&e->bars, b, enext);
-          else
-               SLIST_INSERT_AFTER(prev, b, enext);
+          SLIST_INSERT_TAIL(&e->bars, b, enext, prev);
 
           prev = b;
           j += s;

+ 79 - 95
src/status.c

@@ -9,26 +9,20 @@
 #include "util.h"
 
 #include <string.h>
+#include <ctype.h>
 
 /* Parse arg;between;semicolon */
-#define STATUS_GET_ARGS(i, inc, p, arg, n)                                \
-     do {                                                                 \
-          for(i = 0, p += inc, arg[0] = p; *p && *p != ']' && i < n; ++p) \
-               if(*p == ';')                                              \
-               {                                                          \
-                    *p = '\0';                                            \
-                    arg[++i] = ++p;                                       \
-               }                                                          \
-          *p = '\0';                                                      \
+#define STATUS_GET_ARGS(i,  p, arg, n)                                  \
+     do {                                                               \
+          for(i = 0, p += 2, arg[0] = p; *p && *p != ']' && i < n; ++p) \
+               if(*p == ';')                                            \
+               {                                                        \
+                    *p = '\0';                                          \
+                    arg[++i] = ++p;                                     \
+               }                                                        \
+          *p = '\0';                                                    \
      } while(/* CONSTCOND */ 0);
 
-#define STATUS_CHECK_END(str, end, p)           \
-     if(!(end = strstr(p, "]\\")))              \
-     {                                          \
-          str = end + 2;                        \
-          continue;                             \
-     }
-
 #define STATUS_CHECK_ARGS(i, n1, n2, str, end)  \
      if(i != n1 && i != n2)                     \
      {                                          \
@@ -37,12 +31,12 @@
      }
 
 /* Alloc & fill status_sq struct with universal options: align/position and type */
-#define STATUS_FILL_SQ(sq, t, shift, arg)                               \
+#define STATUS_FILL_SQ(sq, t, ma, shift, arg)                           \
      do {                                                               \
           sq = xcalloc(1, sizeof(struct status_seq));                   \
           sq->type = t;                                                 \
                                                                         \
-          if(!strcmp(arg[0], "right") || !strcmp(arg[0], "left"))       \
+          if(i == ma || !strcmp(arg[0], "right") || !strcmp(arg[0], "left")) \
                sq->align = str_to_position(arg[0]);                     \
           else                                                          \
           {                                                             \
@@ -53,73 +47,61 @@
           }                                                             \
      } while(/* CONSTCOND */ 0);                                        \
 
-
-/** Check text blocks in str and list it
- * --> \s[left/right;#color;text]\ OR \s[x;y;#color;text]\
- *\param ib Infobar pointer
- *\param str String
- */
 static void
-status_text(struct infobar *ib, char *str)
+status_parse(struct infobar *ib)
 {
-     struct status_seq *sq;
-     int i;
-     char *dstr = xstrdup(str), *sauv = dstr;
-     char *p, *end;
+     struct status_seq *sq, *prev = NULL;
+     int i, shift = 0;
+     char *dstr = xstrdup(ib->status), *sauv = dstr;
+     char type, *p, *end, *arg[6] = { NULL };
 
-     while((p = strstr(dstr, "\\s[")))
+     for(; *dstr; ++dstr)
      {
-          char *arg[5] = { NULL };
-          int shift = 0;
-
-          STATUS_CHECK_END(dstr, end, p);
-          STATUS_GET_ARGS(i, 3, p, arg, 4);
-          STATUS_CHECK_ARGS(i, 2, 3, dstr, end);
-          STATUS_FILL_SQ(sq, 's', shift, arg);
+          /* Check if this is a sequence */
+          if(*dstr != '\\')
+               continue;
 
-          /* string sequence options */
-          sq->color = color_atoh(arg[1 + shift]);
-          sq->str = xstrdup(arg[2 + shift]);
+          p = ++dstr;
 
-          SLIST_INSERT_HEAD(&ib->statushead, sq, next);
+          if(!(strchr("sR", *p)) || !(end = strstr(p, "]\\")))
+               continue;
 
-          dstr = end + 2;
-     }
+          /* Then parse & list it */
+          switch((type = tolower(*p)))
+          {
+          /*
+           * Text sequence: \s[left/right;#color;text]\ OR \s[x;y;#color;text]\
+           */
+          case 's':
+               STATUS_GET_ARGS(i, p, arg, 4);
+               STATUS_CHECK_ARGS(i, 2, 3, dstr, end);
+               STATUS_FILL_SQ(sq, type, 2, shift, arg);
 
-     free(sauv);
-}
+               sq->color = color_atoh(arg[1 + shift]);
+               sq->str = xstrdup(arg[2 + shift]);
 
-/** Check rectangle blocks in str and list it
- * --> \s[left/right;width;height;#color]\ OR \s[x;y;width;height;#color]\
- *\param ib Infobar pointer
- *\param str String
- */
-static void
-status_rect(struct infobar *ib, char *str)
-{
-     struct status_seq *sq;
-     int i;
-     char *dstr = xstrdup(str), *sauv = dstr;
-     char *p, *end;
+               break;
 
-     while((p = strstr(dstr, "\r[")))
-     {
-          char *arg[6] = { NULL };
-          int shift = 0;
+         /*
+          * Rectangle sequence: \s[left/right;w;h;#color]\ OR \s[x;y;w;h;#color]\
+          */
+          case 'r':
+               STATUS_GET_ARGS(i, p, arg, 5);
+               STATUS_CHECK_ARGS(i, 3, 4, dstr, end);
+               STATUS_FILL_SQ(sq, type, 3, shift, arg);
 
-          STATUS_CHECK_END(dstr, end, p);
-          STATUS_GET_ARGS(i, 2, p, arg, 5);
-          STATUS_CHECK_ARGS(i, 3, 4, dstr, end);
-          STATUS_FILL_SQ(sq, 'r', shift, arg);
+               sq->geo.w = ATOI(arg[1 + shift]);
+               sq->geo.h = ATOI(arg[2 + shift]);
+               sq->color = color_atoh(arg[3 + shift]);
 
-          /* rectangle sequence options */
-          sq->geo.w = ATOI(arg[1 + shift]);
-          sq->geo.h = ATOI(arg[2 + shift]);
-          sq->color = color_atoh(arg[3 + shift]);
+               break;
+          }
 
-          SLIST_INSERT_HEAD(&ib->statushead, sq, next);
+          SLIST_INSERT_TAIL(&ib->statushead, sq, next, prev);
 
+          prev = sq;
           dstr = end + 2;
+          shift = 0;
      }
 
      free(sauv);
@@ -177,11 +159,35 @@ status_apply_list(struct element *e)
      }
 }
 
+/* Render current statustext of an element */
+void
+status_render(struct element *e)
+{
+     struct barwin *b = SLIST_FIRST(&e->bars);
+
+     if(!e->infobar->status)
+          return;
+
+     barwin_refresh_color(b);
+
+     /* Use simple text instead sequence if no sequence found */
+     if(SLIST_EMPTY(&e->infobar->statushead))
+     {
+          int l = draw_textw(e->infobar->theme, e->infobar->status);
+          draw_text(b->dr, e->infobar->theme, e->geo.w - l,
+                    TEXTY(e->infobar->theme, e->geo.h), b->fg, e->infobar->status);
+     }
+     else
+          status_apply_list(e);
+
+     barwin_refresh(b);
+}
+
+/* Parse and render statustext */
 void
 status_manage(struct element *e)
 {
      struct status_seq *sq;
-     struct barwin *b = SLIST_FIRST(&e->bars);
 
      SLIST_INIT(&e->infobar->statushead);
 
@@ -194,30 +200,8 @@ status_manage(struct element *e)
           free(sq);
      }
 
-     if(!e->infobar->status)
-          return;
-
-     barwin_refresh_color(b);
-
-     status_text(e->infobar, e->infobar->status);
-     status_rect(e->infobar, e->infobar->status);
-
-     /* DEBUG
-        SLIST_FOREACH(sq, &e->infobar->statushead, next)
-        printf("-> %c (%d;%d)x(%d;%d) (%d) (#%x) (%s)\n",
-        sq->type, sq->geo.x, sq->geo.y, sq->geo.w, sq->geo.h, sq->align, sq->color, sq->str);
-     */
-
-     status_apply_list(e);
-
-     /*
-       l = draw_textw(e->infobar->theme, e->infobar->status);
-       draw_text(b->dr, e->infobar->theme, e->geo.w - l,
-       TEXTY(e->infobar->theme, e->geo.h), b->fg, e->infobar->status);
-     */
-
-     barwin_refresh(b);
-
+     status_parse(e->infobar);
+     status_render(e);
 }
 
 /* Syntax: "<infobar name> <status string>" */

+ 1 - 0
src/status.h

@@ -8,6 +8,7 @@
 
 #include "wmfs.h"
 
+void status_render(struct element *e);
 void status_manage(struct element *e);
 void uicb_status(Uicb cmd);
 

+ 7 - 0
src/util.h

@@ -21,6 +21,13 @@
           }                                     \
      } while(/* CONSTCOND */ 0);
 
+/* Insert at the end with SLIST */
+#define SLIST_INSERT_TAIL(head, elem, field, prev) \
+     if(SLIST_EMPTY(head))                         \
+          SLIST_INSERT_HEAD(head, elem, field);    \
+     else                                          \
+          SLIST_INSERT_AFTER(prev, elem, field);
+
 /* t is Map or Unmap */
 #define WIN_STATE(w, t) do {      \
      X##t##Subwindows(W->dpy, w); \