xref: /illumos-gate/usr/src/tools/smatch/src/macro_table.c (revision c85f09cc92abd00c84e58ec9f0f5d942906cb713)
11f5207b7SJohn Levon /*
21f5207b7SJohn Levon  * sparse/macro_table.c
31f5207b7SJohn Levon  *
41f5207b7SJohn Levon  * Copyright (C) 2010 Dan Carpenter.
51f5207b7SJohn Levon  *
61f5207b7SJohn Levon  * Permission is hereby granted, free of charge, to any person obtaining a copy
71f5207b7SJohn Levon  * of this software and associated documentation files (the "Software"), to deal
81f5207b7SJohn Levon  * in the Software without restriction, including without limitation the rights
91f5207b7SJohn Levon  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
101f5207b7SJohn Levon  * copies of the Software, and to permit persons to whom the Software is
111f5207b7SJohn Levon  * furnished to do so, subject to the following conditions:
121f5207b7SJohn Levon  *
131f5207b7SJohn Levon  * The above copyright notice and this permission notice shall be included in
141f5207b7SJohn Levon  * all copies or substantial portions of the Software.
151f5207b7SJohn Levon  *
161f5207b7SJohn Levon  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
171f5207b7SJohn Levon  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
181f5207b7SJohn Levon  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
191f5207b7SJohn Levon  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
201f5207b7SJohn Levon  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
211f5207b7SJohn Levon  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
221f5207b7SJohn Levon  * THE SOFTWARE.
231f5207b7SJohn Levon  */
241f5207b7SJohn Levon 
251f5207b7SJohn Levon #include <stdlib.h>
261f5207b7SJohn Levon #include <stdio.h>
271f5207b7SJohn Levon #include <string.h>
281f5207b7SJohn Levon #include "lib.h"
291f5207b7SJohn Levon #include "parse.h"
301f5207b7SJohn Levon #include "cwchash/hashtable.h"
311f5207b7SJohn Levon 
321f5207b7SJohn Levon static struct hashtable *macro_table;
331f5207b7SJohn Levon 
34*c85f09ccSJohn Levon static DEFINE_HASHTABLE_INSERT(do_insert_macro, struct position, struct string_list);
35*c85f09ccSJohn Levon static DEFINE_HASHTABLE_SEARCH(do_search_macro, struct position, struct string_list);
361f5207b7SJohn Levon 
371f5207b7SJohn Levon static inline unsigned int position_hash(void *_pos)
381f5207b7SJohn Levon {
391f5207b7SJohn Levon 	struct position *pos = _pos;
401f5207b7SJohn Levon 
41*c85f09ccSJohn Levon 	return pos->line | (pos->pos << 22) | (pos->stream << 18);
421f5207b7SJohn Levon }
431f5207b7SJohn Levon 
441f5207b7SJohn Levon static inline int equalkeys(void *_pos1, void *_pos2)
451f5207b7SJohn Levon {
461f5207b7SJohn Levon 	struct position *pos1 = _pos1;
471f5207b7SJohn Levon 	struct position *pos2 = _pos2;
481f5207b7SJohn Levon 
491f5207b7SJohn Levon 	return pos1->line == pos2->line && pos1->pos == pos2->pos &&
501f5207b7SJohn Levon 		pos1->stream == pos2->stream;
511f5207b7SJohn Levon }
521f5207b7SJohn Levon 
53*c85f09ccSJohn Levon static void insert_macro_string(struct string_list **str_list, char *new)
54*c85f09ccSJohn Levon {
55*c85f09ccSJohn Levon 	add_ptr_list(str_list, new);
56*c85f09ccSJohn Levon }
57*c85f09ccSJohn Levon 
581f5207b7SJohn Levon void store_macro_pos(struct token *token)
591f5207b7SJohn Levon {
60*c85f09ccSJohn Levon 	struct string_list *list;
61*c85f09ccSJohn Levon 
621f5207b7SJohn Levon 	if (!macro_table)
631f5207b7SJohn Levon 		macro_table = create_hashtable(5000, position_hash, equalkeys);
641f5207b7SJohn Levon 
65*c85f09ccSJohn Levon 	list = do_search_macro(macro_table, &token->pos);
66*c85f09ccSJohn Levon 	insert_macro_string(&list, token->ident->name);
671f5207b7SJohn Levon 
68*c85f09ccSJohn Levon 	do_insert_macro(macro_table, &token->pos, list);
691f5207b7SJohn Levon }
701f5207b7SJohn Levon 
711f5207b7SJohn Levon char *get_macro_name(struct position pos)
721f5207b7SJohn Levon {
73*c85f09ccSJohn Levon 	struct string_list *list;
74*c85f09ccSJohn Levon 
75*c85f09ccSJohn Levon 	if (!macro_table)
76*c85f09ccSJohn Levon 		return NULL;
77*c85f09ccSJohn Levon 	list = do_search_macro(macro_table, &pos);
78*c85f09ccSJohn Levon 	return first_ptr_list((struct ptr_list *)list);
79*c85f09ccSJohn Levon }
80*c85f09ccSJohn Levon 
81*c85f09ccSJohn Levon char *get_inner_macro(struct position pos)
82*c85f09ccSJohn Levon {
83*c85f09ccSJohn Levon 	struct string_list *list;
84*c85f09ccSJohn Levon 
85*c85f09ccSJohn Levon 	if (!macro_table)
86*c85f09ccSJohn Levon 		return NULL;
87*c85f09ccSJohn Levon 	list = do_search_macro(macro_table, &pos);
88*c85f09ccSJohn Levon 	return last_ptr_list((struct ptr_list *)list);
89*c85f09ccSJohn Levon }
90*c85f09ccSJohn Levon 
91*c85f09ccSJohn Levon struct string_list *get_all_macros(struct position pos)
92*c85f09ccSJohn Levon {
93*c85f09ccSJohn Levon 	if (!macro_table)
94*c85f09ccSJohn Levon 		return NULL;
951f5207b7SJohn Levon 	return do_search_macro(macro_table, &pos);
961f5207b7SJohn Levon }
97