home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (C) 1988 Free Software Foundation
- written by Doug Lea (dl@rocky.oswego.edu)
-
- This file is part of GNU CC.
-
- GNU CC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY. No author or distributor
- accepts responsibility to anyone for the consequences of using it
- or for whether it serves any particular purpose or works at all,
- unless he says so in writing. Refer to the GNU CC General Public
- License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- GNU CC, but only under the conditions described in the
- GNU CC General Public License. A copy of this license is
- supposed to have been given to you along with GNU CC so you
- can know your rights and responsibilities. It should be in a
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies.
- */
-
- #include <builtin.h>
- #include <math.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include "libconfig.h"
- #include <Obstack.h>
-
- /*
- common functions on built-in types
- */
-
- long gcd(long x, long y) // euclid's algorithm
- {
- long a = abs(x);
- long b = abs(y);
-
- long tmp;
-
- if (b > a)
- {
- tmp = a; a = b; b = a;
- }
- for(;;)
- {
- if (b == 0)
- return a;
- else if (b == 1)
- return b;
- else
- {
- tmp = b;
- b = a % b;
- a = tmp;
- }
- }
- }
-
- double pow(double x, long p)
- {
- if (p == 0)
- return (x < 0 && (p & 1)) ? -1.0 : 1.0;
- else if (x == 0.0)
- return 0.0;
- else
- {
- double b;
- if (p < 0)
- {
- p = -p;
- b = 1.0 / x;
- }
- else
- b = x;
- double r = 1.0;
- for(;;)
- {
- if (p & 1)
- r *= b;
- if ((p >>= 1) == 0)
- return r;
- else
- b *= b;
- }
- }
- }
-
- long lg(long x)
- {
- long l = 0;
- unsigned long a = abs(x);
-
- while (a > 1)
- {
- a = a >> 1;
- ++l;
- }
- return l;
- }
-
- long pow(long x, long y)
- {
- if (x == 0)
- return (y == 0)? 1 : 0;
- else if (y < 0)
- return 0;
- else if (y == 0 || x == 1)
- return 1;
- else if (x == -1)
- return (y & 1)? -1 : 1;
- else
- {
- long r = 1;
- for(;;)
- {
- if (y & 1)
- r *= x;
- if ((y >>= 1) == 0)
- return r;
- else
- x *= x;
- }
- }
- }
-
- long sqrt(long x)
- {
- if (x <= 0)
- return 0; // no int error handler, so ...
- else if (x == 1)
- return 1;
- else
- {
- long r = x >> 1;
- long q;
- for(;;)
- {
- q = x / r;
- if (q >= r)
- return r;
- else
- r = (r + q) >> 1;
- }
- }
- }
-
-
- // Obstacks are used as an easy way to allocate enough space
- // for various input and output & conversion operations
- // (they are a real natural for input; we might as well use
- // them for output too rather than creating yet another allocation
- // mechanism.)
- //
- // We guarantee that ONLY the most recently constructed
- // obstack object is intact. There is no queuing mechanism.
- // This is a firmer policy than using a queue that may or may
- // not have enough space to hold several objects.
-
- Obstack _libgxx_io_ob;
- char* _libgxx_io_oblast = 0;
-
-
-
- char* form(const char* fmt ...)
- {
- va_list args;
- va_start(args, fmt);
- if (_libgxx_io_oblast) _libgxx_io_ob.free(_libgxx_io_oblast);
- _libgxx_io_ob.blank(BUFSIZ);
- _libgxx_io_oblast = (char*)(_libgxx_io_ob.finish());
- char* obbase = _libgxx_io_oblast;
- #ifndef HAVE_VPRINTF
- FILE b;
- b._flag = _IOWRT|_IOSTRG;
- b._ptr = obbase;
- b._cnt = BUFSIZ;
- _doprnt(fmt, args, &b);
- putc('\0', &b);
- #else
- vsprintf(obbase, fmt, args);
- #endif
- va_end(args);
- return obbase;
- }
-
- char* itoa(long x, int base = 10, int width = 0)
- {
- if (_libgxx_io_oblast) _libgxx_io_ob.free(_libgxx_io_oblast);
- int wrksiz = 100 + width;
- _libgxx_io_ob.blank(wrksiz);
- _libgxx_io_oblast = (char*)(_libgxx_io_ob.finish());
- char* obbase = _libgxx_io_oblast;
- char* e = obbase + wrksiz - 1;
- char* s = e;
- *--s = 0;
- char sgn = 0;
-
- if (x == 0)
- *--s = '0';
- else
- {
- int z;
- if (x < 0)
- {
- sgn = '-';
- z = -x;
- }
- else
- z = x;
- while (z != 0)
- {
- char ch = z % base;
- z = z / base;
- if (ch >= 10)
- ch += 'a' - 10;
- else
- ch += '0';
- *--s = ch;
- }
- }
-
- if (sgn) *--s = sgn;
- int w = e - s - 1;
- while (w++ < width)
- *--s = ' ';
- return s;
- }
-
- char* hex(long i, int width = 0)
- {
- return itoa(i, 16, width);
- }
-
- char* oct(long i, int width = 0)
- {
- return itoa(i, 8, width);
- }
-
- char* dec(long i, int width = 0)
- {
- return itoa(i, 10, width);
- }
-
- static char chr_buf[2]; // fixed slot to hold chr(ch)
-
- char* chr(char ch)
- {
- chr_buf[0] = ch;
- chr_buf[1] = 0;
- return chr_buf;
- }
-
- /*
- some useful hash functions
- */
-
- unsigned int hashpjw(const char* x) // From Dragon book, p436
- {
- unsigned int h = 0;
- unsigned int g;
-
- while (*x != 0)
- {
- h = (h << 4) + *x++;
- if ((g = h & 0xf0000000) != 0)
- h = (h ^ (g >> 24)) ^ g;
- }
- return h;
- }
-
- unsigned int multiplicativehash(int x)
- {
- // uses a const close to golden ratio * pow(2,32)
- return ((unsigned)x) * 2654435767;
- }
-
-
- unsigned int foldhash(double x)
- {
- union { unsigned int i[2]; double d; } u;
- u.d = x;
- unsigned int u0 = u.i[0];
- unsigned int u1 = u.i[1];
- return u0 ^ u1;
- }
-
- void default_one_arg_error_handler(const char* msg)
- {
- fputs("Error: ", stderr);
- fputs(msg, stderr);
- fputs("\n", stderr);
- abort();
- }
-
-
- void default_two_arg_error_handler(const char* kind, const char* msg)
- {
- fputs(kind, stderr);
- fputs(" Error: ", stderr);
- fputs(msg, stderr);
- fputs("\n", stderr);
- abort();
- }
-
- two_arg_error_handler_t lib_error_handler = default_two_arg_error_handler;
-
- two_arg_error_handler_t set_lib_error_handler(two_arg_error_handler_t f)
- {
- two_arg_error_handler_t old = lib_error_handler;
- lib_error_handler = f;
- return old;
- }
-
-
- // from Doug Schmidt...
-
- /* no such thing as "negative time"! */
- #define TIMER_ERROR_VALUE -1.0
-
- // surely OK for these machines...
-
- #if defined(BSD) || defined(vax) || defined(sun)
-
- extern "C" {
- #include <sys/time.h>
- #include <sys/resource.h>
- int getrusage(int, struct rusage*);
- }
-
- static struct rusage Old_Time;
- static struct rusage New_Time;
- static int Timer_Set = 0;
-
- double start_timer()
- {
- Timer_Set = 1;
- getrusage(RUSAGE_SELF,&Old_Time); /* set starting process time */
- return(Old_Time.ru_utime.tv_sec + (Old_Time.ru_utime.tv_usec / 1000000.0));
- }
-
- /* returns process time since Last_Time (if parameter is not DEFAULT_TIME, */
- /* i.e., (double) 0.0 ),otherwise, if parameter == DEFAULT_TIME then */
- /* the time since the Old_Time was set is returned. */
- /* Returns TIMER_ERROR_VALUE */
- /* if Start_Timer() is not called first */
-
- double return_elapsed_time(double Last_Time)
- {
- if (!Timer_Set) {
- return(TIMER_ERROR_VALUE);
- }
- else {
- /* get process time */
- getrusage(RUSAGE_SELF,&New_Time);
- if (Last_Time == 0.0) {
- return((New_Time.ru_utime.tv_sec - Old_Time.ru_utime.tv_sec) +
- ((New_Time.ru_utime.tv_usec - Old_Time.ru_utime.tv_usec)
- / 1000000.0));
- }
- else {
- return((New_Time.ru_utime.tv_sec +
- (New_Time.ru_utime.tv_usec / 1000000.0)) - Last_Time);
- }
- }
- }
-
- #else /* dummy them out */
- double start_timer()
- {
- return TIMER_ERROR_VALUE;
- }
-
- double return_elapsed_time(double)
- {
- return TIMER_ERROR_VALUE;
- }
-
- #endif
-