1 /* pk-ios.c - IOS-related functions for poke. */
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 #include <config.h>
20
21 #include <regex.h>
22
23 #include "poke.h"
24 #include "pk-ios.h"
25 #include "pk-map.h"
26
27 int
pk_open_ios(const char * handler,int set_cur_p)28 pk_open_ios (const char *handler, int set_cur_p)
29 {
30 int ios_id;
31
32 ios_id = pk_ios_open (poke_compiler, handler, 0, 1);
33 if (ios_id == PK_IOS_NOID)
34 return ios_id;
35
36 if (poke_auto_map_p)
37 {
38 int i;
39 pk_val auto_map;
40 pk_val nelem;
41
42 auto_map = pk_decl_val (poke_compiler, "auto_map");
43 if (auto_map == PK_NULL)
44 pk_fatal ("auto_map is PK_NULL");
45
46 nelem = pk_array_nelem (auto_map);
47 for (i = 0; i < pk_uint_value (nelem); ++i)
48 {
49 pk_val auto_map_entry;
50 pk_val regex, mapname;
51 regex_t regexp;
52 regmatch_t matches;
53
54 auto_map_entry = pk_array_elem_val (auto_map, i);
55 if (pk_type_code (pk_typeof (auto_map_entry)) != PK_ARRAY
56 || pk_uint_value (pk_array_nelem (auto_map_entry)) != 2)
57 pk_fatal ("invalid entry in auto_val");
58
59 regex = pk_array_elem_val (auto_map_entry, 0);
60 if (pk_type_code (pk_typeof (regex)) != PK_STRING)
61 pk_fatal ("regexp should be a string in an auto_val entry");
62
63 mapname = pk_array_elem_val (auto_map_entry, 1);
64 if (pk_type_code (pk_typeof (mapname)) != PK_STRING)
65 pk_fatal ("mapname should be a string in an auto_val entry");
66
67 if (regcomp (®exp, pk_string_str (regex),
68 REG_EXTENDED | REG_NOSUB) != 0)
69 {
70 pk_term_class ("error");
71 pk_puts ("error: ");
72 pk_term_end_class ("error");
73
74 pk_printf ("invalid regexp `%s' in auto_map. Skipping entry.\n",
75 pk_string_str (regex));
76 }
77 else
78 {
79 if (regexec (®exp, handler, 1, &matches, 0) == 0)
80 {
81 /* Load the map. */
82
83 const char *map_handler
84 = pk_map_resolve_map (pk_string_str (mapname),
85 0 /* handler_p */);
86
87 if (!map_handler)
88 {
89 pk_term_class ("error");
90 pk_puts ("warning: ");
91 pk_term_end_class ("error");
92
93 pk_printf ("auto-map: unknown map `%s'",
94 pk_string_str (mapname));
95 regfree (®exp);
96 break;
97 }
98
99 if (!pk_map_load_file (ios_id, map_handler, NULL))
100 {
101 pk_term_class ("error");
102 pk_puts ("error: ");
103 pk_term_end_class ("error");
104
105 pk_printf ("auto-map: loading `%s'\n",
106 pk_string_str (mapname));
107 regfree (®exp);
108 break;
109 }
110
111 if (poke_interactive_p && !poke_quiet_p && !poke_prompt_maps_p)
112 pk_printf ("auto-map: map `%s' loaded\n",
113 pk_string_str (mapname));
114 }
115
116 regfree (®exp);
117 }
118 }
119 }
120
121 return ios_id;
122 }
123