Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

conv.c

Go to the documentation of this file.
00001  /*
00002   * plint/data/conv.c : convertion between value types
00003   * 
00004   * Time-stamp: <2002-12-21 14:28:39 gseba>
00005   * 
00006   * Copyright (C) Sebastian Glita, email: gseba@users.sourceforge.net
00007   * 
00008   * This file is part of plint.
00009   * 
00010   * plint is free software; you can  redistribute it and/or modify it under the
00011   * terms of the  GNU General Public License as published  by the Free Software
00012   * Foundation; either version 2, or (at your option) any later version.
00013   *
00014   * plint  is distributed  in the  hope  that it  will be  useful, but  WITHOUT
00015   * ANY  WARRANTY; without  even  the implied  warranty  of MERCHANTABILITY  or
00016   * FITNESS FOR A  PARTICULAR PURPOSE.  See the GNU  General Public License for
00017   * more details.
00018   * 
00019   * You should  have received a  copy of the  GNU General Public  License along
00020   * with  plint; see  the file  COPYING.  If  not, write  to the  Free Software
00021   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA USA.
00022   *
00023   */
00024 
00036 #include "plint.h"
00037 #include "conv.h"
00038 
00051 plint_num_t plint_cnv_num(plint_ptr_t p)
00052 {
00053   plint_num_t r;
00054   r.typ = PLINT_num_int;
00055   switch (p->typ)
00056     {
00057     case PLINT_num_int: case PLINT_num: case PLINT_num_dbl: r = plint_ptr_num(p); break;
00058     case PLINT_pnt: r.val.num_int = p->val.pnt.x; break;
00059     case PLINT_bol: r.val.num_int = p->val.bol; break;
00060     case PLINT_str: r.val.num_int = p->val.str.n; break;
00061     case PLINT_tab: r.val.num_int = p->val.tab.n; break;
00062 
00063     default:
00064       r.val.num_int = 0;
00065     }
00066   return r;
00067 }
00068 
00081 plint_pnt_t plint_cnv_pnt(plint_ptr_t p)
00082 {
00083   plint_pnt_t r;
00084   switch (p->typ)
00085     {
00086     case PLINT_num_int: case PLINT_num: r.x = r.y = p->val.num_int; break;
00087     case PLINT_num_dbl: r.x = r.y = (int)p->val.num_dbl; break;
00088     case PLINT_pnt: r = plint_ptr_pnt(p); break;
00089     case PLINT_bol: r.x = 1 - (r.y = (p->val.bol) ? 0 : 1); break;
00090     case PLINT_str: r.x = r.y = p->val.str.n; break;
00091     case PLINT_tab: r.x = r.y = p->val.tab.n; break;
00092 
00093     default:
00094       r.x = r.y = 0;
00095     }
00096   return r;
00097 }
00098 
00099 static int hsh2str_1st;
00100 static int hsh2str(hashindex_t hi, ns_key_t ns, plint_ref_t ref, plint_str_t * pstr)
00101 {
00102   plint_str_t str;
00103   plint_str_cat(pstr, plint->conv.hsh[hsh2str_1st]);
00104   if (hsh2str_1st == 0)
00105     hsh2str_1st = 1;
00106   plint_str_cat(pstr, plint->conv.hsh[2]);
00107   plint_hash_str(ns_hash(ns), hi, str);
00108   plint_str_cat(pstr, str);
00109   plint_str_fre(str);
00110   plint_str_cat(pstr, plint->conv.hsh[3]);
00111   str = plint_cnv_str(plint_var_val(plint_ref_var(ref)));
00112   plint_str_cat(pstr, str);
00113   plint_str_cat(pstr, plint->conv.hsh[4]);
00114 
00115   return !0;
00116 }
00117 
00118 static int hsh2bol(hashindex_t hi, ns_key_t ns, plint_ref_t ref, plint_bol_t * pbol)
00119 {
00120   *pbol = !0;
00121   return !0;
00122 }
00123 
00137 plint_bol_t plint_cnv_bol(plint_ptr_t p)
00138 {
00139   plint_bol_t r = 0;
00140   switch (p->typ)
00141     {
00142     case PLINT_num_int: case PLINT_num: r = p->val.num_int != 0; break;
00143     case PLINT_num_dbl: r = p->val.num_dbl != 0.; break;
00144     case PLINT_pnt: r = p->val.pnt.x != 0 && p->val.pnt.y != 0; break;
00145     case PLINT_bol: r = plint_ptr_bol(p); break;
00146     case PLINT_str: r = p->val.str.n != 0; break;
00147     case PLINT_tab: r = p->val.tab.n != 0; break;
00148     case PLINT_hsh: hash_iterdata_all(p->val.hsh, (hash_iterfunc_t)hsh2bol, &r); break;
00149     default:
00150     }
00151   return r;
00152 }
00153 
00168 plint_str_t plint_cnv_str(plint_ptr_t p)
00169 {
00170   plint_str_t r;
00171   switch (p->typ)
00172     {
00173 
00174     case PLINT_num_int: case PLINT_num:
00175       {
00176         char s[] = PLINT_INT_MAX;
00177         int n = sprintf(s, plint->conv.num_int.s, (int)sizeof(s), p->val.num_int), m = 0;
00178         while (s[m] == ' ') ++m;
00179         r = plint_str_new(s + m, n - m);
00180       }
00181       break;
00182     case PLINT_num_dbl:
00183       {
00184         char s[] = PLINT_DBL_MAX;
00185         int n = sprintf(s, plint->conv.num_dbl.s, (int)sizeof(s), p->val.num_dbl), m = 0;
00186         while (s[m] == ' ') ++m;
00187         r = plint_str_new(s + m, n - m);
00188       }
00189       break;
00190     case PLINT_pnt:
00191       {
00192         char sx[] = PLINT_INT_MAX, sy[] = PLINT_DBL_MAX;
00193         plint_str_t x, y;
00194         int mx = 0, my = 0;
00195         x.n = sprintf(sx, plint->conv.num_int.s, (int)sizeof(sx), p->val.pnt.x);
00196         y.n = sprintf(sy, plint->conv.num_int.s, (int)sizeof(sy), p->val.pnt.y);
00197         while (sx[mx] == ' ') ++mx, --x.n;
00198         while (sy[my] == ' ') ++my, --y.n;
00199         x.s = sx + mx; y.s = sy + my;
00200         r = plint_str_dup(plint->conv.pnt[0]);
00201         plint_str_cat(&r, x);
00202         plint_str_cat(&r, plint->conv.pnt[1]);
00203         plint_str_cat(&r, y);
00204         plint_str_cat(&r, plint->conv.pnt[2]);
00205       }
00206       break;
00207     case PLINT_bol: r = plint_str_dup(plint->conv.bol[p->val.bol ? 1 : 0]); break;
00208     case PLINT_str: r = plint_ptr_str(p); break;
00209     case PLINT_tab:
00210       r = plint_str_dup(plint->conv.tab[0]);
00211       if (p->val.tab.n)
00212         {
00213           plint_str_t t;
00214           size_t i;
00215           for (i = 0; i < p->val.tab.n; )
00216             {
00217               t = plint_cnv_str(p->val.tab.a[i]->ptr);
00218               plint_str_cat(&r, t);
00219               plint_str_fre(t);
00220               
00221               if (++i < p->val.tab.n)
00222                 plint_str_cat(&r, plint->conv.tab[1]);
00223             }
00224         }
00225       plint_str_cat(&r, plint->conv.tab[2]);
00226       break;
00227     case PLINT_hsh:
00228       hsh2str_1st = 0;
00229       hash_iterdata_all(p->val.hsh, (hash_iterfunc_t)hsh2str, &r);
00230       plint_str_cat(&r, plint->conv.hsh[5]);
00231       break;
00232 
00233     default:
00234       PLINT_str_EMPTY(r); break;
00235 
00236     }
00237   return r;
00238 }
00239 
00240 #ifndef PLINT_HSH2TAB_DONT
00241 static int hsh2tab(hashindex_t hi, ns_key_t ns, plint_ref_t ref, plint_tab_t * ptab)
00242 {
00243   plint_str_t str;
00244   plint_tab_t tab = PLINT_tab_INIT(2);
00245   plint_hash_str(ns_hash(ns), hi, str);
00246   0[plint_tab_a(tab)] = plint_bar_new(plint_str_ptr(str));
00247   1[plint_tab_a(tab)] = plint_var_dup(plint_ref_var(ref));
00248   plint_tab_cat(ptab, tab);
00249   plint_tab_fre(tab);
00250 
00251   return !0;
00252 }
00253 #endif
00254 
00269 plint_tab_t plint_cnv_tab(plint_ptr_t p)
00270 {
00271   plint_tab_t r = PLINT_tab_INIT_NUL;
00272   switch (p->typ)
00273     {
00274     case PLINT_pnt:
00275       PLINT_tab_NEW(r, 2);
00276       r.a[0] = plint_bar_new(PLINT_PTR_NEW(num_int, p->val.pnt.x));
00277       r.a[1] = plint_bar_new(PLINT_PTR_NEW(num_int, p->val.pnt.y));
00278       break;
00279     case PLINT_str:
00280       if (p->val.str.n)
00281         {
00282           size_t i;
00283           PLINT_tab_NEW(r, p->val.str.n);
00284           for (i = 0; i < r.n; ++i)
00285             r.a[i] = plint_bar_new(plint_str_ptr(plint_str_str(p->val.str, i, i)));
00286         }
00287       else
00288         r.a = 0;
00289       break;
00290     case PLINT_tab:
00291       r = plint_tab_dup(p->val.tab);
00292       break;
00293 #ifndef PLINT_HSH2TAB_DONT
00294     case PLINT_hsh:
00295       /* a table has a finite number of elements, a hash (in theory) doesn't
00296          => shouldn't convert, but in practice ...
00297       */
00298       hash_iterdata_all(p->val.hsh, (hash_iterfunc_t)hsh2tab, &r);
00299       break;
00300 #endif
00301 
00302     default:
00303       0[PLINT_tab_NEW(r, 1)] = plint_bar_new(plint_ptr_dup(p)); break;
00304     }
00305   return r;
00306 }
00307 
00320 plint_hsh_t plint_cnv_hsh(plint_ptr_t p)
00321 {
00322   plint_hsh_t r = plint_hsh_new();
00323   switch (p->typ)
00324     {
00325     case PLINT_pnt:
00326       plint_hsh_put(r, plint->conv.pnt2hsh[0], plint_bar_new(plint_num_ptr(plint_num_INT(plint_pnt_x(p->val.pnt)))));
00327       plint_hsh_put(r, plint->conv.pnt2hsh[1], plint_bar_new(plint_num_ptr(plint_num_INT(plint_pnt_y(p->val.pnt)))));
00328       break;
00329     case PLINT_str:
00330       plint_hsh_put(r, p->val.str, plint_bar_new(plint_str_ptr(plint_str_dup(p->val.str))));
00331      break;
00332 
00333     case PLINT_tab:
00334       {
00335         size_t i;
00336         plint_ptr_t i_n = plint_num_ptr(plint_num_INT(0));
00337         for (i = plint_tab_n(p->val.tab); i-- ;)
00338           {
00339             plint_str_t i_s = plint_cnv_str(plint_num_set(i_n, plint_num_INT((int)i)));
00340             plint_hsh_put(r, i_s, plint_var_dup(i[plint_tab_a(p->val.tab)]));
00341             plint_str_fre(i_s);
00342           }
00343         plint_ptr_fre(i_n);
00344       }
00345       break;
00346     case PLINT_hsh:
00347       plint_hsh_fre(r);
00348       r = plint_hsh_dup(p->val.hsh);
00349       break;
00350 
00351     default:
00352     }
00353   return r;
00354 }
00355 

Generated on Thu Jan 9 19:02:37 2003 for plint by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002