File: defstr.c

package info (click to toggle)
yorick 1.4-14
  • links: PTS
  • area: main
  • in suites: potato
  • size: 5,948 kB
  • ctags: 6,609
  • sloc: ansic: 63,898; yacc: 889; makefile: 605; sh: 65; lisp: 60; fortran: 19
file content (117 lines) | stat: -rw-r--r-- 2,890 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
    DEFSTR.C
    Define functions for string manipulation.

    $Id: defstr.c,v 1.1 1993/08/27 18:32:09 munro Exp $

    Implement StrCpy, StrCat, StrAlloc, StrFree functions using 8 block
    allocators.  This should greatly speed up memory allocate/free
    for short to medium length strings.  The gotcha is that after
    once a string is allocated using StrCpy or StrAlloc, StrFree only
    returns its space for use by other StrCpy or StrAlloc strings,
    NOT to the general memory pool.
 */
/*    Copyright (c) 1994.  The Regents of the University of California.
                    All rights reserved.  */

#include "defstr.h"
#include "defmem.h"

#define N_STRING_BLOCKS 12
extern MemoryBlock y_StringBlocks[N_STRING_BLOCKS];
MemoryBlock y_StringBlocks[N_STRING_BLOCKS]= {
  {0, 0,  2*sizeof(void *), 128* 2*sizeof(void *)},
  {0, 0,  4*sizeof(void *), 64*  4*sizeof(void *)},
  {0, 0,  6*sizeof(void *), 42*  6*sizeof(void *)},
  {0, 0,  8*sizeof(void *), 32*  8*sizeof(void *)},
  {0, 0, 10*sizeof(void *), 25* 10*sizeof(void *)},
  {0, 0, 12*sizeof(void *), 20* 12*sizeof(void *)},
  {0, 0, 14*sizeof(void *), 18* 14*sizeof(void *)},
  {0, 0, 16*sizeof(void *), 16* 16*sizeof(void *)},
  {0, 0, 18*sizeof(void *), 14* 18*sizeof(void *)},
  {0, 0, 20*sizeof(void *), 12* 20*sizeof(void *)},
  {0, 0, 22*sizeof(void *), 10* 22*sizeof(void *)},
  {0, 0, 24*sizeof(void *), 10* 24*sizeof(void *)}
};

char *StrCpy(const char *s)
{
  if (s) {
    char *t= StrAlloc(strlen(s));
    return strcpy(t, s);
  } else {
    return 0;
  }
}

char *StrNCpy(const char *s, long n)
{
  if (s && n>=0) {
    char *t= StrAlloc(n);
    strncpy(t, s, n);
    t[n]= '\0';
    return t;
  } else {
    return 0;
  }
}

char *StrCat(const char *s, const char *t)
{
  if (s) {
    if (t) {
      long ls= strlen(s);
      char *u= StrAlloc(ls+strlen(t));
      strcpy(u, s);
      return strcat(u, t);
    } else {
      return StrCpy(s);
    }
  } else {
    return StrCpy(t);
  }
}

char *StrNCat(const char *s, const char *t, long n)
{
  if (t && n>=0) {
    char *u;
    if (s) {
      u= StrAlloc(strlen(s)+n);
      strcpy(u, s);
    } else {
      u= StrAlloc(n);
    }
    return strncat(u, t, n);
  } else {
    return StrCpy(s);
  }
}

char *StrAlloc(long n)
{
  char *t, tag;
  n+= 1;  /* block marker + trailing \0 minus 1 */
  if (n >= N_STRING_BLOCKS*2*sizeof(void *)) {
    t= (char *)Ymalloc(n+1);
    tag= N_STRING_BLOCKS;
  } else {
    /* All machines I know use 4 or 8 byte void*, so shoot me... */
    if (sizeof(void *) == 4) tag= n>>3;
    else if (sizeof(void *) == 8) tag= n>>4;
    else tag= n%(2*sizeof(void *));
    t= NextUnit(&y_StringBlocks[(int)tag]);
  }
  *t++= tag;
  *t= '\0';
  return t;
}

void StrFree(char *s)
{
  if (s) {
    unsigned char *t= (unsigned char *)s-1;
    if (*t >= N_STRING_BLOCKS) Yfree(t);
    else FreeUnit(&y_StringBlocks[*t], t);
  }
}