xdbe replaced with more generic pixmap based buffering but there are 2 bugs:
[monky] / src / algebra.c
index 6489370..a8070fc 100644 (file)
@@ -1,4 +1,7 @@
-/* Conky, a system monitor, based on torsmo
+/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
+ * vim: ts=4 sw=4 noet ai cindent syntax=c
+ *
+ * Conky, a system monitor, based on torsmo
  *
  * Any original torsmo code is licensed under the BSD license
  *
@@ -7,7 +10,7 @@
  * Please see COPYING for details
  *
  * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
- * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al.
+ * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al.
  *     (see AUTHORS)
  * All rights reserved.
  *
@@ -26,6 +29,7 @@
  */
 #define _GNU_SOURCE
 #include "config.h"
+#include "conky.h"
 #include "algebra.h"
 #include "logging.h"
 #include <ctype.h>
@@ -122,11 +126,9 @@ enum arg_type get_arg_type(const char *arg)
        const char *p, *e;
 
        p = arg;
-       e = arg + strlen(arg);
+       e = arg + strlen(arg)-1;
 
-       if (*(e - 1) == ' ')
-               e--;
-       while (*e && *e == ' ')
+       while (p != e && *e && *e == ' ')
                e--;
        while (p != e && *p == ' ')
                p++;
@@ -136,23 +138,23 @@ enum arg_type get_arg_type(const char *arg)
 
        if (*p == '-')  //allow negative values
                p++;
-       while (p != e) {
+       while (p <= e) {
                if (!isdigit(*p))
                        break;
                p++;
        }
-       if (p == e)
+       if (p == e+1)
                return ARG_LONG;
        if (*p == '.') {
                p++;
-               while (p != e) {
+               while (p <= e) {
                        if (!isdigit(*p))
-                               return ARG_STRING;
+                               return ARG_BAD;
                        p++;
                }
                return ARG_DOUBLE;
        }
-       return ARG_STRING;
+       return ARG_BAD;
 }
 
 char *arg_to_string(const char *arg)
@@ -174,7 +176,7 @@ double arg_to_double(const char *arg)
 {
        double d;
        if (sscanf(arg, "%lf", &d) != 1) {
-               ERR("converting '%s' to double failed", arg);
+               NORM_ERR("converting '%s' to double failed", arg);
                return 0.0;
        }
        return d;
@@ -183,7 +185,7 @@ long arg_to_long(const char *arg)
 {
        long l;
        if (sscanf(arg, "%ld", &l) != 1) {
-               ERR("converting '%s' to long failed", arg);
+               NORM_ERR("converting '%s' to long failed", arg);
                return 0;
        }
        return l;
@@ -193,12 +195,14 @@ int compare(const char *expr)
        char *expr_dup;
        int idx, mtype;
        enum arg_type type1, type2;
+       long lng_a, lng_b;
+       double dbl_a, dbl_b;
 
        idx = find_match_op(expr);
        mtype = get_match_type(expr);
 
        if (!idx || mtype == -1) {
-               ERR("failed to parse compare string '%s'", expr);
+               NORM_ERR("failed to parse compare string '%s'", expr);
                return -2;
        }
 
@@ -209,13 +213,19 @@ int compare(const char *expr)
 
        type1 = get_arg_type(expr_dup);
        type2 = get_arg_type(expr_dup + idx + 1);
+       if (type1 == ARG_BAD || type2 == ARG_BAD) {
+               NORM_ERR("Bad arguments: '%s' and '%s'", expr_dup, (expr_dup + idx + 1));
+               free(expr_dup);
+               return -2;
+       }
        if (type1 == ARG_LONG && type2 == ARG_DOUBLE)
                type1 = ARG_DOUBLE;
        if (type1 == ARG_DOUBLE && type2 == ARG_LONG)
                type2 = ARG_DOUBLE;
        if (type1 != type2) {
-               ERR("trying to compare args '%s' and '%s' of different type",
+               NORM_ERR("trying to compare args '%s' and '%s' of different type",
                                expr_dup, (expr_dup + idx + 1));
+               free(expr_dup);
                return -2;
        }
        switch (type1) {
@@ -227,15 +237,22 @@ int compare(const char *expr)
                                idx = scompare(a, mtype, b);
                                free(a);
                                free(b);
+                               free(expr_dup);
                                return idx;
                        }
                case ARG_LONG:
-                       return lcompare(arg_to_long(expr_dup), mtype,
-                                       arg_to_long(expr_dup + idx + 1));
+                       lng_a = arg_to_long(expr_dup);
+                       lng_b = arg_to_long(expr_dup + idx + 1);
+                       free(expr_dup);
+                       return lcompare(lng_a, mtype, lng_b);
                case ARG_DOUBLE:
-                       return dcompare(arg_to_double(expr_dup), mtype,
-                                       arg_to_double(expr_dup + idx + 1));
+                       dbl_a = arg_to_double(expr_dup);
+                       dbl_b = arg_to_double(expr_dup + idx + 1);
+                       free(expr_dup);
+                       return lcompare(dbl_a, mtype, dbl_b);
+               case ARG_BAD: /* make_gcc_happy() */;
        }
        /* not reached */
+       free(expr_dup);
        return -2;
 }