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 (&regexp, 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 (&regexp, 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 (&regexp);
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 (&regexp);
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 (&regexp);
117           }
118       }
119   }
120 
121   return ios_id;
122 }
123