"Fossies" - the Fresh Open Source Software Archive

Member "mapm_4.9.5a/mapm_set.c" (21 Feb 2010, 8895 Bytes) of package /linux/misc/old/mapm-4.9.5a.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mapm_set.c" see the Fossies "Dox" file reference documentation.

    1 
    2 /* 
    3  *  M_APM  -  mapm_set.c
    4  *
    5  *  Copyright (C) 1999 - 2007   Michael C. Ring
    6  *
    7  *  Permission to use, copy, and distribute this software and its
    8  *  documentation for any purpose with or without fee is hereby granted,
    9  *  provided that the above copyright notice appear in all copies and
   10  *  that both that copyright notice and this permission notice appear
   11  *  in supporting documentation.
   12  *
   13  *  Permission to modify the software is granted. Permission to distribute
   14  *  the modified code is granted. Modifications are to be distributed by
   15  *  using the file 'license.txt' as a template to modify the file header.
   16  *  'license.txt' is available in the official MAPM distribution.
   17  *
   18  *  This software is provided "as is" without express or implied warranty.
   19  */
   20 
   21 /*
   22  *      $Id: mapm_set.c,v 1.18 2007/12/03 01:47:50 mike Exp $
   23  *
   24  *      This file contains the functions necessary to get C 'longs' and
   25  *  'strings' into the MAPM number system. It also contains the function
   26  *  to get a string from a MAPM number.
   27  *
   28  *      $Log: mapm_set.c,v $
   29  *      Revision 1.18  2007/12/03 01:47:50  mike
   30  *      Update license
   31  *
   32  *      Revision 1.17  2003/07/21 20:25:06  mike
   33  *      Modify error messages to be in a consistent format.
   34  *
   35  *      Revision 1.16  2003/03/31 21:59:52  mike
   36  *      call generic error handling function
   37  *
   38  *      Revision 1.15  2002/11/05 23:31:54  mike
   39  *      use new set_to_zero call instead of copy
   40  *
   41  *      Revision 1.14  2002/11/03 22:24:19  mike
   42  *      Updated function parameters to use the modern style
   43  *
   44  *      Revision 1.13  2001/07/16 19:34:16  mike
   45  *      add function M_free_all_set
   46  *
   47  *      Revision 1.12  2001/02/11 22:33:27  mike
   48  *      modify parameters to REALLOC
   49  *
   50  *      Revision 1.11  2001/01/23 21:16:03  mike
   51  *      use dedicated call to long->ascii instead of sprintf
   52  *
   53  *      Revision 1.10  2000/10/25 22:57:25  mike
   54  *      add cast which really wasn't needed
   55  *
   56  *      Revision 1.9  2000/10/25 19:57:01  mike
   57  *      add free call to end of set string if the temp
   58  *      string gets too big
   59  *
   60  *      Revision 1.8  2000/05/04 23:49:19  mike
   61  *      put in more efficient set_long function
   62  *
   63  *      Revision 1.7  2000/02/03 22:47:15  mike
   64  *      use MAPM_* generic memory function
   65  *
   66  *      Revision 1.6  1999/07/12 22:23:17  mike
   67  *      tweak output string when input == 0
   68  *
   69  *      Revision 1.5  1999/07/12 02:07:56  mike
   70  *      fix dec_places error (was == -1, should be < 0)
   71  *
   72  *      Revision 1.4  1999/06/19 21:36:57  mike
   73  *      added some comments
   74  *
   75  *      Revision 1.3  1999/06/19 21:35:19  mike
   76  *      changed local static variables to MAPM stack variables
   77  *
   78  *      Revision 1.2  1999/05/13 21:32:41  mike
   79  *      added check for illegal chars in string parse
   80  *
   81  *      Revision 1.1  1999/05/10 20:56:31  mike
   82  *      Initial revision
   83  */
   84 
   85 #include "m_apm_lc.h"
   86 
   87 static  char *M_buf  = NULL;
   88 static  int   M_lbuf = 0;
   89 static  char *M_set_string_error_msg = "\'m_apm_set_string\', Out of memory";
   90 
   91 /****************************************************************************/
   92 void    M_free_all_set()
   93 {
   94 if (M_lbuf != 0)
   95   {
   96    MAPM_FREE(M_buf);
   97    M_buf  = NULL;
   98    M_lbuf = 0;
   99   }
  100 }
  101 /****************************************************************************/
  102 void    m_apm_set_long(M_APM atmp, long mm)
  103 {
  104 int     len, ii, nbytes;
  105 char    *p, *buf, ch, buf2[64];
  106 
  107 /* if zero, return right away */
  108 
  109 if (mm == 0)
  110   {
  111    M_set_to_zero(atmp);
  112    return;
  113   }
  114 
  115 M_long_2_ascii(buf2, mm);     /* convert long -> ascii in base 10 */
  116 buf = buf2;
  117 
  118 if (mm < 0)
  119   {
  120    atmp->m_apm_sign = -1;
  121    buf++;                     /* get past '-' sign */
  122   }
  123 else
  124   {
  125    atmp->m_apm_sign = 1;
  126   }
  127 
  128 len = strlen(buf);
  129 atmp->m_apm_exponent = len;
  130 
  131 /* least significant nibble of ODD data-length must be 0 */
  132 
  133 if ((len & 1) != 0)
  134   {
  135    buf[len] = '0';
  136   }
  137 
  138 /* remove any trailing '0' ... */
  139 
  140 while (TRUE)
  141   {
  142    if (buf[--len] != '0')
  143      break;
  144   }
  145 
  146 atmp->m_apm_datalength = ++len;
  147 
  148 nbytes = (len + 1) >> 1;
  149 p = buf;
  150 
  151 for (ii=0; ii < nbytes; ii++)
  152   {
  153    ch = *p++ - '0';
  154    atmp->m_apm_data[ii] = 10 * ch + *p++ - '0';
  155   }
  156 }
  157 /****************************************************************************/
  158 void    m_apm_set_string(M_APM ctmp, char *s_in)
  159 {
  160 char    ch, *cp, *s, *p;
  161 void    *vp;
  162 int i, j, zflag, exponent, sign;
  163 
  164 if (M_lbuf == 0)
  165   {
  166    M_lbuf = 256;
  167    if ((M_buf = (char *)MAPM_MALLOC(256)) == NULL)
  168      {
  169       /* fatal, this does not return */
  170 
  171       M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg);
  172      }
  173   }
  174 
  175 if ((i = strlen(s_in)) > (M_lbuf - 4))
  176   {
  177    M_lbuf = i + 32;
  178    if ((vp = MAPM_REALLOC(M_buf, M_lbuf)) == NULL)
  179      {
  180       /* fatal, this does not return */
  181 
  182       M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg);
  183      }
  184 
  185    M_buf = (char *)vp;
  186   }
  187 
  188 s = M_buf;
  189 strcpy(s,s_in);
  190 
  191 /* default == zero ... */
  192 
  193 M_set_to_zero(ctmp);
  194 
  195 p = s;
  196 
  197 while (TRUE)
  198   {
  199    if (*p == ' ' || *p == '\t')
  200      p++;
  201    else
  202      break;
  203   }
  204 
  205 if (*p == '\0')
  206   return;
  207 
  208 sign = 1;             /* assume number is positive */
  209 
  210 if (*p == '+')        /* scan by optional '+' sign */
  211   p++;
  212 else
  213   {
  214    if (*p == '-')     /* check if number negative */
  215      {
  216       sign = -1;
  217       p++;
  218      }
  219   }
  220 
  221 M_lowercase(p);       /* convert string to lowercase */
  222 exponent = 0;         /* default */
  223    
  224 if ((cp = strstr(p,"e")) != NULL)
  225   {
  226    exponent = atoi(cp + sizeof(char));
  227    *cp = '\0';          /* erase the exponent now */
  228   }
  229 
  230 j = M_strposition(p,".");        /* is there a decimal point ?? */
  231 if (j == -1)
  232   {
  233    strcat(p,".");                /* if not, append one */
  234    j = M_strposition(p,".");     /* now find it ... */
  235   }
  236 
  237 if (j > 0)                       /* normalize number and adjust exponent */
  238   {
  239    exponent += j;
  240    memmove((p+1),p,(j * sizeof(char)));
  241   }
  242 
  243 p++;        /* scan past implied decimal point now in column 1 (index 0) */
  244 
  245 i = strlen(p);
  246 ctmp->m_apm_datalength = i;
  247 
  248 if ((i & 1) != 0)   /* if odd number of digits, append a '0' to make it even */
  249   strcat(p,"0");    
  250 
  251 j = strlen(p) >> 1;  /* number of bytes in encoded M_APM number */
  252 
  253 /* do we need more memory to hold this number */
  254 
  255 if (j > ctmp->m_apm_malloclength)
  256   {
  257    if ((vp = MAPM_REALLOC(ctmp->m_apm_data, (j + 32))) == NULL)
  258      {
  259       /* fatal, this does not return */
  260 
  261       M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg);
  262      }
  263   
  264    ctmp->m_apm_malloclength = j + 28;
  265    ctmp->m_apm_data = (UCHAR *)vp;
  266   }
  267 
  268 zflag = TRUE;
  269 
  270 for (i=0; i < j; i++)
  271   {
  272    ch = *p++ - '0';
  273    if ((ch = (10 * ch + *p++ - '0')) != 0)
  274      zflag = FALSE;
  275 
  276    if (((int)ch & 0xFF) >= 100)
  277      {
  278       M_apm_log_error_msg(M_APM_RETURN,
  279       "\'m_apm_set_string\', Non-digit char found in parse");
  280 
  281       M_apm_log_error_msg(M_APM_RETURN, "Text =");
  282       M_apm_log_error_msg(M_APM_RETURN, s_in);
  283 
  284       M_set_to_zero(ctmp);
  285       return;
  286      }
  287 
  288    ctmp->m_apm_data[i]   = ch;
  289    ctmp->m_apm_data[i+1] = 0;
  290   }
  291 
  292 ctmp->m_apm_exponent = exponent;
  293 ctmp->m_apm_sign     = sign;
  294 
  295 if (zflag)
  296   {
  297    ctmp->m_apm_exponent   = 0;
  298    ctmp->m_apm_sign       = 0;
  299    ctmp->m_apm_datalength = 1;
  300   }
  301 else
  302   {
  303    M_apm_normalize(ctmp);
  304   }
  305 
  306 /*
  307  *  if our local temp string is getting too big,
  308  *  release it's memory and start over next time.
  309  *  (this 1000 byte threshold is quite arbitrary,
  310  *  it may be more efficient in your app to make
  311  *  this number bigger).
  312  */
  313 
  314 if (M_lbuf > 1000)
  315   {
  316    MAPM_FREE(M_buf);
  317    M_buf  = NULL;
  318    M_lbuf = 0;
  319   }
  320 }
  321 /****************************************************************************/
  322 void    m_apm_to_string(char *s, int places, M_APM mtmp)
  323 {
  324 M_APM   ctmp;
  325 char    *cp;
  326 int i, index, first, max_i, num_digits, dec_places;
  327 UCHAR   numdiv, numrem;
  328 
  329 ctmp = M_get_stack_var();
  330 dec_places = places;
  331 
  332 if (dec_places < 0)
  333   m_apm_copy(ctmp, mtmp);
  334 else
  335   m_apm_round(ctmp, dec_places, mtmp);
  336 
  337 if (ctmp->m_apm_sign == 0)
  338   {
  339    if (dec_places < 0)
  340       strcpy(s,"0.0E+0");
  341    else
  342      {
  343       strcpy(s,"0");
  344 
  345       if (dec_places > 0)
  346         strcat(s,".");
  347 
  348       for (i=0; i < dec_places; i++)
  349         strcat(s,"0");
  350 
  351       strcat(s,"E+0");
  352      }
  353 
  354    M_restore_stack(1);
  355    return;
  356   }
  357 
  358 max_i = (ctmp->m_apm_datalength + 1) >> 1;
  359 
  360 if (dec_places < 0)
  361   num_digits = ctmp->m_apm_datalength;
  362 else
  363   num_digits = dec_places + 1;
  364 
  365 cp = s;
  366 
  367 if (ctmp->m_apm_sign == -1)
  368   *cp++ = '-';
  369 
  370 first = TRUE;
  371 
  372 i = 0;
  373 index = 0;
  374 
  375 while (TRUE)
  376   {
  377    if (index >= max_i)
  378      {
  379       numdiv = 0;
  380       numrem = 0;
  381      }
  382    else
  383       M_get_div_rem_10((int)ctmp->m_apm_data[index],&numdiv,&numrem);
  384 
  385    index++;
  386 
  387    *cp++ = numdiv + '0';
  388 
  389    if (++i == num_digits)
  390      break;
  391 
  392    if (first)
  393      {
  394       first = FALSE;
  395       *cp++ = '.';
  396      }
  397 
  398    *cp++ = numrem + '0';
  399 
  400    if (++i == num_digits)
  401      break;
  402   }
  403 
  404 i = ctmp->m_apm_exponent - 1;
  405 if (i >= 0)
  406   sprintf(cp,"E+%d",i);
  407 else
  408   sprintf(cp,"E%d",i);
  409 
  410 M_restore_stack(1);
  411 }
  412 /****************************************************************************/