blob: 0f661478a0a72e08a41d579bfb1214b8f12a8454 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include "asn1c_internal.h"
Lev Walkin59004fa2004-08-20 13:37:01 +00002#include "asn1c_misc.h"
3
Lev Walkin082cadc2005-08-14 02:18:27 +00004#include <asn1fix_crange.h> /* constraint groker from libasn1fix */
5#include <asn1fix_export.h> /* other exportable stuff from libasn1fix */
Lev Walkinf15320b2004-06-03 03:38:44 +00006
Lev Walkinf15320b2004-06-03 03:38:44 +00007/*
Ozbolt Menegatti11a3d682016-10-24 15:22:57 +02008 * Checks that the given string is not a reserved C/C++ keyword [1],[2].
9 * _* keywords not included, since asn1 identifiers cannot begin with hyphen [3]
10 * [1] ISO/IEC 9899:2011 (C11), 6.4.1
11 * [2] ISO/IEC 14882:2014 (C++14), 2.12
12 * [3] ISO/IEC 8824-1:2003 (asn1) 11.3
Lev Walkin801fabc2005-01-28 12:18:50 +000013 */
14static char *res_kwd[] = {
Ozbolt Menegatti11a3d682016-10-24 15:22:57 +020015 /* C */
16 "auto", "break", "case", "char", "const", "continue", "default", "do",
17 "double", "else", "enum", "extern", "float", "for", "goto", "if",
18 "inline", "int", "long", "register", "restrict", "return", "short",
19 "signed", "sizeof", "static", "struct", "switch", "typedef", "union",
20 "unsigned", "void", "volatile", "while",
21 /* C++ */
22 "alignas", "alignof", "and", "and_eq", "asm", "bitand", "bitor", "bool",
23 "catch", "char16_t", "char32_t", "class", "compl", "const_cast",
24 "constexpr", "decltype", "delete", "delete", "dynamic_cast",
25 "explicit", "export", "false", "friend", "mutable", "namespace", "new",
26 "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
27 "private", "protected", "public", "reinterpret_cast", "static_assert",
28 "static_cast", "template", "this", "thread_local", "throw", "true", "try",
29 "typeid", "typename", "using", "virtual", "wchar_t", "xor", "xor_eq"
Lev Walkin3fe2e122005-03-03 21:29:27 +000030};
Lev Walkin801fabc2005-01-28 12:18:50 +000031static int
32reserved_keyword(const char *str) {
Lev Walkinc46b7cb2006-08-18 02:27:55 +000033 size_t i;
Lev Walkin801fabc2005-01-28 12:18:50 +000034 for(i = 0 ; i < sizeof(res_kwd)/sizeof(res_kwd[0]); i++) {
35 if(strcmp(str, res_kwd[i]) == 0)
36 return 1;
37 }
38 return 0;
39}
40
41/*
Lev Walkinf15320b2004-06-03 03:38:44 +000042 * Construct identifier from multiple parts.
43 * Convert unsafe characters to underscores.
44 */
45char *
Lev Walkina00d6b32006-03-21 03:40:38 +000046asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
Lev Walkinf15320b2004-06-03 03:38:44 +000047 static char *storage;
48 static int storage_size;
49 int nodelimiter = 0;
50 va_list ap;
51 char *str;
Lev Walkin801fabc2005-01-28 12:18:50 +000052 char *nextstr;
Lev Walkina00d6b32006-03-21 03:40:38 +000053 char *first = 0;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080054 ssize_t size = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +000055 char *p;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080056 char *prefix = NULL;
57 char *sptr[4], **psptr = &sptr[0];
58 int sptr_cnt = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +000059
Lev Walkina00d6b32006-03-21 03:40:38 +000060 if(expr) {
61 /*
62 * Estimate the necessary storage size
63 */
64 if(expr->Identifier == NULL)
65 return "Member";
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080066 /*
67 * Add MODULE name to resolve clash
68 */
69 if(expr->_mark & TM_NAMECLASH) {
70 size += strlen(expr->module->ModuleName) + 2;
71 sptr[sptr_cnt++] = expr->module->ModuleName;
72 }
73 sptr[sptr_cnt++] = expr->Identifier;
74
75 size += strlen(expr->Identifier);
Lev Walkina00d6b32006-03-21 03:40:38 +000076 if(expr->spec_index != -1) {
77 static char buf[32];
Lev Walkina00d6b32006-03-21 03:40:38 +000078 size += 1 + snprintf(buf, sizeof buf, "%dP%d",
79 expr->_lineno, expr->spec_index);
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080080 sptr[sptr_cnt++] = (char *)&buf;
Lev Walkina00d6b32006-03-21 03:40:38 +000081 }
82 } else {
83 size = -1;
84 }
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080085 sptr[sptr_cnt++] = (char *)0;
Lev Walkinf15320b2004-06-03 03:38:44 +000086
Lev Walkina00d6b32006-03-21 03:40:38 +000087 va_start(ap, expr);
Lev Walkinf15320b2004-06-03 03:38:44 +000088 while((str = va_arg(ap, char *)))
89 size += 1 + strlen(str);
90 va_end(ap);
Lev Walkina00d6b32006-03-21 03:40:38 +000091 if(size == -1) return NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +000092
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +080093 if(prefix)
94 size += 1 + strlen(prefix);
Lev Walkinf15320b2004-06-03 03:38:44 +000095 /*
Lev Walkinf4cbbe72017-06-27 08:19:11 -070096 * Make sure we have the required amount of storage.
Lev Walkinf15320b2004-06-03 03:38:44 +000097 */
98 if(storage_size <= size) {
Lev Walkinf4cbbe72017-06-27 08:19:11 -070099 char *tmp = malloc(size + 1);
100 if(tmp) {
101 free(storage);
102 storage = tmp;
103 storage_size = size + 1;
104 } else {
105 return NULL;
106 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000107 }
108
109 /*
110 * Fill-in the storage.
111 */
Lev Walkina00d6b32006-03-21 03:40:38 +0000112 va_start(ap, expr);
Lev Walkinf15320b2004-06-03 03:38:44 +0000113 p = storage;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800114 if(prefix) {
115 strcpy(storage, prefix);
116 p += strlen(prefix);
117 }
Lev Walkina00d6b32006-03-21 03:40:38 +0000118 nextstr = "";
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800119 for(str = 0; str || nextstr; str = nextstr) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000120 int subst_made = 0;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800121 nextstr = *(psptr) ? *(psptr++) : va_arg(ap, char *);
Lev Walkina00d6b32006-03-21 03:40:38 +0000122
123 if(str == 0) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800124 str = first = nextstr;
125 nextstr = *(psptr) ? *(psptr++) : va_arg(ap, char *);
126 if (!first) continue;
Lev Walkina00d6b32006-03-21 03:40:38 +0000127 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000128
129 if(str[0] == ' ' && str[1] == '\0') {
130 *p++ = ' ';
131 nodelimiter = 1; /* No delimiter */
132 continue;
133 }
134
Lev Walkin22b5ed42006-09-13 02:51:20 +0000135 if(str != first && !nodelimiter && !(flags & AMI_NODELIMITER))
Lev Walkinf15320b2004-06-03 03:38:44 +0000136 *p++ = '_'; /* Delimiter between tokens */
137 nodelimiter = 0;
138
Lev Walkin801fabc2005-01-28 12:18:50 +0000139 /*
140 * If it is a single argument, check that it does not clash
141 * with C/C++ language keywords.
142 */
143 if((flags & AMI_CHECK_RESERVED)
Lev Walkina00d6b32006-03-21 03:40:38 +0000144 && str == first && !nextstr && reserved_keyword(str)) {
Lev Walkin801fabc2005-01-28 12:18:50 +0000145 *p++ = toupper(*str++);
146 /* Fall through */
147 }
148
Lev Walkinf15320b2004-06-03 03:38:44 +0000149 for(; *str; str++) {
150 if(isalnum(*str)) {
151 *p++ = *str;
152 subst_made = 0;
153 } else if(!subst_made++) {
Lev Walkin801fabc2005-01-28 12:18:50 +0000154 if((flags & AMI_MASK_ONLY_SPACES)
155 && !isspace(*str)) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000156 *p ++ = *str;
157 } else {
158 *p++ = '_';
159 }
160 }
161 }
162 }
163 va_end(ap);
164 *p = '\0';
165
166 assert((p - storage) <= storage_size);
167
168 return storage;
169}
170
Lev Walkinf15320b2004-06-03 03:38:44 +0000171char *
172asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
Lev Walkina00d6b32006-03-21 03:40:38 +0000173 asn1p_expr_t *exprid = 0;
Lev Walkin5a8219a2004-09-08 00:28:57 +0000174 asn1p_expr_t *top_parent;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800175 asn1p_expr_t *terminal = 0;
Lev Walkin22b5ed42006-09-13 02:51:20 +0000176 int stdname = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000177 char *typename;
178
Lev Walkin5a8219a2004-09-08 00:28:57 +0000179 /* Rewind to the topmost parent expression */
180 if((top_parent = expr->parent_expr))
181 while(top_parent->parent_expr)
182 top_parent = top_parent->parent_expr;
183
Lev Walkin725883b2006-10-09 12:07:58 +0000184 if(0) DEBUG("asn1c_type_name(%s: 0x%x)",
185 expr->Identifier, expr->expr_type);
Lev Walkinc2a75092006-03-14 11:52:12 +0000186
Lev Walkinf15320b2004-06-03 03:38:44 +0000187 switch(expr->expr_type) {
188 case A1TC_REFERENCE:
189 typename = expr->reference->components[
190 expr->reference->comp_count-1].name;
191 if(typename[0] == '&') {
192 arg_t tmp = *arg;
193
194 /*
195 * This is a reference to a type defined in a class.
196 * Resolve it and use instead.
197 */
Lev Walkinc0e03b92017-08-22 01:48:23 -0700198 tmp.expr = WITH_MODULE_NAMESPACE(
199 arg->expr->module, expr_ns,
200 asn1f_class_access_ex(arg->asn, arg->expr->module, expr_ns,
201 arg->expr, expr->rhs_pspecs,
202 expr->reference));
203 if(!tmp.expr) return NULL;
Lev Walkinf15320b2004-06-03 03:38:44 +0000204
Lev Walkinf15320b2004-06-03 03:38:44 +0000205 return asn1c_type_name(&tmp, tmp.expr, _format);
Lev Walkin5a8219a2004-09-08 00:28:57 +0000206 }
207
Lev Walkinc0e03b92017-08-22 01:48:23 -0700208 terminal = WITH_MODULE_NAMESPACE(
209 expr->module, expr_ns,
210 asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
Lev Walkina00d6b32006-03-21 03:40:38 +0000211
Lev Walkinc0e03b92017-08-22 01:48:23 -0700212 if(_format == TNF_RSAFE) {
Lev Walkinc8285712005-03-04 22:18:20 +0000213 if(terminal && terminal->expr_type & ASN_CONSTR_MASK) {
214 typename = terminal->Identifier;
215 }
216 }
217
Lev Walkin8dd0eed2004-09-17 06:32:12 +0000218 if(_format == TNF_CTYPE) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000219 /*
Lev Walkin8dd0eed2004-09-17 06:32:12 +0000220 * If the component references the type itself,
Lev Walkinc8285712005-03-04 22:18:20 +0000221 * switch to a recursion-safe type naming
Lev Walkin8dd0eed2004-09-17 06:32:12 +0000222 * ("struct foo" instead of "foo_t").
Lev Walkinf15320b2004-06-03 03:38:44 +0000223 */
Lev Walkin8dd0eed2004-09-17 06:32:12 +0000224 if(terminal && terminal == top_parent) {
225 _format = TNF_RSAFE;
Lev Walkin5a8219a2004-09-08 00:28:57 +0000226 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000227 }
Lev Walkina00d6b32006-03-21 03:40:38 +0000228
Bi-Ruei, Chiu94f0b642017-06-29 01:34:23 +0800229 if(_format != TNF_RSAFE && terminal && ((terminal->spec_index != -1) || (terminal->_mark & TM_NAMECLASH))) {
Lev Walkina00d6b32006-03-21 03:40:38 +0000230 exprid = terminal;
231 typename = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000232 }
Lev Walkina00d6b32006-03-21 03:40:38 +0000233
Lev Walkinf15320b2004-06-03 03:38:44 +0000234 break;
235 case ASN_BASIC_INTEGER:
236 case ASN_BASIC_ENUMERATED:
Lev Walkinc78cbfb2004-09-14 12:47:45 +0000237 case ASN_BASIC_REAL:
Lev Walkin082cadc2005-08-14 02:18:27 +0000238 if((expr->expr_type == ASN_BASIC_REAL
Lev Walkin2a744a72013-03-27 01:56:23 -0700239 && !(arg->flags & A1C_USE_WIDE_TYPES))
Lev Walkin082cadc2005-08-14 02:18:27 +0000240 || asn1c_type_fits_long(arg, expr)) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000241 switch(_format) {
242 case TNF_CTYPE:
243 case TNF_RSAFE:
Lev Walkinc78cbfb2004-09-14 12:47:45 +0000244 if(expr->expr_type == ASN_BASIC_REAL)
245 return "double";
Lev Walkin8bb57a22007-12-03 13:41:36 +0000246 else if(asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN)
247 return "unsigned long";
Lev Walkinf15320b2004-06-03 03:38:44 +0000248 else
Lev Walkin475d91f2005-02-25 12:09:55 +0000249 return "long";
Lev Walkin22b5ed42006-09-13 02:51:20 +0000250 default:
251 typename = 0;
252 switch(expr->expr_type) {
253 case ASN_BASIC_INTEGER:
254 typename = "NativeInteger"; break;
255 case ASN_BASIC_ENUMERATED:
256 typename = "NativeEnumerated"; break;
257 case ASN_BASIC_REAL:
258 typename = "NativeReal"; break;
259 default:
260 break;
261 }
262 break;
Lev Walkinc78cbfb2004-09-14 12:47:45 +0000263 }
Lev Walkin22b5ed42006-09-13 02:51:20 +0000264 if(typename) {
265 if(_format != TNF_INCLUDE)
266 return typename;
267 stdname = 1;
268 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000269 }
270 }
271 /* Fall through */
272 default:
Lev Walkin0e22b982004-08-25 02:03:26 +0000273 if(expr->expr_type
274 & (ASN_CONSTR_MASK | ASN_BASIC_MASK | ASN_STRING_MASK)) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000275 if(_format == TNF_RSAFE)
276 _format = TNF_CTYPE;
Lev Walkin22b5ed42006-09-13 02:51:20 +0000277 stdname = 1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000278 typename = ASN_EXPR_TYPE2STR(expr->expr_type);
279 } else {
Lev Walkin8dd0eed2004-09-17 06:32:12 +0000280 _format = TNF_RSAFE;
Lev Walkinf15320b2004-06-03 03:38:44 +0000281 typename = expr->Identifier;
282 }
283 }
284
285 switch(_format) {
286 case TNF_UNMODIFIED:
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800287 return asn1c_make_identifier(AMI_MASK_ONLY_SPACES | AMI_NODELIMITER,
288 0, MODULE_NAME_OF(exprid), exprid ? exprid->Identifier : typename, (char*)0);
Lev Walkin22b5ed42006-09-13 02:51:20 +0000289 case TNF_INCLUDE:
290 return asn1c_make_identifier(
291 AMI_MASK_ONLY_SPACES | AMI_NODELIMITER,
Lev Walkinffd035e2010-10-16 01:26:57 -0700292 0, ((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
293 ? "\"" : "<"),
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800294 MODULE_NAME_OF(exprid),
Lev Walkin22b5ed42006-09-13 02:51:20 +0000295 exprid ? exprid->Identifier : typename,
Lev Walkinffd035e2010-10-16 01:26:57 -0700296 ((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
Vasil Velichkovfebd3d52016-07-18 20:24:49 +0300297 ? ".h\"" : ".h>"), (char*)0);
Lev Walkinf15320b2004-06-03 03:38:44 +0000298 case TNF_SAFE:
Vasil Velichkovfebd3d52016-07-18 20:24:49 +0300299 return asn1c_make_identifier(0, exprid, typename, (char*)0);
Lev Walkinc8285712005-03-04 22:18:20 +0000300 case TNF_CTYPE: /* C type */
Lev Walkina00d6b32006-03-21 03:40:38 +0000301 return asn1c_make_identifier(0, exprid,
Vasil Velichkovfebd3d52016-07-18 20:24:49 +0300302 exprid?"t":typename, exprid?0:"t", (char*)0);
Lev Walkinc8285712005-03-04 22:18:20 +0000303 case TNF_RSAFE: /* Recursion-safe type */
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800304 return asn1c_make_identifier(AMI_CHECK_RESERVED | AMI_NODELIMITER, 0,
305 "struct", " ", MODULE_NAME_OF(exprid), typename, (char*)0);
Lev Walkinf15320b2004-06-03 03:38:44 +0000306 }
307
Lev Walkin8dd0eed2004-09-17 06:32:12 +0000308 assert(!"unreachable");
Lev Walkinf15320b2004-06-03 03:38:44 +0000309 return typename;
310}
311
Lev Walkin082cadc2005-08-14 02:18:27 +0000312/*
313 * Check whether the specified INTEGER or ENUMERATED type can be represented
Lev Walkin8bb57a22007-12-03 13:41:36 +0000314 * using the generic 'long' or 'unsigned long' type.
Lev Walkin082cadc2005-08-14 02:18:27 +0000315 */
316enum asn1c_fitslong_e
317asn1c_type_fits_long(arg_t *arg, asn1p_expr_t *expr) {
318 asn1cnst_range_t *range = 0;
319 asn1cnst_edge_t left;
320 asn1cnst_edge_t right;
321 asn1p_expr_t *v;
322
323/*
324 * Since we don't know the sizeof(long) on the possible target platform
325 * which will be compiling the code generated by asn1c, let's play it
326 * simple: long's range is equal to or greater than int32_t.
Lev Walkin4c97bd62005-08-15 01:01:24 +0000327 * NOTE: the most negative integer cannot be written in C, as the C99
328 * standard will give it an unsigned type.
329 * It is defined here as a constant expression.
Lev Walkin082cadc2005-08-14 02:18:27 +0000330 */
Lev Walkinc08c3cf2005-08-15 01:04:48 +0000331#define RIGHTMAX 2147483647 /* of 32-bit integer type */
332#define LEFTMIN (-RIGHTMAX-1) /* of 32-bit integer type */
Lev Walkin082cadc2005-08-14 02:18:27 +0000333
334 /* Descend to the terminal type */
Lev Walkinc0e03b92017-08-22 01:48:23 -0700335 expr = WITH_MODULE_NAMESPACE(
336 expr->module, expr_ns,
337 asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
338 if(expr == 0) return FL_NOTFIT;
Lev Walkin082cadc2005-08-14 02:18:27 +0000339
340 /* The "fits into long" operation is relevant only for integer types */
341 switch(expr->expr_type) {
342 case ASN_BASIC_INTEGER:
343 case ASN_BASIC_ENUMERATED:
344 break;
345 default:
346 return FL_NOTFIT;
347 }
348
349 /*
350 * First, evaluate the range of explicitly given identifiers.
351 */
352 TQ_FOR(v, &(expr->members), next) {
353 if(v->expr_type != A1TC_UNIVERVAL)
354 continue;
355 if(v->value->value.v_integer < LEFTMIN
356 || v->value->value.v_integer > RIGHTMAX)
357 return FL_NOTFIT;
358 }
359
Lev Walkin4b553412005-08-14 14:45:44 +0000360 if(!expr->combined_constraints)
Lev Walkin2a744a72013-03-27 01:56:23 -0700361 return (arg->flags & A1C_USE_WIDE_TYPES)
362 ? FL_NOTFIT : FL_PRESUMED;
Lev Walkin4b553412005-08-14 14:45:44 +0000363
Lev Walkin082cadc2005-08-14 02:18:27 +0000364 /*
Lev Walkin4b553412005-08-14 14:45:44 +0000365 * Second, if -fbless-SIZE is given, the (SIZE()) constraint may be
366 * applied (non-standard! but we can deal with this) to the type.
367 * Check the range.
Lev Walkin082cadc2005-08-14 02:18:27 +0000368 */
Lev Walkina28cbb92017-07-31 20:20:17 -0700369 range = asn1constraint_compute_constraint_range(expr->Identifier,
370 expr->expr_type,
Lev Walkin4b553412005-08-14 14:45:44 +0000371 expr->combined_constraints, ACT_CT_SIZE, 0, 0,
372 CPR_simulate_fbless_SIZE);
373 if(range) {
374 if(!range->incompatible) {
375 right = range->right;
376 /* Use 4 instead of sizeof(long) is justified! */
377 if(right.type == ARE_VALUE && right.value <= 4)
Lev Walkin8bb57a22007-12-03 13:41:36 +0000378 return FL_FITS_SIGNED;
Lev Walkin4b553412005-08-14 14:45:44 +0000379 }
380 asn1constraint_range_free(range);
381 }
382
383 /*
384 * Third, pull up the PER visible range of the INTEGER.
385 */
Lev Walkina28cbb92017-07-31 20:20:17 -0700386 range = asn1constraint_compute_PER_range(expr->Identifier, expr->expr_type,
Lev Walkin4b553412005-08-14 14:45:44 +0000387 expr->combined_constraints, ACT_EL_RANGE, 0, 0, 0);
Lev Walkine5086e32014-02-10 11:00:51 -0800388
Lev Walkin082cadc2005-08-14 02:18:27 +0000389 if(!range
Lev Walkine5086e32014-02-10 11:00:51 -0800390 /* Commenting out
391 || range->extensible
392 * because this may or may not indicate wide type.
393 */
Lev Walkin334d5cc2014-02-10 11:06:56 -0800394 || (range->extensible && (arg->flags & A1C_USE_WIDE_TYPES))
Lev Walkin082cadc2005-08-14 02:18:27 +0000395 || range->empty_constraint
Lev Walkin082cadc2005-08-14 02:18:27 +0000396 || range->incompatible
397 || range->not_PER_visible
398 ) {
399 asn1constraint_range_free(range);
Lev Walkin2a744a72013-03-27 01:56:23 -0700400 return (arg->flags & A1C_USE_WIDE_TYPES)
401 ? FL_NOTFIT : FL_PRESUMED;
Lev Walkin082cadc2005-08-14 02:18:27 +0000402 }
403
404 left = range->left;
405 right = range->right;
406 asn1constraint_range_free(range);
407
Lev Walkin8bb57a22007-12-03 13:41:36 +0000408 /* Special case for unsigned */
409 if(left.type == ARE_VALUE
410 && left.value >= 0
411 && right.type == ARE_VALUE
412 && right.value > 2147483647
Lev Walkin1b3a1352016-01-10 13:15:02 -0800413 && right.value <= (asn1c_integer_t)(4294967295UL))
Lev Walkin8bb57a22007-12-03 13:41:36 +0000414 return FL_FITS_UNSIGN;
415
416
Lev Walkin082cadc2005-08-14 02:18:27 +0000417 /* If some fixed value is outside of target range, not fit */
418 if(left.type == ARE_VALUE
419 && (left.value < LEFTMIN || left.value > RIGHTMAX))
420 return FL_NOTFIT;
421 if(right.type == ARE_VALUE
422 && (right.value > RIGHTMAX || right.value < LEFTMIN))
423 return FL_NOTFIT;
424
Lev Walkin2a744a72013-03-27 01:56:23 -0700425 /* If the range is open, fits only unless -fwide-types is given */
Lev Walkin082cadc2005-08-14 02:18:27 +0000426 if(left.type != ARE_VALUE || right.type != ARE_VALUE) {
Lev Walkin2a744a72013-03-27 01:56:23 -0700427 return (arg->flags & A1C_USE_WIDE_TYPES)
428 ? FL_NOTFIT : FL_PRESUMED;
Lev Walkin082cadc2005-08-14 02:18:27 +0000429 }
430
Lev Walkin8bb57a22007-12-03 13:41:36 +0000431 return FL_FITS_SIGNED;
Lev Walkin082cadc2005-08-14 02:18:27 +0000432}
433