File: identifier.c

package info (click to toggle)
faucc 20160511-1
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 1,460 kB
  • ctags: 2,914
  • sloc: ansic: 38,788; yacc: 1,602; xml: 519; sh: 436; lex: 378; makefile: 125
file content (123 lines) | stat: -rw-r--r-- 2,070 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
118
119
120
121
122
123
/* $Id: identifier.c,v 1.12 2009/01/27 15:40:22 potyra Exp $ 
 *
 * Copyright (C) 2007-2009 FAUcc Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "identifier.h"

struct identifier {
	struct identifier *prev;
	struct identifier *next;

	const char *string;
};

static struct identifier *hash_first[IDENTIFIER_HASH_SIZE];
static struct identifier *hash_last[IDENTIFIER_HASH_SIZE];


unsigned int
identifier_hash(const char *_n)
{
	const unsigned char *n = (const unsigned char *) _n;
	unsigned int sum;

	while (*n == '_') {
		n++;
	}

	sum = 0;
	while (*n) {
		if ('0' <= *n && *n <= '9') {
			sum *= 10;
			sum += *n - '0';
		} else {
			sum <<= 5;
			sum += *n & 0x1f;
		}
		n++;
	}
	sum %= IDENTIFIER_HASH_SIZE;

	return sum;
}

const char *
identifier_new(const char *n)
{
	struct identifier *id;
	unsigned int hash;

	hash = identifier_hash(n);

	for (id = hash_first[hash]; ; id = id->next) {
		if (! id) {
			/* New entry. */
			id = malloc(sizeof(*id));
			assert(id);

			id->string = strdup(n);
			assert(id->string);

			id->prev = hash_last[hash];
			id->next = NULL;
			if (id->prev) {
				id->prev->next = id;
			} else {
				hash_first[hash] = id;
			}
			hash_last[hash] = id;
			break;
		}
		if (strcmp(n, id->string) == 0) {
			/* Entry found. */
			break;
		}
	}

	return id->string;
}

const char *
identifier_tmp(void)
{
	static unsigned int count = 0;
	char name[20];

	sprintf(name, "__%u", count++);

	return identifier_new(name);
}

int
identifier_is_tmp(const char *name)
{
	unsigned int i;

	if (name[0] != '_') return 0;
	if (name[1] != '_') return 0;
	for (i = 2; name[i]; i++) {
		if (! isdigit(name[i])) return 0;
	}
	return 1;
}

const char *
identifier_dup(const char *n)
{
	return n;
}

void
identifier_free(const char *n)
{
}