1 /*** symbols.h ****************************************************************
2 **
3 ** This file is part of BibTool.
4 ** It is distributed under the GNU General Public License.
5 ** See the file COPYING for details.
6 **
7 ** (c) 1996-2020 Gerd Neugebauer
8 **
9 ** Net: gene@gerd-neugebauer.de
10 **
11 ** This program is free software; you can redistribute it and/or modify
12 ** it under the terms of the GNU General Public License as published by
13 ** the Free Software Foundation; either version 2, or (at your option)
14 ** any later version.
15 **
16 ** This program is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ** GNU General Public License for more details.
20 **
21 ** You should have received a copy of the GNU General Public License
22 ** along with this program; if not, write to the Free Software
23 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 **
25 **-----------------------------------------------------------------------------
26 ** Description:
27 **	This header file contains definitions dealing with symbols.
28 **
29 **	\BibTool{} uses symbols as the basic representation for
30 **	strings.  Symbols are stored in a symbol table and shared
31 **	among different instances. Thus the same string occurring at
32 **	different places has to be stored only once.
33 **
34 **	Another advantage of symbols is that once you have got two
35 **	symbols at hand it is rather easy to compare them for
36 **	equality.  A simple pointer comparison is enough. It is not
37 **	necessary to compare them character by character.
38 **
39 **	The disadvantage of a symbol is that you can not simply modify
40 **	it temporarily since it is part of the symbol table. This
41 **	symbol table would be in an insane state otherwise. Thus you
42 **	always have to make a copy if you want to modify a symbol.
43 **
44 **	The functions defined in |symbols.c| are exported with this
45 **	header file as well.
46 **
47 ******************************************************************************/
48 
49 #ifndef SYMBOLS_H_LOADED
50 #define SYMBOLS_H_LOADED
51 
52 #include <bibtool/type.h>
53 
54 /*-----------------------------------------------------------------------------
55 ** Macro:	UnlinkSymbol()
56 ** Type:	void
57 ** Purpose:	The symbol given as argument is released. In fact the
58 **		memory is not really freed but one instance is marked
59 **		as not used any more. At other places the symbol might
60 **		be still required. The freeing of memory is performed
61 **		by the garbage collector |sym_gc()|.
62 ** Arguments:
63 **	SYM	Symbol to release.
64 ** Returns:	nothing
65 **___________________________________________________			     */
66 #ifdef FREE_MEMORY
67 #define UnlinkSymbol(SYM) if (--SymbolCount(SYM) == 0) sym_del(SYM)
68 #else
69 #ifdef COMPLEX_SYMBOL
70 #define UnlinkSymbol(SYM) --SymbolCount(SYM)
71 #else
72 #define UnlinkSymbol(SYM)
73 #endif
74 #endif
75 
76 /*****************************************************************************/
77 /***									   ***/
78 /*****************************************************************************/
79 
80 #ifdef COMPLEX_SYMBOL
81 
82 typedef struct
83  { String sy_value;
84    int sy_count;
85  } sSymbol, *Symbol;
86 #define SymbolValue(X) ((X)->sy_value)
87 #define SymbolCount(X) ((X)->sy_count)
88 
89 #define LinkSymbol(SYM) SymbolCount(SYM)++
90 
91 #else
92 
93 typedef String Symbol;
94 #define SymbolValue(X) (X)
95 #define LinkSymbol(SYM)
96 
97 #endif
98 
99 #define SetSym(VAR,SYM)			\
100   if (VAR) { UnlinkSymbol(VAR); }	\
101   VAR = SYM;				\
102   if (VAR) { LinkSymbol(VAR); }
103 
104 #define symlen(SYM) strlen((char*)SymbolValue(SYM))
105 #define symcmp(S,T) strcmp((char*)SymbolValue(S),(char*)SymbolValue(T))
106 
107 /*-----------------------------------------------------------------------------
108 ** Constant:	NO_SYMBOL
109 ** Type:	Symbol
110 ** Purpose:	The NULL pointer for Symbols
111 **___________________________________________________			     */
112 #define NO_SYMBOL (Symbol)NULL
113 
114 /*-----------------------------------------------------------------------------
115 ** Variable:	s_empty
116 ** Type:	String
117 ** Purpose:	Unmodifiable value containing the empty string. This
118 **		variable needs |init_symbols()| to be called first.
119 **___________________________________________________			     */
120  extern String s_empty;
121 
122 /*-----------------------------------------------------------------------------
123 ** Variable:	sym_empty
124 ** Type:	Symbol
125 ** Purpose:	The empty symbol. This is a symbol pointing
126 **		immediately to a |\0| byte.  This needs
127 **		|init_symbols()| to be called first.
128 **___________________________________________________			     */
129  extern Symbol sym_empty;
130 
131 /*-----------------------------------------------------------------------------
132 ** Variable:	sym_crossref
133 ** Type:	Symbol
134 ** Purpose:	The symbol |crossref|. This variable needs
135 **		|init_symbols()| to be called first.
136 **___________________________________________________			     */
137  extern Symbol sym_crossref;
138 
139 /*-----------------------------------------------------------------------------
140 ** Variable:	sym_xref
141 ** Type:	Symbol
142 ** Purpose:	The symbol |xref|. This variable needs
143 **		|init_symbols()| to be called first.
144 **___________________________________________________			     */
145  extern Symbol sym_xref;
146 
147 /*-----------------------------------------------------------------------------
148 ** Variable:	sym_xdata
149 ** Type:	Symbol
150 ** Purpose:	The symbol |xdata|. This variable needs
151 **		|init_symbols()| to be called first.
152 **___________________________________________________			     */
153  extern Symbol sym_xdata;
154 
155 /*-----------------------------------------------------------------------------
156 ** Variable:	sym_space
157 ** Type:	Symbol
158 ** Purpose:	The symbol with a single space character. This variable needs
159 **		|init_symbols()| to be called first.
160 **___________________________________________________			     */
161  extern Symbol sym_space;
162 
163 /*-----------------------------------------------------------------------------
164 ** Variable:	sym_star
165 ** Type:	Symbol
166 ** Purpose:	The symbol with a single star character. This variable needs
167 **		|init_symbols()| to be called first.
168 **___________________________________________________			     */
169  extern Symbol sym_star;
170 
171  extern Symbol sym_qqq;
172 
173 /*-----------------------------------------------------------------------------
174 ** Variable:	sym_comma
175 ** Type:	Symbol
176 ** Purpose:	The symbol with a single comma character. This variable needs
177 **		|init_symbols()| to be called first.
178 **___________________________________________________			     */
179  extern Symbol sym_comma;
180 
181 /*-----------------------------------------------------------------------------
182 ** Variable:	sym_double_quote
183 ** Type:	Symbol
184 ** Purpose:	The symbol with a single double quote character (").
185 **		This variable needs |init_symbols()| to be called first.
186 **___________________________________________________			     */
187  extern Symbol sym_double_quote;
188 
189 /*-----------------------------------------------------------------------------
190 ** Variable:	sym_open_brace
191 ** Type:	Symbol
192 ** Purpose:	The symbol with a single open brace character. This
193 **		variable needs |init_symbols()| to be called first.
194 **___________________________________________________			     */
195  extern Symbol sym_open_brace;
196 
197 /*-----------------------------------------------------------------------------
198 ** Variable:	sym_close_brace
199 ** Type:	Symbol
200 ** Purpose:	The symbol with a single close brace character. This
201 **		variable needs |init_symbols()| to be called first.
202 **___________________________________________________			     */
203  extern Symbol sym_close_brace;
204 
205 /*-----------------------------------------------------------------------------
206 ** Variable:	sym_et
207 ** Type:	Symbol
208 ** Purpose:	The symbol with a single et character (\&). This
209 **		variable needs |init_symbols()| to be called first.
210 **___________________________________________________			     */
211  extern Symbol sym_et;
212 
213  extern Symbol sym_key;
214 
215  extern Symbol sym_sortkey;
216 
217 /*-----------------------------------------------------------------------------
218 ** Macro:	newString()
219 ** Type:	String
220 ** Purpose:	Create a copy of a given String.
221 ** Arguments:
222 **	S	the source of the bytes
223 ** Returns:	a newly allocated byte array containing the content of
224 **		the source
225 **___________________________________________________			     */
226 #define newString(S) (String)new_string((char*)(S))
227 
228 #ifdef __STDC__
229 #define _ARG(A) A
230 #else
231 #define _ARG(A) ()
232 #endif
233  Symbol  symbol _ARG((String s));	   	   /* symbols.c              */
234  Symbol  sym_extract _ARG((String *sp,bool lowercase));/* symbols.c          */
235  char * new_string _ARG((char * s));		   /* symbols.c              */
236  void init_symbols _ARG((void));		   /* symbols.c              */
237  void sym_dump _ARG((void));			   /* symbols.c              */
238  void sym_del _ARG((Symbol sym));		   /* symbols.c              */
239  void sym_gc _ARG((void));			   /* symbols.c              */
240  void sym_unlink _ARG((Symbol s));		   /* symbols.c              */
241  void free_sym_array _ARG((Symbol *sym_arr));	   /*                        */
242 
243 #endif /* SYMBOLS_H_LOADED */
244