diff --git a/src/libraries/libmisc/ChangeLog b/src/libraries/libmisc/ChangeLog new file mode 100644 index 0000000000000000000000000000000000000000..9f0ce4f5f06aa41c5e1baa0e812f37b6fff86067 --- /dev/null +++ b/src/libraries/libmisc/ChangeLog @@ -0,0 +1,27 @@ +Thu Dec 20 04:59:36 1990 Thomas Bellman (bellman at lave) + + * s-string.[ch]: s_strchr() och s_strrchr(): Lade till en + parameter som anger var s|kningen ska b|rja. + + * s-string.c: [ndrat fr}n if-satser f|r kontroll av parametrar + till att anv{nda assert()-makrot. + + * s-string.[ch]: Lade till s_strrchr(). + + * zmalloc.c: Fixat en del buggar d{r pekare till z_info-structen + returnerades i st f pekare efter denna, samt lite annat. + +Sat Dec 8 03:05:51 1990 Thomas Bellman (bellman at laila) + + * [ndrade tillbaka s_strcpy(). Den ska sl{ppa loss minnet {ven om + den f}r en EMPTY_STRING. + +Sat Dec 1 12:09:35 1990 Lars Willf|r (willfor at nanny) + + * [ndrade s_strcpy s} att den med s{kerhet fungerar {ven om + source_string == EMPTY_STRING. + +Thu Aug 9 05:12:52 1990 Thomas Bellman (bellman at laila) + + * Biblioteket skapat ig}r. + diff --git a/src/libraries/libmisc/pom.c b/src/libraries/libmisc/pom.c new file mode 100644 index 0000000000000000000000000000000000000000..41e8d4c7862ec3e84b598086ca9c69bad9f58f97 --- /dev/null +++ b/src/libraries/libmisc/pom.c @@ -0,0 +1,168 @@ +/* + * pom.c -- Calculate the Phase Of the Moon + * + * Written by G|ran ]hlstr|m 1984-04-05, revision 5 1986-03-03 + * + * Modified by Thomas Bellman 1991-01-29 + */ + +#include <sys/types.h> +#include <time.h> +#include <math.h> +#include <stdio.h> + +#include "pom.h" + + +#define EXPORT + + +#define RADS (M_PI/180.0) + +static char * pmt[] = { "NM", "FQ", "FM", "LQ" }; +static short ix; +static double m; /* Sun's Mean Anomaly */ +static double mp; /* Moon's Mean Anomaly */ +static double f; /* Moon's Argument of Latitude */ +static struct tm dt; + + +/* New & Full Moon correction */ +static double +mcorr (double t) + +{ + double tmp; + + tmp = (0.1734-3.93E-4*t) * sin(m) + 0.0021 * sin(2.0*m) - 0.4068 * sin(mp); + tmp += 0.0161 * sin(2.0*mp) - 0.0004 * sin(3.0*mp) + 0.0104 * sin(2.0*f); + tmp += 0.0004 * sin(2.0*f + m) - 0.0051 * sin(m+mp) - 0.0074 * sin(m-mp); + tmp -= 0.0004 * sin(2.0*f - m) + 0.0006 * sin(2.0*f + mp); + return tmp += 0.0010 * sin(2.0*f - mp) + 0.0005 * sin(m + 2.0*mp); +} + + + +/* First & Last Quarter correction */ +static double +qcorr (double t) + +{ + double tmp, tmp2; + + tmp = (0.1721 - 0.0004*t) * sin(m) + 0.0021 * sin(2.0*m) - 0.628 * sin(mp); + tmp += 0.0089 * sin(2.0*mp) - 0.0004 * sin(3.0*mp) + 0.0079 * sin(2.0*f); + tmp += 0.0003 * sin(2.0*f + m) - 0.0119 * sin(m+mp) - 0.0047 * sin(m-mp); + tmp += 0.0021 * sin(2.0*f - mp) - 0.0004 * sin(2.0*f - m); + tmp += -0.0006 * sin(2.0*f + mp) + 0.0003 * sin(m + 2.0*mp); + tmp += 0.0004 * sin(m - 2.0*mp) - 0.0003 * sin(2.0*m + mp); + tmp2 = (0.0028 - 0.0004 * cos (m) + 0.0003 * cos (mp)); + if (ix == 1) + tmp += tmp2; + else + tmp -= tmp2; + + return tmp; +} + + + +/* When is nearest phase? */ +static double +pcon (void) + +{ + double frc; + double year; + double k; + double t; + double tmp; + int leap; + + + year = (dt.tm_hour + ((dt.tm_min + (dt.tm_sec / 60.0)) / 60.0)) / 24.0; + year += dt.tm_yday; + + /* Leap year? */ + leap = dt.tm_year + 1900; + leap = (leap % 4 == 0 && (leap % 100 != 0 || leap % 400 == 0)); + + /* This year with decimals */ + year = dt.tm_year + year / (365.0 + leap); + + k = year * 12.3685; + k -= (frc = k - floor (k)); + + /* Determine nearest phase */ + for ( ix = 0 ; frc > ix * 0.25 + 0.125 ; ix++ ) + ; + t = (k += ix * 0.25) / 1236.85; + tmp = 2415020.75933 + 29.53058868 * k + + (1.178E-4 - 1.55E-7 * t) * pow (t, 2.0); + tmp += 3.3E-4 * sin (166.56*RADS + 132.87*RADS * t + - 9.173E-3*RADS * pow(t, 2.0)); + m = RADS * fmod (359.2242 + 29.10535608 * k + - (3.47e-6*t + 3.33e-5) * pow (t, 2.0), 360.0); + mp = RADS * fmod (306.0253 + 385.81691806 * k + + (1.236e-5*t + 0.0107306) * pow (t, 2.0), 360.0); + f = RADS * fmod (21.2964 + 390.67050646 * k + - (2.39e-6*t + 1.6528e-3) * pow (t, 2.0), 360.0); + return tmp += ((ix % 2 == 0) ? mcorr (t) : qcorr (t)); +} + + + +/* JD at this instant */ +static double +dcon (void) + +{ + double a, b, d, m, y; + + + m = dt.tm_mon; + y = dt.tm_year + 1900.0; + d = dt.tm_mday + dt.tm_hour / 24.0 + dt.tm_min / 1440.0 + + dt.tm_sec / 86400.0; + if (m <= 2.0) + { + y -= 1.0; + m += 12.0; + } + a = floor (y/100.0); /* Gregorian Calendar correction */ + b = 2.0 - a + floor (a / 4.0); + return (floor (365.25 * y) + floor (30.6001 * (m+1.0)) + d + 1720994.5 + b); +} + + + +EXPORT struct pom +phase_of_the_moon (struct tm * when) + +{ + int p1, p2, p3, p4; + char sgn; + long ts; + double tmp; + struct pom result; + + + dt = *when; + dt.tm_mon++; + dt.tm_yday++; + tmp = pcon() - dcon(); + sgn = (tmp > 0) ? '-' : '+'; + tmp = fabs (tmp); + tmp -= (p1 = floor (tmp)); + tmp = tmp * 24.0 - (p2 = floor (tmp * 24.0)); + tmp = tmp * 60.0 - (p3 = floor (tmp * 60.0)); + p4 = floor (tmp * 60.0); + + result.quarter = ix % 4; + result.days = (sgn == '+') ? p1 : -p1; + result.hours = (sgn == '+') ? p2 : -p2; + result.minutes = (sgn == '+') ? p3 : -p3; + result.seconds = (sgn == '+') ? p4 : -p4; + + return result; +} diff --git a/src/libraries/libmisc/pom.h b/src/libraries/libmisc/pom.h new file mode 100644 index 0000000000000000000000000000000000000000..f0f7c32d17f76a52befd8582ff0e19d56cfa8d98 --- /dev/null +++ b/src/libraries/libmisc/pom.h @@ -0,0 +1,34 @@ +/* + * pom.h + * Calculate the phase of the moon at any given time. + * + * + * This file is in the public domain. No rights reserved. + */ + + +#ifndef POM_H_INCLUDED__ +#define POM_H_INCLUDED__ + + +struct pom { + enum { pom_NM, pom_FQ, pom_FM, pom_LQ } + quarter; /* Nearest quarter */ + /* Time since nearest quarter. All fields are negative if + * nearest quarter is in the future. */ + int days; + int hours; + int minutes; + int seconds; +}; + + +/* + * Calculate the phase of the moon at the time WHEN, which should be + * the GMT time. + */ +extern struct pom +phase_of_the_moon (struct tm * when); + + +#endif /* POM_H_INCLUDED__ */ diff --git a/src/libraries/libmisc/s-collat-tabs.c b/src/libraries/libmisc/s-collat-tabs.c new file mode 100644 index 0000000000000000000000000000000000000000..8d058b3c5e1552318d27c0d92226270777ce587f --- /dev/null +++ b/src/libraries/libmisc/s-collat-tabs.c @@ -0,0 +1,108 @@ +/* + * s-collat-tables.c -- Collating tables used for the s_usr_strcmp() + * routine in s-string.[ch] + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + */ + + +#include "s-collat-tables.h" + + +/* + * Collating tables: + * swedish_collate_tab: Swedish text. "][\}{|" in the right + * order. Upper and lower case letters + * are equal. + * english_collate_tab: English text. Upper and lower case + * letters are equal. + */ + + + +char swedish_collate_tab [ COLLAT_TAB_SIZE ] = + { + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + ' ', '!', '"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '}', '{', '|', '~', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '}', '{', '|', '~', '', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�' + }; + + + +char english_collate_tab [ COLLAT_TAB_SIZE ] = + { + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + ' ', '!', '"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '[', '\\', ']', '~', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', '', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�', + '�', '�', '�', '�', '�', '�', '�', '�' + }; diff --git a/src/libraries/libmisc/s-collat-tabs.h b/src/libraries/libmisc/s-collat-tabs.h new file mode 100644 index 0000000000000000000000000000000000000000..0c47985f8d2455a02085358be6993a30bb3da125 --- /dev/null +++ b/src/libraries/libmisc/s-collat-tabs.h @@ -0,0 +1,35 @@ +/* + * s-collat-tables.h -- Declarations for collating tables + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + * + * + * Any opinions expressed in this code are the author's PERSONAL opinions, + * and does NOT, repeat NOT, represent any official standpoint of Lysator, + * even if so stated. + */ + + +#include <limits.h> + +#define COLLAT_TAB_SIZE (UCHAR_MAX+1) + + +extern char swedish_collate_tab [ COLLAT_TAB_SIZE ]; +extern char english_collate_tab [ COLLAT_TAB_SIZE ]; +#if 0 +extern char iso8859_1_collate_tab [ COLLAT_TAB_SIZE ]; +#endif diff --git a/src/libraries/libmisc/s-string.c b/src/libraries/libmisc/s-string.c new file mode 100644 index 0000000000000000000000000000000000000000..30cfbe723f2c6d37101547b5bfb683d05d904f6d --- /dev/null +++ b/src/libraries/libmisc/s-string.c @@ -0,0 +1,881 @@ +/* + * s-string.c -- Routines for manipulating objects of type String. + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + * + * + * Any opinions expressed in this code are the author's PERSONAL opinions, + * and does NOT, repeat NOT, represent any official standpoint of Lysator, + * even if so stated. + */ + + +#include <sys/types.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdlib.h> +#include <assert.h> + +#include <misc-types.h> +#include "s-collat-tables.h" +#include "s-string.h" + + +#define EXPORT /* To emphasize objects that are exported */ + + +/* The empty String */ +EXPORT const String EMPTY_STRING = EMPTY_STRING_i; + + +static free_function x_free = NULL; +static malloc_function x_malloc = NULL; +static realloc_function x_realloc = NULL; + + + +/* + * Functions to manipulate strings of type 'String'. + * All these functions return a value of type Success, which is + * an enum of OK an FAILURE (do NOT trust the order of these!). + * + * All functions automatically allocates (and deallocates) any + * necessary storage, using the storage management functions + * defined by the s_set_storage_management() call. + */ + + +/* Macro to reallocate new storage. Works even if PTR is a + * nil pointer. */ +#define REALLOC_0(ptr, size) (((ptr) == NULL) \ + ? MALLOC_0 (size) \ + : (*x_realloc) ((ptr), size)) + +/* Free storage. Works even if PTR is a nil pointer. */ +#define FREE_0(ptr) (((ptr) == NULL) \ + ? ((void) 0) \ + : (*x_free) (ptr)) + +#define MALLOC_0(size) ((*x_malloc) (size)) + + +/* + * Set the functions to use for storage management. These must + * be call compatible with the normal functions malloc(), + * realloc() and free(). + */ +EXPORT void +s_set_storage_management (malloc_function new_malloc, + realloc_function new_realloc, + free_function new_free) + +{ + x_malloc = new_malloc; + x_realloc = new_realloc; + x_free = new_free; +} + + + +/* + * Create an object of type String from an ordinary C string. + */ +EXPORT Success +s_crea_str (String * dest_string, + const char * c_string ) + +{ + String_size length; + void * temp_ptr; /* To hold result from malloc/realloc + * before actually using it. */ + + length = strlen(c_string); + + temp_ptr = MALLOC_0 (length); + if (temp_ptr == NULL) + { + return FAILURE; + } + + FREE_0 (dest_string->string); + dest_string->string = temp_ptr; + + strncpy(dest_string->string, c_string, length); + dest_string->len = length; + + return OK; +} + + + +/* + * Return a temporary String from a C string, i e return a struct + * pointing to the actual C string. Suitable for sending a 'String' + * object as parameter to a function (IF that function does not modify + * it's parameter. Note that normally String variables should be set + * by s_crea_str(), to deallocate the memory used by it. + */ +EXPORT String +s_fcrea_str (const char * c_string) + +{ + String temp; + + /* Cast needed to make compiler not warn about assignment from + * const pointer to non-const pointer. Sigh... */ + temp.string = (char *) c_string; + temp.len = strlen(c_string); + return temp; +} + + + +/* + * Free's the space used by a String object. The object is + * set to EMPTY_STRING. + */ +EXPORT void +s_clear (String * str) +{ + FREE_0 (str->string); + *str = EMPTY_STRING; +} + + + +/* + * Copy SOURCE_STRING to DEST_STRING. Old value of DEST_STRING is + * retained if an error was encountered. If 'foo' is a separate + * String, then it is legal to do 's_strcpy(&foo, foo)'. + */ +EXPORT Success +s_strcpy (String * dest_string, + const String source_string) + +{ + void * temp_ptr; /* To hold result from malloc/realloc + * before actually using it. */ + + if (s_strlen(source_string) == 0) + { + s_clear (dest_string); + return OK; + } + + /* (Re-)allocate memory */ + temp_ptr = REALLOC_0 (dest_string->string, s_strlen(source_string)); + if (temp_ptr == NULL) + return FAILURE; + dest_string->string = temp_ptr; + + /* Copy the string */ + memcpy (dest_string->string, + source_string.string, + s_strlen (source_string)); + dest_string->len = s_strlen (source_string); + + return OK; +} + + + +/* + * In String STR remove the characters starting with number FIRST + * and ending with number LAST, inclusive. If FIRST > LAST, then + * no characters are removed. + */ +extern Success +s_strdel (String * str, + String_size first, + String_size last ) + +{ + String_size i; /* Just an index in a loop */ + + + assert ( first >= 0 && first <= s_strlen (*str) + && last >= -1 && last < s_strlen (*str)); + + for ( i = last + 1 ; i < s_strlen(*str) ; i++ ) + str->string [i-(last-first+1)] = str->string [i]; + + str->len -= last-first+1; + + return OK; +} + + + +/* + * Append SOURCE_STRING to the end of DEST_STRING. DEST_STRING is not + * changed if an error is encountered. + */ +EXPORT Success +s_strcat (String * dest_string, + const String source_string) + +{ + void * temp_ptr; /* To hold result from malloc/realloc + * before actually using it. */ + + /* (Re-)alloc space for new string */ + temp_ptr = REALLOC_0 (dest_string->string, + dest_string->len + source_string.len); + if (temp_ptr == NULL) + { + return FAILURE; + } + dest_string->string = (char *)temp_ptr; + + /* Append SOURCE_STRING to *DEST_STRING */ + memcpy (dest_string->string + s_strlen (*dest_string), + source_string.string, + s_strlen (source_string)); + dest_string->len += source_string.len; + + return OK; +} + + + +/* + * Extract a substring from SOURCE_STRING, starting with char no + * START_CHAR and ending with char no END_CHAR. First character + * is character no 0. If END_CHAR < START_CHAR, then DEST_STRING + * is set to 'EMPTY_STRING'. If END_CHAR is equal to the macro + * 'END_OF_STRING', then the substring reaches to the last character + * in SOURCE_STRING. + */ +EXPORT Success +s_substr (String * dest_string, + const String source_string, + String_size start_char, + String_size end_char) + +{ + String_size sub_len; /* Length of substring */ + void * temp_ptr; /* To hold result from malloc/realloc + * before really using it. */ + + if (end_char == END_OF_STRING) + end_char = s_strlen(source_string)-1; + + assert ( start_char >= 0 && end_char >= -1 + && start_char <= s_strlen (source_string) + && end_char < s_strlen (source_string)); + + sub_len = end_char - start_char + 1; + + /* Will the substring be empty? */ + if (sub_len <= 0) + { + s_clear (dest_string); /* Free and set to EMPTY_STRING */ + return OK; + } + + /* (Re-)allocate space for substring */ + temp_ptr = REALLOC_0(dest_string->string, sub_len); + if (temp_ptr == NULL) + { + return FAILURE; + } + dest_string->string = (char *)temp_ptr; + + /* Copy substring to DEST_STRING */ + memcpy (dest_string->string, + source_string.string + start_char, + sub_len); + dest_string->len = sub_len; + + return OK; +} + + + +/* + * Fast extraction of a substring. Returns an object of type + * String wich points into SOURCE_STRING. Thus you should NEVER + * modify the result of this function. (Raw character modifying + * is OK if you know what you are doing, but never use anything + * that might call free or realloc on it.) If END_CHAR is equal + * to the macro 'END_OF_STRING', then the substring reaches to + * the last character in SOURCE_STRING. + */ +EXPORT String +s_fsubstr (const String source_string, + String_size start_char, + String_size end_char ) + +{ + String sub_string; /* Substring struct */ + + + if (end_char == END_OF_STRING) + end_char = s_strlen(source_string)-1; + + assert ( start_char >= 0 && end_char >= -1 + && start_char <= s_strlen (source_string) + && end_char < s_strlen (source_string)); + + sub_string.len = end_char - start_char + 1; + + /* Is the substring empty? */ + if (sub_string.len < 1) + { + return EMPTY_STRING; + } + + sub_string.string = source_string.string + start_char; + + return sub_string; +} + + + +/* + * Returns -1 if ARG is negative, 0 if 0 and +1 if positive. + * Used in the string comparison routines. + */ +static int +sign (int arg) +{ + if (arg < 0) + return -1; + else if (arg == 0) + return 0; + else + return +1; +} + + + +/* + * Compares two strings. Returns -1 if STR1 is lexically less + * than STR2, +1 if STR1 is greater than STR2, and 0 if they are + * equal. + */ +EXPORT int +s_strcmp (String str1, + String str2) + +{ + u_int index; + String_size shortest; /* Length of the shortest string */ + int retval_based_on_lengths; + + + retval_based_on_lengths = sign(str1.len - str2.len); + + if (str1.len < str2.len) + shortest = str1.len; + else + shortest = str2.len; + + + /* If they point to the same string, then we only have to + * compare the lengths. */ + if (str1.string == str2.string) + return retval_based_on_lengths; + + + /* Find first diff:ing character (in [index]) */ + index = 0; + while ( (index < shortest) + && (str1.string[index] == str2.string[index]) ) + index++; + + /* If no diff:ing char, then the shortest is the "smallest" */ + if (index >= shortest) + return retval_based_on_lengths; + else /* ...else check which character was the "smallest". */ + return sign(str1.string[index] - str2.string[index]); + +} + + + +/* + * Makes INDEX (type char) positive. Those that are negative, + * result in a positive number above the other numbers. This + * works as if bitcopying a 2's complement nuber to an unsigned + * number. + * + * NOTE: This code might need to be modified for some arhitectures. + */ +#define POS_INDEX(index) ((u_char)(index)) + +/* + * Compares two strings with user specified collation order. + * Returns the same values as s_srcmp(). + * COLLAT_TAB is a table of collating values for every char. + */ +EXPORT int +s_usr_strcmp (String str1, + String str2, + char * collat_tab) + +{ + u_int index; + String_size shortest; /* Length of the shortest string */ + int retval_based_on_lengths; + + + retval_based_on_lengths = sign(str1.len - str2.len); + + if (str1.len < str2.len) + shortest = str1.len; + else + shortest = str2.len; + + + /* If they point to the same string, then we only have to + * compare the lengths. */ + if (str1.string == str2.string) + return retval_based_on_lengths; + + + /* Find first diff:ing character (in [index-1]) */ + index = 0; + while ( (index < shortest) + && ( collat_tab [ POS_INDEX( str1.string [index] )] + == collat_tab [ POS_INDEX( str2.string [index] )]) ) + index++; + + + /* If no diff:ing char, then the shortest is the "smallest" */ + if (index >= shortest) + return retval_based_on_lengths; + + /* ...else check which character was the "smallest". */ + else + return sign( collat_tab [ POS_INDEX( str1.string[index] )] + - collat_tab [ POS_INDEX( str2.string[index] )] ); + +} + + + +/* + * Checks if STR1 is the exact beginning of STR2, e g if STR1 + * is "foobar" and STR2 is "foobarf" then the result is TRUE. + */ +EXPORT Bool +s_strhead (String str1, + String str2) + +{ + String_size i; /* Index in comparison loop */ + + + /* If STR1 is longer than STR2, then it can't be a head. */ + if (s_strlen(str1) > s_strlen(str2)) + return FALSE; + + /* If they point to the same string, then STR1 is a head + * of STR2. (We have already compared the lengths.) */ + if (str1.string == str2.string) + return TRUE; + + /* Check character by character */ + for ( i = 0 ; i < s_strlen(str1) ; i++) + if (str1.string[i] != str2.string[i]) + return FALSE; /* Diff. found, so not head. */ + + /* No differences found */ + return TRUE; +} + + + +/* + * Checks if STR1 is the exact beginning of STR2, but uses a + * user specified collating sequence for comparison (as in + * s_usr_strcmp()). + */ +EXPORT Bool +s_usr_strhead (String str1, + String str2, + char collat_tab [ COLLAT_TAB_SIZE ]) + +{ + String_size i; /* Index in comparison loop */ + + + /* If STR1 is longer than STR2, then it can't be a head. */ + if (s_strlen(str1) > s_strlen(str2)) + return FALSE; + + /* If they point to the same string, then STR1 is a head + * of STR2. (We have already compared the lengths.) */ + if (str1.string == str2.string) + return TRUE; + + /* Check character by character */ + for ( i = 0 ; i < s_strlen(str1) ; i++) + { + if ( collat_tab [ POS_INDEX( str1.string[i] )] + != collat_tab [ POS_INDEX( str2.string[i] )] ) + { + return FALSE; /* Diff. found, so not head. */ + } + } + + /* No differences found */ + return TRUE; +} + + + + +/* + * From STR strip all trailing characters that can be found + * in STRIP_STRING. + */ +extern String +s_strip_trailing (String str, + const String strip_string) + +{ + while ( s_strlen (str) > 0 + && s_strchr (strip_string, + str.string[s_strlen(str) - 1], 0) != -1) + str.len--; + return str; +} + + + + +/* + * Returns the index of the first occurrence in the String STR + * of the character CH, starting at position STAR_POS. Returns + * -1 if no occurrence. + */ +EXPORT String_size +s_strchr (const String str, + char ch, + String_size start_pos) + +{ + char * ptr; + + assert (start_pos >= 0 && start_pos <= s_strlen (str)); + + ptr = memchr (str.string + start_pos, ch, s_strlen (str) - start_pos); + if (ptr == NULL) + return -1; + else + return ptr - str.string; +} + + + +/* + * Returns the index of the last occurrence in the String STR + * of the character CH, starting at position START_POS. Returns + * -1 if no occurrence. + */ +EXPORT String_size +s_strrchr (const String str, + char ch, + String_size start_pos) + +{ + String_size index; + + if (start_pos == END_OF_STRING) + start_pos = s_strlen (str) - 1; + + assert (start_pos >= -1 && start_pos < s_strlen (str)); + + index = start_pos; + while (index >= 0 && str.string[index] != ch) + index--; + + return index; /* This will be -1 if not found. */ +} + + + + +/* + * Return the index of the first occurrence in the String LOOK_IN + * of any of the characters in the String SEARCH_FOR, or -1 if none. + */ +extern String_size +s_strpbrk (const String look_in, + const String search_for) + +{ + String_size i; + + for ( i = 0 ; i < s_strlen (look_in) ; i++ ) + if (s_strchr (search_for, look_in.string[i], 0) != -1) + return i; + + return -1; +} + + + + +/* + * Find the first character in LOOK_IN that *is* present in + * SEARCH_FOR, and return its index, or the length of LOOK_IN if + * it contains only characters that are not present in SEARCH_FOR. + */ +extern String_size +s_strcspn (const String look_in, + const String search_for) + +{ + String_size i; + + i = 0; + while ( i < s_strlen (look_in) + && s_strchr (search_for, look_in.string[i], 0) == -1) + i++; + return i; +} + + + + +/* + * Find the first character in LOOK_IN that is *not* present in + * SKIP_CHARS, and return its index, or the length of LOOK_IN if + * it contains only characters that are present in SKIP_CHARS. + */ +extern String_size +s_strspn (const String look_in, + const String skip_chars) + +{ + String_size i; + + i = 0; + while ( i < s_strlen (look_in) + && s_strchr (skip_chars, look_in.string[i], 0) != -1) + i++; + return i; +} + + + + + +/* + * Pick out the first token from SOURCE separated by one or more + * of the characters in SEPARATORS, starting in position START_POS. + * + * More specifically: start in position START_POS and skip over + * separator characters (any of those present in SEPARATORS). + * Extract the substring starting with the first non-separator, + * and ending the character immediately before the first separator + * following. *start_pos will be the index of the first separator + * character after the token. + * + * Note that the return value actually points into SOURCE. It + * is not separately allocated. + */ +EXPORT String +s_strtok (const String source, + String_size * start_pos, + const String separators) + +{ + String_size first_char; /* First character in token */ + String_size end_char; /* First character after token */ + + + /* Check of parameters - we might save some time on this */ + if ( (*start_pos >= s_strlen(source)) + || s_empty(separators) || s_empty(source) ) + { + return EMPTY_STRING; + } + + /* Skip leading separators */ + first_char = *start_pos; + while ( (first_char < s_strlen(source)) + && (s_strchr (separators, source.string[first_char], 0) != -1) ) + first_char++; + + /* End of source string? Then we can stop here. */ + if (first_char >= s_strlen(source)) + { + *start_pos = first_char; + return EMPTY_STRING; + } + + /* Find next separator */ + end_char = first_char; + while ( (end_char < s_strlen(source)) + && (s_strchr (separators, source.string[end_char], 0) == -1) ) + end_char++; + + /* OK, we're practically done. */ + *start_pos = end_char; + return s_fsubstr(source, first_char, end_char-1); +} + + + + +/**************************************************** + * Misc. routines using our String type. * + ****************************************************/ + + +/* + * Convert a char to a number in base BASE. + */ +static int +char2digit (const char ch, + const int base) +{ + int index; + static char * translate_table = + "0123456789abcdefghijklmnopqrstuvwxyz"; + + index = 0; + while ( (index < base) + && ( translate_table[index] + != (isalpha(ch) ? tolower(ch) : ch))) + index++; + + if (index >= base) + return -1; + else + return index; +} + + + +/* + * Convert the String STR to a long, using the base BASE. + * Leading blanks are skipped according to isblank() in <ctype.h>. + * The index of the first character that couldn't be used to form + * the number is returned in *FIRST_ILL_CHAR. Returns -1 in + * *first_ill_char if there was an error in the parameters. + * BASE may be in the range 2..36 + */ +#define MAXBASE 36 +EXPORT long +s_strtol (const String str, + String_size * first_ill_char, + const int base ) + +{ + long number = 0; /* The result */ + int sign = 0; /* Sign o' the times :-) */ + String_size char_no; + int digit; + + + assert (base >= 2 && base <= MAXBASE); + + if (s_empty(str)) + { + *first_ill_char = -1; + return 0; + } + + + /* Skip all blanks */ + char_no = 0; + while ( (char_no < s_strlen(str)) && isspace(str.string[char_no]) ) + char_no++; + + /* Find any sign character (+ or -) */ + if (str.string[char_no] == '+') + { + sign = +1; + char_no++; + } + else if (str.string[char_no] == '-') + { + sign = -1; + char_no++; + } + + while ( (char_no < s_strlen(str)) + && ((digit = char2digit(str.string[char_no], base)) != -1) ) + { + number = number * base + digit; + char_no++; + } + + *first_ill_char = char_no++; + if (sign != -1) + return number; + else + return -number; +} + + + + +/************************************************ + * Input/Output routines for String * + ************************************************/ + + + +/* + * Outputs the string STR on the stream STREAM. No information + * about the length of the string is output. + */ +EXPORT Success +s_fputs (FILE * stream, + const String str) + +{ + String_size i; + + for ( i = 0 ; i < str.len ; i++ ) + putc (str.string[i], stream); + + return OK; +} + + +/* + * Create an ordinary C string from a String. + * The pointer returned will point to a '\0'-terminated character + * array which is obtained with the malloc-function supplied to + * s_set_storage_management(). It should be freed by the caller. + * NULL is returned if there is an error. The String may contain + * '\0's, but the resulting string will be truncated at the first + * '\n'. Thou shalt not depend on this behaviour. Later versions + * might substitute "foobar" for '\0's. + */ + +EXPORT char * +s_crea_c_str(const String source) +{ + char *dest; + + dest = MALLOC_0( 1 + s_strlen(source) ); + + if ( dest == NULL ) + return NULL; + + memcpy(dest, source.string, s_strlen(source)); + dest[ s_strlen(source) ] = '\0'; + return dest; +} diff --git a/src/libraries/libmisc/s-string.h b/src/libraries/libmisc/s-string.h new file mode 100644 index 0000000000000000000000000000000000000000..bc4c4ab189d2bca9186a9730ef783a4b684df476 --- /dev/null +++ b/src/libraries/libmisc/s-string.h @@ -0,0 +1,445 @@ +/* + * s-string.h + * Our own string type. Definition of string type, + * and functions to manipulate these strings. + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + */ + + + +#ifndef S_STRING_H_ALREADY_INCLUDED__ +#define S_STRING_H_ALREADY_INCLUDED__ + + +#include <limits.h> +#include <stdio.h> +#include <stddef.h> + +#include <misc-types.h> + +#include "s-collat-tables.h" + + +typedef long String_size; +#define END_OF_STRING LONG_MAX + + +/* + * All objects of type String *must* be initialized to EMPTY_STRING + * before using any destructive function on them. If you only use + * non-destructive functions (s_strlen(), s_strcmp(), ...), you can + * set them with + * str = s_fcrea_str("Hej hopp i lingonskogen"); + * But the value of this may *not* be used in any destructive call, + * since str.string points to read-only memory. + + * Note also that you need to call s_free() on any auto variables + * of type String before exiting the block they are declared in, + * since otherwise the memory they use will still be allocated. + * This is of course the same rules as for normal pointers. + + * To make it possible for people to use their own storage + * management routines, you can set the functions to use for + * malloc(), realloc() and free() with the + * s_set_storage_management() function. This MUST be called + * before using any of the other functions, even if you want to + * use the normal malloc(), realloc() and free(). + + * Terminology: + * -- A "separate" String is an object that points to some memory + * that is somehow obtained from malloc() or its cousins. This + * means that it is legal to free() or realloc() it. + */ + + +typedef struct { + String_size len; + unsigned char * string; +} String; + +/* + * Note that the first character is String.string[0], and the last + * character is String.string[String.len-1] + */ + + +/* This is the representation of the empty String */ +#define EMPTY_STRING_i ((String) { 0, NULL }) +extern const String EMPTY_STRING; + + + +/* + * Functions to manipulate strings of type 'String'. + * All these functions return a value of type Success, which is + * an enum of OK an FAILURE (do NOT trust the order of these!). + * + * All functions automatically allocates (and deallocates) any + * necessary storage. + */ + + + +typedef void (*free_function) (void *); +typedef void * (*malloc_function) (size_t); +typedef void * (*realloc_function) (void *, size_t); + +/* + * Set the functions to use for storage management. These must + * be call compatible with the normal functions malloc(), + * realloc() and free(). + */ +extern void +s_set_storage_management (malloc_function new_malloc, + realloc_function new_realloc, + free_function new_free); + + +/* + * Returns the number of characters in a String + */ +#define s_strlen(str) ((str).len) + + + +/* + * Create an object of type String from an ordinary C string. + */ +extern Success +s_crea_str (String * dest_string, + const char * c_string ); + + +/* + * Create a string from a buffer. The contents of the buffer + * are copied into the new string. + */ + +extern Success +s_mem_crea_str (String * dest_string, + const char * buffer, + String_size length); + +/* + * Create a string of a given size. The contents of the string + * are unspecified. The LysKOM-server uses this to get a string + * of a fixed size into which it can fread() data. This is probably + * not a good idea since it relies heavily on the implementation + * of strings. However, by using this function, those places are + * easy to identify if the implementation should be done differently. + */ + +extern Success +s_size_crea_str(String *result, + String_size length); + +/* + * Return a temporary String from a C string, i e return a struct + * pointing to the actual C string. Suitable for sending a 'String' + * object as parameter to a function (IF that function does not modify + * it's parameter. Note that normally String variables should be set + * by s_crea_str(), to deallocate the memory used by it. + */ +extern String +s_fcrea_str (const char * c_string); + + + +/* + * Free's the space used by a String object. The object is + * set to EMPTY_STRING. + */ +extern void +s_clear (String * str); + + +/* + * Create an ordinary C string from a String. + * The pointer returned will point to a '\0'-terminated character + * array which is obtained with the malloc-function supplied to + * s_set_storage_management(). It should be freed by the caller. + * NULL is returned if there is an error. The String may contain + * '\0's, but the resulting string will be truncated at the first + * '\n'. Thou shalt not depend on this behaviour. Later versions + * might substitute "foobar" for '\0's. + */ + + +extern char * +s_crea_c_str(const String source); + + + +/* + * Copy SOURCE_STRING to DEST_STRING. Old value of DEST_STRING is + * retained if an error was encountered. Note that it is never + * legal to do 's_strcpy(&foo, foo)', since the string 'foo' is + * pointing to is reallocated before it is read. + */ +extern Success +s_strcpy (String * dest_string, + const String source_string); + + + +/* + * In String STR remove the characters starting with number FIRST + * and ending with number LAST, inclusive. If FIRST > LAST, then + * no characters are removed. + */ +extern Success +s_strdel (String * str, + String_size first, + String_size last ); + + + +/* + * Append SOURCE_STRING to the end of DEST_STRING. DEST_STRING is not + * changed if an error is encountered. + */ +extern Success +s_strcat (String * dest_string, + const String source_string); + + + +/* + * Extract a substring from SOURCE_STRING, starting with char no + * START_CHAR and ending with char no END_CHAR. First character + * is character no 0. If END_CHAR < START_CHAR, then DEST_STRING + * is set to 'EMPTY_STRING'. If END_CHAR is equal to the macro + * 'END_OF_STRING', then the substring reaches to the last character + * in SOURCE_STRING. + */ +extern Success +s_substr (String * dest_string, + const String source_string, + String_size start_char, + String_size end_char); + + + +/* + * Fast extraction of a substring. Returns an object of type + * String wich points into SOURCE_STRING. Thus you should NEVER + * modify the result of this function. (Raw character modifying + * is OK if you know what you are doing, but never use anything + * that might call free or realloc on it.) If END_CHAR is equal + * to the macro 'END_OF_STRING', then the substring reaches to + * the last character in SOURCE_STRING. + */ +extern String +s_fsubstr (const String source_string, + String_size start_char, + String_size end_char ); + + + +/* Check if a string is the empty string. Returns TRUE or FALSE. + */ +#define s_empty(str) (((str).len == 0) ? TRUE : FALSE) + + +/* Check if two strings are equal. + */ +#define s_streq(str1, str2) (s_strcmp(str1, str2) == 0) +#define s_usr_streq(str1, str2, collat_tab) \ + (s_usr_strcmp(str1, str2, collat_tab) == 0) + + + +/* + * Compares two strings. Returns -1 if STR1 is lexically less + * than STR2, +1 if STR1 is greater than STR2, and 0 if they are + * equal. + */ +extern int +s_strcmp (String str1, + String str2); + + + +/* + * Compares two strings with user specified collation order. + * Returns the same values as s_strcmp(). + * COLLAT_TAB is a table of collating values for every char. + */ +extern int +s_usr_strcmp (String str1, + String str2, + char collat_tab [ COLLAT_TAB_SIZE ]); + + + +/* + * Checks if STR1 is the exact beginning of STR2, e g if STR1 + * is "foobar" and STR2 is "foobarf" then the result is TRUE. + */ +extern Bool +s_strhead (String str1, + String str2); + + + +/* + * Checks if STR1 is the exact beginning of STR2, but uses a + * user specified collating sequence for comparison (as in + * s_usr_strcmp()). + */ +extern Bool +s_usr_strhead (String str1, + String str2, + char collat_tab [ COLLAT_TAB_SIZE ]); + + + +/* + * From STR strip all trailing characters that can be found + * in STRIP_STRING. STR isn't altered in any way. The returned + * object points to the same string as STR, but with a possibly + * shorter length. The pointer is unchanged *even* if the length + * should be 0, which means you don't "lose" the storage but can + * free it with s_free(). + */ +extern String +s_strip_trailing (String str, + const String strip_string); + + + +/* + * Returns the index of the first occurrence in the String STR + * of the character CH. Returns -1 if no occurrence. + */ +extern String_size +s_strchr (const String str, + char ch, + String_size start_pos); + + + +/* + * Returns the index of the last occurrence in the String STR + * of the character CH. Returns -1 if no occurrence. + */ +extern String_size +s_strrchr (const String str, + char ch, + String_size start_pos); + + + +/* + * Return the index of the first occurrence in the String LOOK_IN + * of any of the characters in the String SEARCH_FOR, or -1 if none. + */ +extern String_size +s_strpbrk (const String look_in, + const String search_for); + + + +/* + * Find the first character in LOOK_IN that *is* present in + * SEARCH_FOR, and return its index, or the length of LOOK_IN if + * it contains only characters that are not present in SEARCH_FOR. + */ +extern String_size +s_strcspn (const String look_in, + const String search_for); + + + +/* + * Find the first character in LOOK_IN that is *not* present in + * SKLIP_CHARS, and return its index, or the length of LOOK_IN if + * it contains only characters that are present in SKIP_CHARS. + */ +extern String_size +s_strspn (const String look_in, + const String skip_chars); + + + +/* + * Pick out the first token from SOURCE separated by one or more + * of the characters in SEPARATORS, starting in position START_POS. + * + * More specifically: start in position START_POS and skip over + * separator characters (any of those present in SEPARATORS). + * Extract the substring starting with the first non-separator, + * and ending the character immediately before the first separator + * following. *start_pos will be the index of the first separator + * character after the token. + * + * Note that the return value actually points into SOURCE. It + * is not separately allocated. + */ +extern String +s_strtok (const String source, + String_size * start_pos, + const String separators); + + + + +/**************************************************** + * Misc. routines using our String type. * + ****************************************************/ + + +/* + * Convert the String STR to a long, using the base BASE. + * Leading blanks are skipped according to isblank() in <ctype.h>. + * The index of the first character that couldn't be used to form + * the number is returned in *FIRST_ILL_CHAR. Returns -1 in + * *first_ill_char if there was an error in the parameters. + * BASE may be in the range 2..36 + */ +extern long +s_strtol (const String str, + String_size * first_ill_char, + const int base ); + + + + +/************************************************ + * Input/Output routines for String * + ************************************************/ + + + +/* + * Outputs the string STR on the stream STREAM. No information + * about the length of the string is output. + */ +extern Success +s_fputs (FILE * stream, + const String str); + + + +/* + * Outputs the string STR on stdout. No information + * about the length of the string is output. + */ +#define s_puts(str) s_fputs(stdout, str) + + +#endif /* _S_STRING_H_ALREADY_INCLUDED__ */ diff --git a/src/libraries/libmisc/zmalloc.c b/src/libraries/libmisc/zmalloc.c new file mode 100644 index 0000000000000000000000000000000000000000..80a20070789245120d7da8acd95c6dc768a110f7 --- /dev/null +++ b/src/libraries/libmisc/zmalloc.c @@ -0,0 +1,171 @@ +/* + * zmalloc.c + * + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + * + * + * Any opinions expressed in this code are the author's PERSONAL opinions, + * and does NOT, repeat NOT, represent any official standpoint of Lysator, + * even if so stated. + */ + + + +#include <stddef.h> +#include <malloc.h> +#include <string.h> + +#include <compiler.h> + +#include "zmalloc.h" + + +#define EXPORT + + +typedef struct { + int refcount; + size_t size; +} z_info; + + + +#define REFCOUNT(pointer) \ + (((z_info *) ((char *) pointer - sizeof (z_info)))->refcount) + +#define AREA_SIZE(pointer) \ + (((z_info *) ((char *) pointer - sizeof (z_info)))->size) + + +#define MIN(n1, n2) (((n1) < (n2)) ? (n1) : (n2)) + + + +EXPORT void * +zmalloc (size_t size) +{ + void * memory; + + memory = malloc (size + sizeof (z_info)); + if (memory == NULL) + return NULL; + ((z_info *) memory)->size = size; + ((z_info *) memory)->refcount = 1; + return (char *) memory + sizeof (z_info); +} + + + +EXPORT void * +zcalloc (size_t n, + size_t size) + +{ + void * memory; + + memory = malloc (n * size + sizeof (z_info)); + if (memory == NULL) + return NULL; + ((z_info *) memory)->size = n * size; + ((z_info *) memory)->refcount = 1; + memset ((char *) memory + sizeof (z_info), + 0, n * size); + + return (char *) memory + sizeof (z_info); +} + + + +EXPORT void * +zrealloc (void * ptr, + size_t size) + +{ + void * memory; + + if (ptr == NULL) + return zmalloc (size); + if (REFCOUNT (ptr) > 1) + { + memory = zmalloc (size); + if (memory == NULL) + return NULL; + memcpy (memory, ptr, MIN (size, AREA_SIZE (ptr))); + --REFCOUNT (ptr); + return memory; + } + else + { + memory = realloc ((char *) ptr - sizeof (z_info), + size + sizeof (z_info)); + return (char *) memory + sizeof (z_info); + } +} + + + +EXPORT void +zfree (void * ptr) +{ + if (ptr != NULL && --REFCOUNT (ptr) <= 0) + { + free ((char *) ptr - sizeof (z_info)); + } +} + + + +EXPORT void +zdestruct (void * ptr) +{ + if (ptr != NULL) + free ((char *) ptr - sizeof (z_info)); +} + + + +EXPORT void * +zuse (void * ptr) +{ + if (ptr != NULL) + { + ++REFCOUNT (ptr); + } + return ptr; +} + + + +EXPORT void * +zown (void * ptr) +{ + void * memory; + + if (ptr == NULL) + return NULL; + if (REFCOUNT (ptr) == 1) + return ptr; + else + { + if ((memory = malloc (AREA_SIZE (ptr))) == NULL) + return NULL; + memcpy (memory, ptr, AREA_SIZE (ptr)); + zfree (ptr); + + return memory; + } +} diff --git a/src/libraries/libmisc/zmalloc.h b/src/libraries/libmisc/zmalloc.h new file mode 100644 index 0000000000000000000000000000000000000000..a11a8c256b6959ea832492097e8cd41d9425f52f --- /dev/null +++ b/src/libraries/libmisc/zmalloc.h @@ -0,0 +1,116 @@ +/* + * zmalloc.h -- Memory allocation routines with reference counts + * + * + * Copyright (C) 1990 Lysator Computer Club, + * Linkoping University, Sweden + * + * Everyone is granted permission to copy, modify and redistribute + * this code, provided the people they give it to can. + * + * + * Author: Thomas Bellman + * Lysator Computer Club + * Linkoping University + * Sweden + * + * email: Bellman@Lysator.LiU.SE + */ + + +#ifndef _ZMALLOC_H_INCLUDED__ +#define _ZMALLOC_H_INCLUDED__ + + +/* Declare 'size_t' */ +#include <stddef.h> + +#include <compiler.h> + + + +/* + * Allocate a piece of memory and set its reference count to 1. + * Allocating a zero sized object is allowed, and results in a + * unique pointer that can be used by all the other routines in + * this package, and must be released using zfree(), but it + * points to "nothing". + */ +extern void * +zmalloc (size_t size); + + +/* + * Allocate N contigous objects of size SIZE, set the contents + * to binary 0 and set the reference count to 1. Allocating 0 + * objecs, or objects of size zero, is allowed, and results in a + * unique pointer that can be used by all the other routines in + * this package, and must be released using zfree(), but it + * points to "nothing". + */ +extern void * +zcalloc (size_t n, + size_t size); + + +/* + + * Reallocate the storage PTR points to the size SIZE. If + * "others" are still holding references to this memory, they + * can still use it, and the caller of zrealloc() gets a copy of + * the original memory area. NULL is returned if the request + * couldn't be honored, and the memory area is still in use by + * the caller. Reallocating the NULL pointer is equivalent to + * doing a zmalloc() with the same size. The same rules for + * allocating objects of size 0 as for zmalloc() and zcalloc() + * applies. + + */ +extern void * +zrealloc (void * ptr, + size_t size); + + +/* + * Indicate that the memory pointed to by PTR is not used anymore + * by the caller, i e the reference count is decremented by one. + * The memory pointed to might be released as a result of this + * call. Freeing the NULL pointer is a no-op. + */ +extern void +zfree (void * ptr); + + + +/* + * Free the area pointed to by PTR regardless of how many are + * referencing it. This invalidiates all pointers to the area. + * Calling zdestruct() on a NULL pointer is a no-op. + */ +extern void +zdestruct (void * ptr); + + + +/* + * Add onother user of the memory pointed to by PTR, i e increase + * the reference count by one. Return value is PTR. Using the + * NULL pointer is a no-op, i e it just returns NULL. + */ +extern void * +zuse (void * ptr); + + + +/* + * Get a private copy of the area pointed to by PTR. If + * necessary, i e if others are holding references to the area, + * copies the contents to a new place, and releases the original + * area. If you want to keep a reference to the old area, you + * should do 'zown(zuse(p))'. + */ +extern void * +zown (void * ptr); + + +#endif /* _ZMALLOC_H_INCLUDED__ */