14#include "../nyx_node_internal.h"
20static const double NAN_double = (double) NAN;
24static bool _parse_format(
char *result_conv,
int *result_lcnt,
int *result_w,
int *result_f,
STR_t s)
28 STR_t p = strchr(s,
'%');
29 if(p == NULL) {
return false; }
33 STR_t q = strchr(p,
'%');
34 if(q != NULL) {
return false; }
38 while(*p ==
'+' || *p ==
'-' || *p ==
' ' || *p ==
'#' || *p ==
'0') { p++; }
48 while(isdigit((
unsigned char) *p)) { w = (w * 10) + (*p++ -
'0'); have_w =
true; }
54 while(isdigit((
unsigned char) *p)) { f = (f * 10) + (*p++ -
'0'); have_f =
true; }
67 if(*p !=
'\0') {
return false; }
69 if(!have_w || !have_f) {
return false; }
71 if(f != 3 && f != 5 && f != 6 && f != 8 && f != 9) {
return false; }
75 if(result_conv != NULL) { *result_conv =
'm'; }
76 if(result_lcnt != NULL) { *result_lcnt = 0 ; }
77 if(result_w != NULL) { *result_w = w ; }
78 if(result_f != NULL) { *result_f = f ; }
95 else if(*p ==
'h' || *p ==
'j' || *p ==
'z' || *p ==
't' || *p ==
'L')
102 if(*p ==
'\0') {
return false; }
104 char conv = *p++;
if(conv ==
'n') {
return false; }
106 if(*p !=
'\0') {
return false; }
110 if(result_conv != NULL) { *result_conv = conv; }
111 if(result_lcnt != NULL) { *result_lcnt = lcnt; }
112 if(result_w != NULL) { *result_w = 0x00; }
113 if(result_f != NULL) { *result_f = 0x00; }
122static double sextod(
STR_t p)
130 while(*p !=
'\0' && isspace((
unsigned char) *p)) { p++; }
138 if(*p ==
'-') { sign *= -1; p++; }
139 else if(*p ==
'+') { sign *= +1; p++; }
148 deg = (double) strtol(p, &end1, 10);
157 if(*p !=
':') {
return NAN_double; } p++;
161 STR_t colon = strchr(p,
':');
168 min = (double) strtol(p, &end2, 10);
177 if(p != colon) {
return NAN_double; } p++;
182 sec = (double) strtod(p, &end3);
196 min = (double) strtod(p, &end4);
212 while(*p !=
'\0' && isspace((
unsigned char) *p)) { p++; }
216 if(*p !=
'\0') {
return NAN_double; }
218 if(!(min >= 0.0 && min < 60.0)) {
return NAN_double; }
220 if(!(sec >= 0.0 && sec < 60.0)) {
return NAN_double; }
224 return sign * (deg + (min / 60.0) + (sec / 3600.0));
231static int snprintm(
str_t dst_str,
size_t dst_len,
int w,
int f,
double value)
235 STR_t sign_str = signbit(value) ?
"-"
243 int deg_i = (int) floor(value);
245 double frac_d = value - (double) deg_i;
255 long m1 = lround(frac_d * 60.0);
258 if(mm >= 60) { mm = 0; deg_i++; }
260 snprintf(core,
sizeof(core),
"%s%d:%02d", sign_str, deg_i, mm);
266 long m10 = lround(frac_d * 600.0);
267 int mm = (int) (m10 / 10);
268 int mm_t1 = (int) (m10 % 10);
270 if(mm >= 60) { mm = 0; deg_i++; }
272 snprintf(core,
sizeof(core),
"%s%d:%02d.%01d", sign_str, deg_i, mm, mm_t1);
278 long s1 = lround(frac_d * 3600.0);
279 int mm = (int) (s1 / 60);
280 int ss = (int) (s1 % 60);
282 if(mm >= 60) { mm = 0; deg_i++; }
284 snprintf(core,
sizeof(core),
"%s%d:%02d:%02d", sign_str, deg_i, mm, ss);
290 long s10 = lround(frac_d * 36000.0);
291 int mm = (int) (s10 / 600);
292 int ss = (int) (s10 % 600 / 10);
293 int ss_t1 = (int) (s10 % 10);
295 if(mm >= 60) { mm = 0; deg_i++; }
297 snprintf(core,
sizeof(core),
"%s%d:%02d:%02d.%01d", sign_str, deg_i, mm, ss, ss_t1);
303 long s100 = lround(frac_d * 360000.0);
304 int mm = (int) (s100 / 6000);
305 int ss = (int) (s100 % 6000 / 100);
306 int ss_t2 = (int) (s100 % 100);
308 if(mm >= 60) { mm = 0; deg_i++; }
310 snprintf(core,
sizeof(core),
"%s%d:%02d:%02d.%02d", sign_str, deg_i, mm, ss, ss_t2);
318 return snprintf(dst_str, dst_len,
"%*s", w, core);
320 return snprintf(dst_str, dst_len,
"%s", core);
330str_t internal_variant_to_string(
STR_t format, nyx_variant_t value)
339 if(_parse_format(&conv, &lcnt, &w, &f, format))
345 if( (value.type == NYX_VARIANT_TYPE_LONG && (conv ==
'd' ) && (l = snprintf(buffer,
sizeof(buffer), format, value.value._long)) >= 0)
347 (value.type == NYX_VARIANT_TYPE_ULONG && (conv ==
'u' || conv ==
'o' || conv ==
'x' || conv ==
'X' ) && (l = snprintf(buffer,
sizeof(buffer), format, value.value._ulong)) >= 0)
349 (value.type == NYX_VARIANT_TYPE_DOUBLE && (conv ==
'f' || conv ==
'F' || conv ==
'e' || conv ==
'E' || conv ==
'g' || conv ==
'G' || conv ==
'a' || conv ==
'A') && (l = snprintf(buffer,
sizeof(buffer), format, value.value._double)) >= 0)
351 (value.type == NYX_VARIANT_TYPE_DOUBLE && (conv ==
'm' ) && (l = snprintm(buffer,
sizeof(buffer), w, f, value.value._double)) >= 0)
353 if((
size_t) l <
sizeof(buffer))
355 for(
int i = 0; i < l; i++)
if(buffer[i] ==
',') buffer[i] =
'.';
363 if( (value.type == NYX_VARIANT_TYPE_INT && (conv ==
'd' ) && (l = snprintf(buffer,
sizeof(buffer), format, value.value._int)) >= 0)
365 (value.type == NYX_VARIANT_TYPE_UINT && (conv ==
'u' || conv ==
'o' || conv ==
'x' || conv ==
'X' ) && (l = snprintf(buffer,
sizeof(buffer), format, value.value._uint)) >= 0)
367 (value.type == NYX_VARIANT_TYPE_DOUBLE && (conv ==
'f' || conv ==
'F' || conv ==
'e' || conv ==
'E' || conv ==
'g' || conv ==
'G' || conv ==
'a' || conv ==
'A') && (l = snprintf(buffer,
sizeof(buffer), format, value.value._double)) >= 0)
369 (value.type == NYX_VARIANT_TYPE_DOUBLE && (conv ==
'm' ) && (l = snprintm(buffer,
sizeof(buffer), w, f, value.value._double)) >= 0)
371 if((
size_t) l <
sizeof(buffer))
373 for(
int i = 0; i < l; i++)
if(buffer[i] ==
',') buffer[i] =
'.';
383 NYX_LOG_ERROR(
"This function is not compatible with the format `%s`", format);
394nyx_variant_t internal_string_to_variant(
STR_t format,
STR_t value)
399 if(_parse_format(&conv, &lcnt, NULL, NULL, format))
405 return lcnt > 0 ? NYX_VARIANT_FROM_LONG((int64_t) strtol(value, NULL, 10))
406 : NYX_VARIANT_FROM_INT((int32_t) strtol(value, NULL, 10))
414 return lcnt > 0 ? NYX_VARIANT_FROM_ULONG((uint64_t) strtoul(value, NULL, 10))
415 : NYX_VARIANT_FROM_UINT((uint32_t) strtoul(value, NULL, 10))
423 return lcnt > 0 ? NYX_VARIANT_FROM_ULONG((uint64_t) strtoul(value, NULL, 8))
424 : NYX_VARIANT_FROM_UINT((uint32_t) strtoul(value, NULL, 8))
430 if(conv ==
'x' || conv ==
'X')
432 return lcnt > 0 ? NYX_VARIANT_FROM_ULONG((uint64_t) strtoul(value, NULL, 16))
433 : NYX_VARIANT_FROM_UINT((uint32_t) strtoul(value, NULL, 16))
439 if(conv ==
'f' || conv ==
'F' || conv ==
'e' || conv ==
'E' || conv ==
'g' || conv ==
'G' || conv ==
'a' || conv ==
'A')
441 return NYX_VARIANT_FROM_DOUBLE(strtod(value, NULL));
446 return NYX_VARIANT_FROM_DOUBLE(sextod(value));
452 NYX_LOG_ERROR(
"This function is not compatible with the format `%s`", format);
454 return NYX_VARIANT_FROM_INT(0);
#define NYX_LOG_ERROR(fmt,...)
Logs an error message.
#define STR_t
Alias for const char *.
__NYX_NULLABLE__ str_t nyx_string_dup(__NYX_NULLABLE__ STR_t s)
Similar to libc strdup.
#define str_t
Alias for char *.