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)
{
}
|