# HG changeset patch # User Myhailo Danylenko # Date 1263563040 -7200 # Node ID faaed3ae3fa88c8fc651be32e4bf615c9b1de21e # Parent 7b0b509e02e4c23ebdb34b361ec168ae91ce0feb String head and tail operators * : string head * ^ string tail * fix for negative integer detection diff -r 7b0b509e02e4 -r faaed3ae3fa8 TODO --- a/TODO Fri Jan 15 12:57:16 2010 +0200 +++ b/TODO Fri Jan 15 15:44:00 2010 +0200 @@ -1,3 +1,3 @@ -String splitting (need to decide, which operator characters to use) +Pattern matching/cutting over strings diff -r 7b0b509e02e4 -r faaed3ae3fa8 help/en/hlp_eval.txt --- a/help/en/hlp_eval.txt Fri Jan 15 12:57:16 2010 +0200 +++ b/help/en/hlp_eval.txt Fri Jan 15 15:44:00 2010 +0200 @@ -6,6 +6,8 @@ * all operators have the same precedence; * supported operators: . string concatenation + : string head + ^ string tail + binary plus / string concatenation - binary minus * multiplication / string replication @@ -25,3 +27,4 @@ Example: /eval "echo 2 + 2 = " . (2+2) /eval "set ping_interval = " . (ping_interval + 1) ) this example probably should use /let command. + /eval "echo " . (ssl_fingerprint : 5) . "..." . (ssl_fingerprint ^ 5) ) negative offsets are also supported diff -r 7b0b509e02e4 -r faaed3ae3fa8 yaubil.c --- a/yaubil.c Fri Jan 15 12:57:16 2010 +0200 +++ b/yaubil.c Fri Jan 15 15:44:00 2010 +0200 @@ -55,7 +55,7 @@ { if (value) { const char *e; - gboolean integer = (*value == '-') ? FALSE : (g_ascii_isdigit (*value) ? TRUE : FALSE); + gboolean integer = (*value == '-') ? TRUE : (g_ascii_isdigit (*value) ? TRUE : FALSE); if (integer) { for (e = value + 1; *e; ++e) { @@ -78,7 +78,7 @@ static gboolean op_concat (value_t *l, value_t *r) { - GString *res = g_string_new (NULL);; + GString *res = g_string_new (NULL); if (l->type == TYPE_INT) g_string_append_printf (res, "%d", l->int_value); @@ -97,6 +97,84 @@ return TRUE; } +static gboolean op_head (value_t *l, value_t *r) +{ + if (l->type == TYPE_UNDEF) { + l->type = TYPE_INT; + l->int_value = 0; + } + if (r->type == TYPE_UNDEF) { + r->type = TYPE_INT; + r->int_value = 0; + } + + if (l -> type == TYPE_INT) { + l -> type = TYPE_STR; + if (!l -> str_value) + l -> str_value = g_strdup_printf ("%d", l -> int_value); + } + if (r->type == TYPE_STR && check_value_type (r->str_value) == TYPE_INT) { + r->type = TYPE_INT; + r->int_value = atoi (r->str_value); + g_free (r->str_value); + r->str_value = NULL; + } + + if (l->type == TYPE_STR && r->type == TYPE_INT) { + gchar *res = NULL; + int len = l -> str_value ? strlen (l -> str_value) : 0; // XXX can str_value be NULL? + int off = r -> int_value; + if (off < 0 && len + off > 0) + res = g_strndup (l -> str_value, len + off); + else if (off > 0 && len > off) + res = g_strndup (l -> str_value, off); + else + res = g_strdup (""); // XXX leave NULL here? + g_free (l->str_value); + l->str_value = res; + } else + return FALSE; +} + +static gboolean op_tail (value_t *l, value_t *r) +{ + if (l->type == TYPE_UNDEF) { + l->type = TYPE_INT; + l->int_value = 0; + } + if (r->type == TYPE_UNDEF) { + r->type = TYPE_INT; + r->int_value = 0; + } + + if (l -> type == TYPE_INT) { + l -> type = TYPE_STR; + if (!l -> str_value) + l -> str_value = g_strdup_printf ("%d", l -> int_value); + } + if (r->type == TYPE_STR && check_value_type (r->str_value) == TYPE_INT) { + r->type = TYPE_INT; + r->int_value = atoi (r->str_value); + g_free (r->str_value); + r->str_value = NULL; + } + + if (l->type == TYPE_STR && r->type == TYPE_INT) { + gchar *res = NULL; + int len = l -> str_value ? strlen (l -> str_value) : 0; // XXX can str_value be NULL? + int off = r -> int_value; + if (off < 0 && len + off > 0) + res = g_strdup (l -> str_value + (-off)); + else if (off > 0 && len > off) + res = g_strdup (l -> str_value + (len - off)); + else + res = g_strdup (""); // XXX leave NULL here? + g_free (l->str_value); + l->str_value = res; + } else + return FALSE; +} + static gboolean op_plus (value_t *l, value_t *r) { if (l->type == TYPE_UNDEF) { @@ -454,6 +532,8 @@ static op_t operators[] = { { '.', op_concat }, + { ':', op_head }, + { '^', op_tail }, { '+', op_plus }, { '-', op_minus }, { '*', op_multiply },