blob: d8d7e93ad1821043c4ad1222ad67e3dc8b14e1bd [file] [log] [blame]
Shinichiro Hamajie7992752015-06-29 18:38:35 +09001// Copyright 2015 Google Inc. All rights reserved
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// +build ignore
16
17#include "symtab.h"
18
19#include <string.h>
20
21#include <unordered_map>
22
23#include "log.h"
24#include "strutil.h"
25
Shinichiro Hamajiba2ccdb2015-07-17 05:55:42 +090026vector<string*>* g_symbols;
Shinichiro Hamajie7992752015-06-29 18:38:35 +090027
Shinichiro Hamaji43defe02015-07-11 07:06:43 +090028Symbol kEmptySym = Symbol(Symbol::IsUninitialized());
Shinichiro Hamaji94d6f2a2015-07-05 05:32:25 +090029Symbol kShellSym = Symbol(Symbol::IsUninitialized());
30
Shinichiro Hamajie7992752015-06-29 18:38:35 +090031Symbol::Symbol(int v)
32 : v_(v) {
33}
34
35class Symtab {
36 public:
37 Symtab() {
38 CHECK(g_symbols == NULL);
39 g_symbols = &symbols_;
Shinichiro Hamaji82aeb272015-06-30 02:24:36 +090040
41 Symbol s = InternImpl("");
Shinichiro Hamajie7992752015-06-29 18:38:35 +090042 CHECK(s.v_ == 0);
43 CHECK(Intern("") == s);
Shinichiro Hamaji82aeb272015-06-30 02:24:36 +090044 char b[2];
45 b[1] = 0;
46 for (int i = 1; i < 256; i++) {
47 b[0] = i;
48 s = InternImpl(b);
49 CHECK(s.val() == i);
50 }
Shinichiro Hamaji94d6f2a2015-07-05 05:32:25 +090051
Shinichiro Hamaji43defe02015-07-11 07:06:43 +090052 kEmptySym = Intern("");
Shinichiro Hamaji94d6f2a2015-07-05 05:32:25 +090053 kShellSym = Intern("SHELL");
Shinichiro Hamajie7992752015-06-29 18:38:35 +090054 }
55
Shinichiro Hamajiba2ccdb2015-07-17 05:55:42 +090056 ~Symtab() {
Shinichiro Hamaji9f127b22015-10-28 18:08:47 +090057 LOG_STAT("%zu symbols", symbols_.size());
Shinichiro Hamajiba2ccdb2015-07-17 05:55:42 +090058 for (string* s : symbols_)
59 delete s;
60 }
61
Shinichiro Hamaji82aeb272015-06-30 02:24:36 +090062 Symbol InternImpl(StringPiece s) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +090063 auto found = symtab_.find(s);
64 if (found != symtab_.end()) {
65 return found->second;
66 }
Shinichiro Hamajiba2ccdb2015-07-17 05:55:42 +090067 symbols_.push_back(new string(s.data(), s.size()));
Shinichiro Hamajie7992752015-06-29 18:38:35 +090068 Symbol sym = Symbol(symtab_.size());
Shinichiro Hamajiba2ccdb2015-07-17 05:55:42 +090069 bool ok = symtab_.emplace(*symbols_.back(), sym).second;
Shinichiro Hamajie7992752015-06-29 18:38:35 +090070 CHECK(ok);
71 return sym;
72 }
73
Shinichiro Hamaji82aeb272015-06-30 02:24:36 +090074 Symbol Intern(StringPiece s) {
75 if (s.size() <= 1) {
76 return Symbol(s.empty() ? 0 : (unsigned char)s[0]);
77 }
78 return InternImpl(s);
79 }
80
Shinichiro Hamajie7992752015-06-29 18:38:35 +090081 private:
82 unordered_map<StringPiece, Symbol> symtab_;
Shinichiro Hamajiba2ccdb2015-07-17 05:55:42 +090083 vector<string*> symbols_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +090084};
85
86static Symtab* g_symtab;
87
88void InitSymtab() {
89 g_symtab = new Symtab;
90}
91
92void QuitSymtab() {
93 delete g_symtab;
94}
95
96Symbol Intern(StringPiece s) {
97 return g_symtab->Intern(s);
98}
99
100string JoinSymbols(const vector<Symbol>& syms, const char* sep) {
101 vector<string> strs;
102 for (Symbol s : syms) {
103 strs.push_back(s.str());
104 }
105 return JoinStrings(strs, sep);
106}