1 /* pk-map.h - Support for map files.  */
2 
3 /* Copyright (C) 2020, 2021 Jose E. Marchesi */
4 
5 /* This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /* Poke maintains a set of "named maps" associated with each open IO
20    space.  These maps are collections of mapped variables which are
21    defined in the top-level environment of the incremental compiler.
22 
23    This file provides services to access both the global map and the
24    named maps.  */
25 
26 #ifndef PK_MAP_H
27 #define PK_MAP_H
28 
29 #include <config.h>
30 
31 #include "libpoke.h"
32 
33 /* Each map entry corresponds to a mapped value in the top-level
34    environment.
35 
36    NAME is the name of the entry.  There cannot be two entries in the
37    same map with the same name.
38 
39    VARNAME is the name of a mapped variable defined in the poke
40    top-level environment.  This name is derived from the entry name
41    and the containing map ID.
42 
43    OFFSET is the offset where the entry is mapped.
44 
45    CHAIN is a pointer to another map entry, or NULL.  */
46 
47 #define PK_MAP_ENTRY_NAME(ENTRY) ((ENTRY)->name)
48 #define PK_MAP_ENTRY_VARNAME(ENTRY) ((ENTRY)->varname)
49 #define PK_MAP_ENTRY_OFFSET(ENTRY) ((ENTRY)->offset)
50 #define PK_MAP_ENTRY_CHAIN(ENTRY) ((ENTRY)->chain)
51 
52 struct pk_map_entry
53 {
54   char *name;
55   char *varname;
56   pk_val offset;
57   struct pk_map_entry *chain;
58 };
59 
60 typedef struct pk_map_entry *pk_map_entry;
61 
62 /* Poke maps are ordered sets of map entries.
63 
64    ID is an unique number identifying the map in the poke session.
65 
66    NAME is the name of the map.
67 
68    SOURCE is a string describing the origin of this map.  For maps
69    loaded from files, this contains the path of the file.  For maps
70    created by the user using commands, this is NULL.
71 
72    ENTRIES is a list of chained map entries.
73 
74    CHAIN is a pointer to another pk map, or NULL.  */
75 
76 #define PK_MAP_ID(MAP) ((MAP)->id)
77 #define PK_MAP_NAME(MAP) ((MAP)->name)
78 #define PK_MAP_SOURCE(MAP) ((MAP)->source)
79 #define PK_MAP_ENTRIES(MAP) ((MAP)->entries)
80 #define PK_MAP_CHAIN(MAP) ((MAP)->chain)
81 
82 struct pk_map
83 {
84   uint64_t id;
85   char *name;
86   char *source;
87   struct pk_map_entry *entries;
88   struct pk_map *chain;
89 };
90 
91 typedef struct pk_map *pk_map;
92 
93 /* Status codes returned by the functions below.  */
94 
95 #define PK_MAP_OK 0
96 #define PK_MAP_EINVNAME 1
97 #define PK_MAP_EINVIOS 2
98 
99 /* Create a new empty map, associated to a given IO space.
100 
101    IOS_ID is the id of an existing IO space.
102 
103    MAPNAME is a NULL-terminated string with the name of the map.
104 
105    SOURCE is a NULL-terminated string with the source of the map.
106    This is either the path of the file from which the map was loaded,
107    or NULL if the map was created interactively.
108 
109    If there is already a map named MAPNAME associated with the given
110    IO space, this function returns 0.  Otherwise this function returns
111    1.  */
112 
113 int pk_map_create (int ios_id, const char *mapname, const char *source);
114 
115 /* Remove a map.
116 
117   IOS_ID is the id of an existing IO space.
118 
119   MAPNAME is a NULL-terminated string with the name of the map to
120   remove.
121 
122   If there is no map named MAPNAME associated with the given IO space,
123   this function returns 0.  Otherwise this function returns 1.  */
124 
125 int pk_map_remove (int ios_id, const char *mapname);
126 
127 /* Add a new entry to a map.
128 
129    IOS_ID is the id of the IO space associated with the map.
130    MAPNAME is the name of the map to which the entry will be added.
131    NAME is the name of the new entry.
132    VARNAME is the name of the variable associated with the entry.
133    OFFSET is the offset where the variable is mapped.
134 
135    If there is already an entry with the given VARNAME in the given
136    map MAPNAME, then return 0.  Return 1 otherwise.  */
137 
138 int pk_map_add_entry (int ios_id, const char *mapname,
139                       const char *name, const char *varname,
140                       pk_val offset);
141 
142 /* Remove an entry from a map.
143 
144    IOS_ID si the id of the IO space associated with the map.
145 
146    MAPNAME is the name of the map from which the entry will be
147    removed.
148 
149    VARNAME is the name of a variable, used to identify the entry to
150    remove.
151 
152    If the map doesn't exist, or there is no entry for variable
153    VARNAME, return 0.  Otherwise return 1.  */
154 
155 int pk_map_remove_entry (int ios_id, const char *mapname,
156                          const char *varname);
157 
158 /* Initialize the global map.   */
159 
160 void pk_map_init (void);
161 
162 /* Free all the resources used by the global map.  */
163 
164 void pk_map_shutdown (void);
165 
166 /* Return a chained list of maps defined in the given IOS.  */
167 
168 pk_map pk_map_get_maps (int ios_id);
169 
170 /* Search for a map by name.
171 
172    IOS_ID is the ID of an IOS.
173    NAME is the name of the map.
174 
175    Return the map if found.  NULL otherwise.  */
176 
177 pk_map pk_map_search (int ios_id, const char *name);
178 
179 /* Resolve the name of a map file.
180 
181    If FILENAME_P is 1 then MAPNAME refers to a file, like `foo.map'.
182    Otherwise MAPNAME contains the name of a map, like `foo'.
183 
184    Return the full path to the file containing the map.  If no file is
185    found, then return NULL.  */
186 
187 char *pk_map_resolve_map (const char *mapname, int filename_p);
188 
189 /* Load a map from the given file.
190 
191    IOS_ID is the IO space where to install the loaded map.
192 
193    PATH is the path to the file to load.
194 
195    ERRMSG, if not NULL, is a string where either NULL or an error
196    message is stored when the function returns 0.  This string should
197    be fred by the caller.
198 
199    If there is an error loading the file, return 0.
200    Otherwise return 1.  */
201 
202 int pk_map_load_file (int ios_id, const char *path, char **errmsg);
203 
204 /* XXX writeme  */
205 int pk_map_save_file (const char *path);
206 
207 /* Given a string, normalize it to be a valid name for a map.  */
208 
209 char *pk_map_normalize_name (const char *str);
210 
211 #endif /* ! PK_MAP_H */
212