Diff for /parser3/src/classes/math.C between versions 1.17 and 1.20

version 1.17, 2002/04/10 09:53:14 version 1.20, 2002/06/25 13:36:44
Line 1 Line 1
 /** @file  /** @file
         Parser: @b math parser class.          Parser: @b math parser class.
   
         Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)          Copyright(c) 2001, 2002 ArtLebedev Group(http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru>(http://paf.design.ru)
   
         $Id$          $Id$
 */  */
Line 11 Line 11
 #include "pa_vint.h"  #include "pa_vint.h"
 #include "pa_vmath.h"  #include "pa_vmath.h"
 #include "pa_request.h"  #include "pa_request.h"
   #include "pa_md5.h"
   
 #ifdef WIN32  #ifdef WIN32
   // for threadID
 #       include <windows.h>  #       include <windows.h>
 #endif  #endif
   
   #ifdef HAVE_CRYPT_H
   #include <crypt.h>
   #endif
   
 // defines  // defines
   
 #define PI 3.1415926535  #define PI 3.1415926535
 #define MATH_CLASS_NAME "math"  #define MAX_SALT 8
   
 // class  // class
   
Line 34  public: // Methoded Line 40  public: // Methoded
   
 // methods  // methods
 static unsigned int randomizer=0;  static unsigned int randomizer=0;
   static inline int _random(uint top) {
           return (int)(((double)((randomizer=rand())% RAND_MAX)) / RAND_MAX * top );
   }
 static void _random(Request& r, const String& method_name, MethodParams *params) {  static void _random(Request& r, const String& method_name, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
   
Line 42  static void _random(Request& r, const St Line 51  static void _random(Request& r, const St
     if(top<=1)      if(top<=1)
                 throw Exception("parser.runtime",                  throw Exception("parser.runtime",
                         &method_name,                          &method_name,
                         "top must be above 1 (%g)", top);                          "top must be above 1(%g)", top);
                   
         Value& result=*new(pool) VInt(pool, (int)(          r.write_no_lang(*new(pool) VInt(pool, _random(uint(top))));
                 ((double)((randomizer=rand())% RAND_MAX)) / RAND_MAX * uint(top) ));  
         result.set_name(method_name);  
         r.write_no_lang(result);  
 }  }
   
   
 typedef double (*math1_func_ptr)(double);  typedef double(*math1_func_ptr)(double);
 static double frac(double param) { return param-trunc(param); }  static double frac(double param) { return param-trunc(param); }
 static double degrees(double param) { return param /PI *180; }  static double degrees(double param) { return param /PI *180; }
 static double radians(double param) { return param /180 *PI; }  static double radians(double param) { return param /180 *PI; }
Line 62  static void math1(Request& r, Line 68  static void math1(Request& r,
         Pool& pool=r.pool();          Pool& pool=r.pool();
         Value& param=params->as_junction(0, "parameter must be expression");          Value& param=params->as_junction(0, "parameter must be expression");
   
         Value& result=*new(pool) VDouble(pool, (*func)(r.process_to_value(param).as_double()));          double result=(*func)(r.process_to_value(param).as_double());
         result.set_name(method_name);          r.write_no_lang(*new(pool) VDouble(pool, result));
         r.write_no_lang(result);  
 }  }
   
 #define MATH1(name) \  #define MATH1(name) \
Line 94  static void math2(Request& r, Line 99  static void math2(Request& r,
         Value& a=params->as_junction(0, "parameter must be expression");          Value& a=params->as_junction(0, "parameter must be expression");
         Value& b=params->as_junction(1, "parameter must be expression");          Value& b=params->as_junction(1, "parameter must be expression");
   
         Value& result=*new(pool) VDouble(pool, (*func)(          double result=(*func)(
                 r.process_to_value(a).as_double(),                  r.process_to_value(a).as_double(),
                 r.process_to_value(b).as_double()));                  r.process_to_value(b).as_double());
         result.set_name(method_name);          r.write_no_lang(*new(pool) VDouble(pool, result));
         r.write_no_lang(result);  
 }  }
   
 #define MATH2(name) \  #define MATH2(name) \
Line 107  static void math2(Request& r, Line 111  static void math2(Request& r,
         }          }
 MATH2(pow);  MATH2(pow);
   
   inline bool is_salt_body_char(int c) {
           return isalnum(c) || c == '.' || c=='/';
   }
   static size_t calc_prefix_size(const char *salt) {
           if(size_t salt_size=strlen(salt)) {
                   if(!is_salt_body_char(salt[0])) { // $...  {...
                           const char *cur=salt+1; // skip
                           while(is_salt_body_char(*cur++)) // ...$  ...}
                                   ;
                           return cur-salt;
                   } else
                           return 0;
           } else
                   return 0;
   }
   static void _crypt(Request& r, const String& method_name, MethodParams *params) {
           Pool& pool=r.pool();
           const char *password=params->as_string(0, "password must be string").cstr();
           const char *maybe_bodyless_salt=params->as_string(1, "salt must be string").cstr();
   
           size_t prefix_size=calc_prefix_size(maybe_bodyless_salt);
           const char *normal_salt;
           char normalize_buf[MAX_STRING];
           if(prefix_size==strlen(maybe_bodyless_salt)) { // bodyless?
                   strncpy(normalize_buf, maybe_bodyless_salt, MAX_STRING-MAX_SALT-1);
                   char *cur=normalize_buf+strlen(normalize_buf);
                   // sould add up MAX_SALT random chars
                   static unsigned char itoa64[] =         /* 0 ... 63 => ASCII - 64 */
                   "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
                   for(int i=0; i<MAX_SALT; i++)
                           *cur++=itoa64[_random(64)];
                   *cur=0;
                   normal_salt=normalize_buf;
           } else
                   normal_salt=maybe_bodyless_salt;
   
       /* FreeBSD style MD5 string 
        */
       if(strncmp(normal_salt, PA_MD5PW_ID, PA_MD5PW_IDLEN) == 0) {
                   const size_t sample_size=120;
                   char *sample_buf=(char *)pool.malloc(sample_size);
                   pa_MD5Encode((const unsigned char *)password,
                                   (const unsigned char *)normal_salt, sample_buf, sample_size);
                   r.write_pass_lang(*new(pool) String(pool, sample_buf));
       } else {
   #ifdef HAVE_CRYPT
                   const char *sample_buf=crypt(password, normal_salt);
                   if(!sample_buf  // nothing generated
                           || !sample_buf[0] // generated nothing
                           || strncmp(sample_buf, normal_salt, prefix_size)!=0) // salt prefix not preserved
                           throw Exception("parser.runtime",
                                   &method_name,
                                   "this platform does not support '%*s' salt prefix", prefix_size, normal_salt);
                   
                   r.write_pass_lang(*new(pool) String(pool, sample_buf));
   #else
                   throw Exception("parser.runtime",
                           &method_name,
                           "salt must start with '" PA_MD5PW_ID "'");
   #endif
           }
   }
   
 // constructor  // constructor
   
 MMath::MMath(Pool& apool) : Methoded(apool) {  MMath::MMath(Pool& apool) : Methoded(apool, "math") {
         set_name(*NEW String(pool(), MATH_CLASS_NAME));  
           
         // ^FUNC(expr)            // ^FUNC(expr)  
 #define ADD1(name) \  #define ADD1(name) \
         add_native_method(#name, Method::CT_STATIC, _##name, 1, 1)          add_native_method(#name, Method::CT_STATIC, _##name, 1, 1)
Line 133  MMath::MMath(Pool& apool) : Methoded(apo Line 198  MMath::MMath(Pool& apool) : Methoded(apo
         // ^pow(x;y)          // ^pow(x;y)
         ADD2(pow);          ADD2(pow);
   
           // ^crypt[password;salt]
           ADD2(crypt);
 }  }
   
 // in MSVC each thread has it's own pseudo-random sequence  // in MSVC each thread has it's own pseudo-random sequence
Line 147  void MMath::configure_admin(Request&) { Line 214  void MMath::configure_admin(Request&) {
 #else  #else
                 ^ getpid()                  ^ getpid()
 #endif  #endif
                 ^ (unsigned int)time(NULL)                  ^(unsigned int)time(NULL)
         );          );
         if(!randomizer)          if(!randomizer)
                 randomizer=rand();                  randomizer=rand();

Removed from v.1.17  
changed lines
  Added in v.1.20


E-mail: