+ break; }
+ case UDIPROPS__message:
+ {
+ tUDI_PropMessage *msg = &driver_module->Messages[msg_index++];
+ msg->locale = cur_locale;
+ msg->index = _get_token_uint16(str, &str);
+ IF_ERROR(continue);
+ msg->string = str;
+ //Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string);
+ break;
+ }
+ case UDIPROPS__locale:
+ // TODO: Set locale
+ cur_locale = 1;
+ break;
+ case UDIPROPS__region:
+ {
+ udi_index_t rgn_idx = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ // Search for region index (just in case internal_bind_ops appears earlier)
+ tUDI_PropRegion *rgn = &driver_module->RegionTypes[0];
+ if( rgn_idx > 0 )
+ {
+ rgn ++;
+ for( int i = 1; i < next_unpop_region; i ++, rgn ++ ) {
+ if( rgn->RegionIdx == rgn_idx )
+ break;
+ }
+ if(i == next_unpop_region) {
+ if( next_unpop_region == driver_module->nRegionTypes ) {
+ // TODO: warning if reigon types overflow
+ continue ;
+ }
+ next_unpop_region ++;
+ rgn->RegionIdx = rgn_idx;
+ }
+ }
+ // Parse attributes
+ while( *str )
+ {
+ int sym = _get_token_sym(str, &str, true,
+ "type", "binding", "priority", "latency", "overrun_time", NULL
+ );
+ if( !str ) break ;
+ switch(sym)
+ {
+ case 0: // type
+ rgn->Type = _get_token_sym(str, &str, true,
+ "normal", "fp", NULL);
+ break;
+ case 1: // binding
+ rgn->Binding = _get_token_sym(str, &str, true,
+ "static", "dynamic", NULL);
+ break;
+ case 2: // priority
+ rgn->Priority = _get_token_sym(str, &str, true,
+ "med", "lo", "hi", NULL);
+ break;
+ case 3: // latency
+ rgn->Latency = _get_token_sym(str, &str, true,
+ "non_overrunable", "powerfail_warning", "overrunable",
+ "retryable", "non_critical", NULL);
+ break;
+ case 4: // overrun_time
+ rgn->OverrunTime = _get_token_uint32(str, &str);
+ break;
+ }
+ IF_ERROR(break);
+ }
+ break;
+ }
+ case UDIPROPS__parent_bind_ops:
+ {
+ tUDI_BindOps *bind = &driver_module->Parents[parent_index++];
+ bind->meta_idx = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ bind->region_idx = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ bind->ops_idx = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ bind->bind_cb_idx = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ if( *str ) {
+ // Expected EOL, didn't get it :(
+ }
+ Log_Debug("UDI", "Parent bind - meta:%i,rgn:%i,ops:%i,bind:%i",
+ bind->meta_idx, bind->region_idx, bind->ops_idx, bind->bind_cb_idx);
+ break;
+ }
+ case UDIPROPS__internal_bind_ops:
+ {
+ // Get region using index
+ udi_index_t meta = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ udi_index_t rgn_idx = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+
+ // Search for region index (just in case the relevant 'region' comes after)
+ tUDI_PropRegion *rgn = &driver_module->RegionTypes[0];
+ if( rgn_idx > 0 )
+ {
+ rgn ++;
+ int j;
+ for( j = 1; j < next_unpop_region; j ++, rgn ++ ) {
+ if( rgn->RegionIdx == rgn_idx )
+ break;
+ }
+ if( j == next_unpop_region ) {
+ if( next_unpop_region == driver_module->nRegionTypes ) {
+ // TODO: warning if reigon types overflow
+ continue ;
+ }
+ next_unpop_region ++;
+ rgn->RegionIdx = rgn_idx;
+ }
+ }
+
+ // Set properties
+ rgn->BindMeta = meta;
+
+ rgn->PriBindOps = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ rgn->SecBindOps = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ rgn->BindCb = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ if( *str ) {
+ // TODO: Please sir, I want an EOL
+ }
+ break;
+ }
+ case UDIPROPS__child_bind_ops:
+ {
+ tUDI_BindOps *bind = &driver_module->ChildBindOps[child_bind_index++];
+ bind->meta_idx = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ bind->region_idx = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ bind->ops_idx = _get_token_idx(str, &str);
+ IF_ERROR(continue);
+ if( *str ) {
+ // Expected EOL, didn't get it :(
+ }
+ Log_Debug("UDI", "Child bind - meta:%i,rgn:%i,ops:%i",
+ bind->meta_idx, bind->region_idx, bind->ops_idx);
+ break;
+ }
+ case UDIPROPS__supplier:
+ case UDIPROPS__contact:
+ case UDIPROPS__name:
+ case UDIPROPS__shortname:
+ case UDIPROPS__release:
+ break;
+ //case UDIPROPS__requires:
+ // // TODO: Requires
+ // break;
+ case UDIPROPS__device:
+ {
+ int n_attr = 0;
+ // Count properties (and validate)
+ _get_token_uint16(str, &str); // message
+ IF_ERROR(continue);
+ _get_token_idx(str, &str); // meta
+ IF_ERROR(continue);
+ while( *str )
+ {
+ _get_token_str(str, &str, NULL);
+ IF_ERROR(break);
+ _get_token_sym(str, &str, true, "string", "ubit32", "boolean", "array", NULL);
+ IF_ERROR(break);
+ _get_token_str(str, &str, NULL);
+ IF_ERROR(break);
+ n_attr ++;
+ }
+ // Rewind and actually parse
+ // - Eat the 'device' token and hence reset 'str'
+ _get_token_str(udipropsptrs[i], &str, NULL);
+
+ tUDI_PropDevSpec *dev = NEW_wA(tUDI_PropDevSpec, Attribs, n_attr);
+ driver_module->Devices[device_index++] = dev;;
+ dev->MessageNum = _get_token_uint16(str, &str);
+ dev->MetaIdx = _get_token_idx(str, &str);
+ dev->nAttribs = n_attr;
+ n_attr = 0;
+ while( *str )
+ {
+ udi_instance_attr_list_t *at = &dev->Attribs[n_attr];
+ _get_token_str(str, &str, at->attr_name);
+ IF_ERROR(break);
+ at->attr_type = _get_token_sym(str, &str, true,
+ " ", "string", "array", "ubit32", "boolean", NULL);
+ IF_ERROR(break);
+ udi_ubit32_t val;
+ switch( dev->Attribs[n_attr].attr_type )
+ {
+ case 1: // String
+ at->attr_length = _get_token_str(str, &str, (char*)at->attr_value);
+ break;
+ case 2: // Array
+ // TODO: Array
+ Log_Warning("UDI", "TODO: Parse 'array' attribute in 'device'");
+ _get_token_str(str, &str, NULL);
+ error_hit = true;
+ break;
+ case 3: // ubit32
+ at->attr_length = sizeof(udi_ubit32_t);
+ val = _get_token_uint32(str, &str);
+ Log_Debug("UDI", "device %i: Value '%s'=%x", device_index,
+ at->attr_name, val);
+ UDI_ATTR32_SET(at->attr_value, val);
+ break;
+ case 4: // boolean
+ at->attr_length = sizeof(udi_boolean_t);
+ UDI_ATTR32_SET(at->attr_value, _get_token_bool(str, &str));
+ break;
+ }
+ IF_ERROR(break);
+ n_attr ++;
+ }
+
+ break;
+ }
+ default:
+ Log_Debug("UDI", "udipropsptrs[%i] = '%s'", i, udipropsptrs[i]);
+ break;