Fawkes API Fawkes Development Version
mod_utils.h
1
2/***************************************************************************
3 * mod_utils.cpp - OpenPRS module utils
4 *
5 * Created: Tue Aug 26 17:33:01 2014
6 * Copyright 2014 Tim Niemueller [www.niemueller.de]
7 ****************************************************************************/
8
9/* This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Library General Public License for more details.
18 *
19 * Read the full text in the LICENSE.GPL file in the doc directory.
20 */
21
22#ifndef _PLUGINS_OPENPRS_AGENT_MOD_UTILS_H_
23#define _PLUGINS_OPENPRS_AGENT_MOD_UTILS_H_
24
25#include <algorithm>
26#include <cstdio>
27#include <cstring>
28#include <string>
29#include <unistd.h>
30
31// clang-format off
32#include <opaque-pub.h>
33#include <action_f-pub.h>
34#include <constant-pub.h>
35#include <ev-function_f-pub.h>
36#include <ev-predicate_f-pub.h>
37#include <intention_f-pub.h>
38#include <macro-pub.h>
39#include <oprs-type-pub.h>
40#include <oprs-type_f-pub.h>
41#include <shashPack_f.h>
42#include <slistPack-pub.h>
43#include <user-end-hook_f-pub.h>
44// clang-format on
45
46/// @cond EXTERNAL
47extern "C" {
48typedef Slist *List_Envar;
49List_Envar global_var_list;
50Shash * id_hash;
51
52typedef struct type Type;
53typedef Slist * TypeList;
54typedef Slist * SymList;
55Symbol wait_sym;
56
57/* type de Variable */
58typedef enum { LOGICAL_VARIABLE, PROGRAM_VARIABLE } Variable_Type;
59
60struct envar
61{ /* Un envar */
62 Symbol name; /* son name */
63 Term * value; /* le term sur lequel elle pointe */
64 Type * unif_type;
65 Variable_Type type BITFIELDS( : 8); /* Le type de la variable */
66};
67
68struct type
69{
70 Symbol name;
71 Type * father;
72 TypeList sur_types; /* Plus itself */
73 SymList elts;
74};
75}
76/// @endcond
77
78/** Get Fawkes host and port.
79 * This goes through the list of global variables and extracts the
80 * parent Fawkes hostname from @@FAWKES_HOST and the TCP port from
81 * @@FAWKES_PORT.
82 * @return true if the data could be gathered successfully, false otherwise
83 */
84bool
85get_fawkes_host_port(std::string &fawkes_host, unsigned short &fawkes_port)
86{
87 Envar *env;
88 sl_loop_through_slist(global_var_list, env, Envar *)
89 {
90 if (strcmp(env->name, "@@FAWKES_HOST") == 0 || strcmp(env->name, "@@fawkes_host") == 0) {
91 if (env->value->type != STRING) {
92 fprintf(stderr, "Error: @@FAWKES_HOST is not of type STRING\n");
93 return false;
94 }
95 fawkes_host = env->value->u.string;
96 } else if (strcmp(env->name, "@@FAWKES_PORT") == 0 || strcmp(env->name, "@@fawkes_port") == 0) {
97 if (env->value->type != STRING) {
98 fprintf(stderr, "Error: @@FAWKES_PORT is not of type STRING\n");
99 return false;
100 }
101 fawkes_port = atoi(env->value->u.string);
102 }
103 }
104
105 if (fawkes_host.empty()) {
106 fawkes_host = getenv("FAWKES_HOST");
107 }
108 if (fawkes_port == 0) {
109 fawkes_port = atoi(getenv("FAWKES_PORT"));
110 }
111
112 return (!fawkes_host.empty() && fawkes_port != 0);
113}
114
115//define ACTION_DEBUG
116
117#ifdef ACTION_DEBUG
118# define ACTION_RETURN(value) \
119 do { \
120 if (value == nil_sym || value == lisp_t_sym) { \
121 printf("Action returns: %s\n", \
122 value == nil_sym ? "FAIL" : (value == wait_sym ? ":WAIT" : "FINAL")); \
123 } \
124 Term *res = MAKE_OBJECT(Term); \
125 res->type = ATOM; \
126 res->u.id = value; \
127 return res; \
128 } while (0);
129#else
130# define ACTION_RETURN(value) \
131 do { \
132 Term *res = MAKE_OBJECT(Term); \
133 res->type = ATOM; \
134 res->u.id = value; \
135 return res; \
136 } while (0);
137#endif
138#define ACTION_FAIL() ACTION_RETURN(nil_sym);
139#define ACTION_WAIT() ACTION_RETURN(wait_sym);
140#define ACTION_FINAL() ACTION_RETURN(lisp_t_sym);
141
142bool
143assert_arg_type(const char *func_name, TermList &tl, int index, Term_Type t_type)
144{
145 Term *t = (Term *)get_list_pos(tl, index);
146 if (t->type != t_type) {
147 const char *type = "UNKNOWN";
148 switch (t_type) {
149 case INTEGER: type = "INTEGER"; break;
150 case LONG_LONG: type = "LONG_LONG"; break;
151 case TT_FLOAT: type = "TT_FLOAT"; break;
152 case STRING: type = "STRING"; break;
153 case TT_ATOM: type = "TT_ATOM"; break;
154 case EXPRESSION: type = "EXPRESSION"; break;
155 case VARIABLE: type = "VARIABLE"; break;
156 case LISP_LIST: type = "LISP_LIST"; break;
157 case INT_ARRAY: type = "INT_ARRAY"; break;
158 case FLOAT_ARRAY: type = "FLOAT_ARRAY"; break;
159 case C_LIST: type = "C_LIST"; break;
160 case TT_FACT: type = "TT_FACT"; break;
161 case TT_GOAL: type = "FF_GOAL"; break;
162 case TT_INTENTION: type = "TT_INTENTION"; break;
163 case TT_OP_INSTANCE: type = "TT_OP_INSTANCE"; break;
164 case U_POINTER: type = "U_POINTER"; break;
165 case U_MEMORY: type = "U_MEMORY"; break;
166 }
167 fprintf(stderr, "Error[%s]: argument type is not a %s\n", func_name, type);
168 return false;
169 } else {
170 return true;
171 }
172}
173
174#define ACTION_ASSERT_ARG_LENGTH(func_name, tl, length) \
175 do { \
176 int terms_len = sl_slist_length(tl); \
177 if (terms_len != length) { \
178 fprintf(stderr, \
179 "Error[%s]: invalid number of arguments:" \
180 " req %i, got %i\n", \
181 func_name, \
182 length, \
183 terms_len); \
184 ACTION_FAIL(); \
185 } \
186 } while (0);
187
188#define ACTION_SET_AND_ASSERT_ARG_TYPE(func_name, var, tl, index, t_type) \
189 do { \
190 if (!assert_arg_type(func_name, tl, index, t_type)) \
191 ACTION_FAIL(); \
192 var = (Term *)get_list_pos(tl, index); \
193 } while (0);
194
195// Boolean return versions
196#define ACTION_ASSERT_B_ARG_LENGTH(func_name, tl, length) \
197 do { \
198 int terms_len = sl_slist_length(tl); \
199 if (terms_len != length) { \
200 fprintf(stderr, \
201 "Error[%s]: invalid number of arguments:" \
202 " req %i, got %i\n", \
203 func_name, \
204 length, \
205 terms_len); \
206 return false; \
207 } \
208 } while (0);
209
210#define ACTION_SET_AND_ASSERT_B_ARG_TYPE(func_name, var, tl, index, t_type) \
211 do { \
212 if (!assert_arg_type(func_name, tl, index, t_type)) \
213 return false; \
214 var = (Term *)get_list_pos(tl, index); \
215 } while (0);
216
217#define ACTION_ASSERT_B_ARG_TYPE(func_name, var, tl, index, t_type) \
218 do { \
219 if (!assert_arg_type(func_name, tl, index, t_type)) \
220 return false; \
221 } while (0);
222
223#endif