Author: timbo
Date: Mon Jun  2 00:43:19 2008
New Revision: 11368

Modified:
   dbi/trunk/DBI.xs
   dbi/trunk/t/18concathash.t

Log:
Rename sort_type & sort_order to num_sort.
Rename value_format to use_neat (and invert meaning).
Add extra aray ref arg to _concat_hash_sorted for quickly appending extra info.


Modified: dbi/trunk/DBI.xs
==============================================================================
--- dbi/trunk/DBI.xs    (original)
+++ dbi/trunk/DBI.xs    Mon Jun  2 00:43:19 2008
@@ -242,7 +242,7 @@
 }
 
 static char **
-_sort_hash_keys (HV *hash, int sort_order, STRLEN *total_length)
+_sort_hash_keys (HV *hash, int num_sort, STRLEN *total_length)
 {
     dTHX;
     I32 hv_len, key_len;
@@ -276,10 +276,10 @@
     if (total_length)
         *total_length = tot_len;
 
-    if (sort_order < 0)
-        sort_order = (has_non_numerics) ? 0 : 1;
+    if (num_sort < 0)
+        num_sort = (has_non_numerics) ? 0 : 1;
 
-    if (0 == sort_order) {
+    if (!num_sort) {
         qsort(keys, hv_len, sizeof(char*), _cmp_str);
     }
     else {
@@ -294,7 +294,7 @@
 
 
 static SV *
-_join_hash_sorted(HV *hash, char *kv_sep, STRLEN kv_sep_len, char *pair_sep, 
STRLEN pair_sep_len, int use_neat, int sort_type)
+_join_hash_sorted(HV *hash, char *kv_sep, STRLEN kv_sep_len, char *pair_sep, 
STRLEN pair_sep_len, int use_neat, int num_sort)
 {
        dTHX;
         I32 hv_len;
@@ -303,7 +303,7 @@
         unsigned int i = 0;
         SV *return_sv;
 
-        keys = _sort_hash_keys(hash, sort_type, &total_len);
+        keys = _sort_hash_keys(hash, num_sort, &total_len);
         if (!keys)
             return newSVpv("", 0);
 
@@ -4388,25 +4388,43 @@
 
 
 SV *
-_concat_hash_sorted(hash, kv_sep_sv, pair_sep_sv, value_format_sv, 
sort_type_sv)
-    HV *hash
+_concat_hash_sorted(hash_sv, kv_sep_sv, pair_sep_sv, use_neat_sv, num_sort_sv, 
extra_sv=Nullsv)
+    SV *hash_sv
     SV *kv_sep_sv
     SV *pair_sep_sv
-    SV *value_format_sv
-    SV *sort_type_sv
+    SV *use_neat_sv
+    SV *num_sort_sv
+    SV *extra_sv
     PREINIT:
     STRLEN kv_sep_len, pair_sep_len;
     char *kv_sep, *pair_sep;
-    int use_neat, sort_type;
+    int use_neat, num_sort;
     CODE:
-        kv_sep = SvPV(kv_sep_sv, kv_sep_len);
+        if (!SvOK(hash_sv))
+            XSRETURN_UNDEF;
+        if (!SvROK(hash_sv) || SvTYPE(SvRV(hash_sv))!=SVt_PVHV)
+            croak("hash is not a hash reference");
+        kv_sep   = SvPV(kv_sep_sv,   kv_sep_len);
         pair_sep = SvPV(pair_sep_sv, pair_sep_len);
-        if (SvGMAGICAL(value_format_sv)) /* SvTRUE doesn't handle magic */
-            mg_get(value_format_sv);
-        use_neat = SvTRUE(value_format_sv);
-        sort_type = (SvOK(sort_type_sv)) ? SvIV(sort_type_sv) : -1;
-
-        RETVAL = _join_hash_sorted(hash, kv_sep, kv_sep_len, pair_sep, 
pair_sep_len, use_neat, sort_type);
+        /* use_neat should be undef, 0 or 1, may allow sprintf format strings 
later */
+        use_neat = (SvOK(use_neat_sv)) ? SvIV(use_neat_sv) : 0;
+        num_sort = (SvOK(num_sort_sv)) ? SvIV(num_sort_sv) : -1;
+
+        RETVAL = _join_hash_sorted((HV*)SvRV(hash_sv), kv_sep, kv_sep_len, 
pair_sep, pair_sep_len, use_neat, num_sort);
+
+        /* efficient way for the caller to tack extra info onto the return 
string */
+        if (extra_sv && SvOK(extra_sv) && SvROK(extra_sv) && 
SvTYPE(SvRV(extra_sv))==SVt_PVAV) {
+            AV *extra_av = (AV*)SvRV(extra_sv);
+            int i, items = AvFILL(extra_av)+1;
+            for (i=0; i < items; ++i) {
+                SV *e_sv = *av_fetch(extra_av, i, 1);
+                if (SvTRUE(RETVAL))
+                    sv_catsv(RETVAL, kv_sep_sv);
+                if (SvOK(e_sv))
+                     sv_catsv(RETVAL, *av_fetch(extra_av, i, 1));
+                else sv_catpvn(RETVAL, "undef", 5);
+            }
+        }
 
     OUTPUT:
         RETVAL

Modified: dbi/trunk/t/18concathash.t
==============================================================================
--- dbi/trunk/t/18concathash.t  (original)
+++ dbi/trunk/t/18concathash.t  Mon Jun  2 00:43:19 2008
@@ -15,12 +15,13 @@
 BEGIN { use_ok('DBI') };
 
 # null and undefs -- segfaults?;
-is (DBI::_concat_hash_sorted({ }, "=",   ":",   0, undef), "");
-eval { DBI::_concat_hash_sorted(undef, "=", ":", 0, undef) };
+is (DBI::_concat_hash_sorted(undef, "=",   ":",   0, undef), "");
+is (DBI::_concat_hash_sorted({ },   "=",   ":",   0, undef), "");
+eval { DBI::_concat_hash_sorted([], "=",   ":",   0, undef) };
 like ($@ || "", qr/is not a hash reference/);
-is (DBI::_concat_hash_sorted({ }, undef, ":",   0,     undef), "");
-is (DBI::_concat_hash_sorted({ }, "=",   undef, 0,     undef), "");
-is (DBI::_concat_hash_sorted({ }, "=",   ":",   undef, undef),"");
+is (DBI::_concat_hash_sorted({ },   undef, ":",   0,     undef), "");
+is (DBI::_concat_hash_sorted({ },   "=",   undef, 0,     undef), "");
+is (DBI::_concat_hash_sorted({ },   "=",   ":",   undef, undef),"");
 
 # simple cases
 is (DBI::_concat_hash_sorted({ 1=>"a", 2=>"b" }, "=", ", ", undef, undef), 
"1='a', 2='b'");

Reply via email to