+static udi_index_t _get_token_idx(const char *str, const char **outstr)
+{
+ char *end;
+ int ret = strtol(str, &end, 10);
+ if( ret < 0 || ret > 255 ) {
+ Log_Notice("UDI", "Value '%.*s' out of range for udi_index_t",
+ end-str, str);
+ *outstr = NULL;
+ return 0;
+ }
+ if( *end && !isspace(*end) ) {
+ Log_Notice("UDI", "No whitespace following '%.*s', got '%c'",
+ end-str, str, *end);
+ *outstr = NULL;
+ return 0;
+ }
+ while( *end && isspace(*end) )
+ end ++;
+
+ *outstr = end;
+ return ret;
+}
+static udi_ubit16_t _get_token_uint16(const char *str, const char **outstr)
+{
+ char *end;
+ unsigned long ret = strtoul(str, &end, 10);
+ if( ret > 0xFFFF ) {
+ Log_Notice("UDI", "Value '%.*s' out of range for udi_ubit16_t",
+ end-str, str);
+ *outstr = NULL;
+ return 0;
+ }
+ if( *end && !isspace(*end) ) {
+ Log_Notice("UDI", "No whitespace following '%.*s', got '%c'",
+ end-str, str, *end);
+ *outstr = NULL;
+ return 0;
+ }
+ while( *end && isspace(*end) )
+ end ++;
+
+ *outstr = end;
+ return ret;
+}
+static udi_ubit32_t _get_token_uint32(const char *str, const char **outstr)
+{
+ char *end;
+ udi_ubit32_t ret = strtoul(str, &end, 0);
+ if( *end && !isspace(*end) ) {
+ Log_Notice("UDI", "No whitespace following '%.*s', got '%c'",
+ end-str, str, *end);
+ *outstr = NULL;
+ return 0;
+ }
+ while( *end && isspace(*end) )
+ end ++;
+
+ *outstr = end;
+ return ret;
+}
+static int _get_token_sym(const char *str, const char **outstr, ...)
+{
+ va_list args;
+ va_start(args, outstr);
+ const char *sym;
+ for( int idx = 0; (sym = va_arg(args, const char *)); idx ++ )
+ {
+ size_t len = strlen(sym);
+ if( memcmp(str, sym, len) != 0 )
+ continue ;
+ if( str[len] && !isspace(str[len]) )
+ continue ;
+
+ // Found it!
+ return idx;
+ }
+ va_end(args);
+
+ const char *end = str;
+ while( !isspace(*end) )
+ end ++;
+ Log_Notice("UDI", "Unknown token '%.*s'",
+ end-str, str);
+
+ *outstr = NULL;
+ return -1;
+}
+
+