1/*
2 * Copyright 1993, 1995 Christopher Seiwald.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7/*
8 * newstr.c - string manipulation routines
9 *
10 * To minimize string copying, string creation, copying, and freeing
11 * is done through newstr.
12 *
13 * External functions:
14 *
15 *    newstr() - return a malloc'ed copy of a string
16 *    copystr() - return a copy of a string previously returned by newstr()
17 *    freestr() - free a string returned by newstr() or copystr()
18 *    donestr() - free string tables
19 *
20 * Once a string is passed to newstr(), the returned string is readonly.
21 *
22 * This implementation builds a hash table of all strings, so that multiple
23 * calls of newstr() on the same string allocate memory for the string once.
24 * Strings are never actually freed.
25 *
26 * 11/04/02 (seiwald) - const-ing for string literals
27 */
28
29# include "jam.h"
30# include "newstr.h"
31# include "hash.h"
32
33typedef const char *STRING;
34
35static struct hash *strhash = 0;
36static int strtotal = 0;
37
38/*
39 * newstr() - return a malloc'ed copy of a string
40 */
41
42const char *
43newstr( const char *string )
44{
45	STRING str, *s = &str;
46
47	if( !strhash )
48	    strhash = hashinit( sizeof( STRING ), "strings" );
49
50	*s = string;
51
52	if( hashenter( strhash, (HASHDATA **)&s ) )
53	{
54	    int l = strlen( string );
55	    char *m = (char *)malloc( l + 1 );
56
57	    if (DEBUG_MEM)
58		    printf("newstr: allocating %d bytes\n", l + 1 );
59
60	    strtotal += l + 1;
61	    memcpy( m, string, l + 1 );
62	    *s = m;
63	}
64
65	return *s;
66}
67
68/*
69 * copystr() - return a copy of a string previously returned by newstr()
70 */
71
72const char *
73copystr( const char *s )
74{
75	return s;
76}
77
78/*
79 * freestr() - free a string returned by newstr() or copystr()
80 */
81
82void
83freestr( const char *s )
84{
85}
86
87/*
88 * donestr() - free string tables
89 */
90
91void
92donestr()
93{
94	hashdone( strhash );
95
96	if( DEBUG_MEM )
97	    printf( "%dK in strings\n", strtotal / 1024 );
98}
99