/** * Function oyStruct_IsObserved * @memberof oyObserver_s * @brief return object observation status * * Check if a object is observed by others. * * @param model model to ask * @param observer which observes that model * @return true or false * * @version Oyranos: 0.1.10 * @date 2009/10/28 * @since 2009/10/28 (Oyranos: 0.1.10) */ OYAPI int OYEXPORT oyStruct_IsObserved ( oyStruct_s * model, oyStruct_s * observer ) { int observed = 0; int i,n = 0; oyOption_s_ * o = 0; oyOptions_s_ * handles = (oyOptions_s_*) model->oy_->handles_; int error = 0; if(handles) n = oyStructList_Count( handles->list_ ); for(i = 0; i < n; ++i) { o = (oyOption_s_*) oyStructList_Get_( (oyStructList_s_*)(handles->list_), i ); if( oyStrcmp_( o->registration, OY_SIGNAL_OBSERVERS ) == 0) { if(observer) { oyStructList_s * observers = 0; int j_n,j; observers = (oyStructList_s*)oyOption_GetStruct( (oyOption_s*) o, oyOBJECT_STRUCT_LIST_S ); if(!error) { j_n = oyStructList_Count( observers ); for(j = 0; j < j_n; ++j) { oyObserver_s * obs; obs = (oyObserver_s*) oyStructList_GetType( observers, j, oyOBJECT_OBSERVER_S ); if(obs && obs->observer == observer) { observed = 1; break; } } } } else { observed = 1; break; } } } return observed; }
/** * @internal * Function oyOption_Match_ * @memberof oyOption_s * @brief two option key name matches * * A registration name match is not required. * * @version Oyranos: 0.1.8 * @since 2008/06/28 (Oyranos: 0.1.8) * @date 2008/06/28 */ int oyOption_Match_ ( oyOption_s_ * option_a, oyOption_s_ * option_b ) { int erg = 0; if( option_a && option_b ) { char * a = oyFilterRegistrationToText( option_a->registration, oyFILTER_REG_TYPE, 0 ); char * b = oyFilterRegistrationToText( option_b->registration, oyFILTER_REG_TYPE, 0 ); if( oyStrcmp_( a, b ) == 0 ) erg = 1; oyDeAllocateFunc_(a); oyDeAllocateFunc_(b); } return erg; }
/** Function oyFilterNode_SetContext_ * @memberof oyFilterNode_s * @brief Set module context in a filter * @internal * * The api4 data is passed to a interpolator specific transformer. The result * of this transformer will on request be cached by Oyranos as well. * * @param[in] node filter * @param[in,out] blob context to fill; expensive * @return error * * @version Oyranos: 0.9.6 * @date 2014/06/26 * @since 2008/11/02 (Oyranos: 0.1.8) */ int oyFilterNode_SetContext_( oyFilterNode_s_ * node, oyBlob_s_ * blob ) { int error = 0; oyFilterCore_s_ * core_ = node->core; if(error <= 0) { size_t size = 0; oyHash_s * hash4 = 0, /* public context provider */ * hash7 = 0; /* data processor part */ oyPointer ptr = 0; oyPointer_s * cmm_ptr4 = 0, * cmm_ptr7 = 0; /* Cache Search * 1. hash from input * 2. query for hash in cache * 3. check * 3a. eighter take cache entry * 3b. or ask CMM * 3b.1. update cache entry */ if(oy_debug && getenv("OY_DEBUG_WRITE")) { size = 0; ptr = oyFilterNode_TextToInfo_( node, &size, oyAllocateFunc_ ); if(ptr) oyWriteMemToFile_( "test_dbg_color.icc", ptr, size ); } /* 1. + 2. query in cache for api7 */ hash7 = oyFilterNode_GetHash_(node, 7); if(error <= 0) { /* select the module by option */ oyOption_s * ct = oyOptions_Find( node->core->options_, "////context", oyNAME_PATTERN ); const char * pattern = oyOption_GetValueString( ct, 0 ); if(pattern && !oyFilterRegistrationMatch( core_->registration_, pattern, 0 )) { oyMessageFunc_p( oyMSG_DBG, (oyStruct_s*) node, OY_DBG_FORMAT_ "create core from pattern: %s", OY_DBG_ARGS_, oyFilterNode_GetText( (oyFilterNode_s*)node,oyNAME_NICK) ); error = oyFilterNode_SetFromPattern_( node, 1, pattern ); if(error) { if(oyOption_GetFlags( ct ) & oyOPTIONATTRIBUTE_EDIT) { oyMessageFunc_p( oyMSG_WARN, (oyStruct_s*) node, OY_DBG_FORMAT_ "edited pattern not available: %d %s", OY_DBG_ARGS_, oyObject_GetId(ct->oy_), pattern ); error = 1; goto clean; } else error = 0; } else core_ = node->core; oyHash_Release( &hash7 ); hash7 = oyFilterNode_GetHash_(node, 7); } oyOption_Release( &ct ); ct = oyOptions_Find( node->core->options_, "////renderer", oyNAME_PATTERN ); pattern = oyOption_GetValueString( ct, 0 ); if(pattern && !oyFilterRegistrationMatch( node->api7_->registration, pattern, 0 )) { oyMessageFunc_p( oyMSG_DBG, (oyStruct_s*) node, OY_DBG_FORMAT_ "create node from pattern: %s", OY_DBG_ARGS_, oyFilterNode_GetText( (oyFilterNode_s*)node,oyNAME_NICK) ); error = oyFilterNode_SetFromPattern_( node, 0, pattern ); if(error) { if(oyOption_GetFlags( ct ) & oyOPTIONATTRIBUTE_EDIT) { error = 1; goto clean; } else error = 0; } else core_ = node->core; oyHash_Release( &hash7 ); hash7 = oyFilterNode_GetHash_(node, 7); } /* 3. check and 3.a take*/ cmm_ptr7 = (oyPointer_s*) oyHash_GetPointer( hash7, oyOBJECT_POINTER_S); if(!(cmm_ptr7 && oyPointer_GetPointer(cmm_ptr7)) || blob) { /* write the cmm4 context to memory */ if(blob) { if(oy_debug) error = oyOptions_SetFromString( &node->tags, "////verbose", "true", OY_CREATE_NEW ); /* oy_debug is used to obtain a complete data set */ ptr = oyFilterNode_ContextToMem_( node, &size, oyAllocateFunc_); oyBlob_SetFromData( (oyBlob_s*)blob, ptr, size, core_->api4_->context_type ); if(oy_debug) error = oyOptions_SetFromString( &node->tags, "////verbose", "false", 0 ); goto clean; } /* 2. query in cache for api4 */ hash4 = oyFilterNode_GetHash_(node, 4); cmm_ptr4 = (oyPointer_s*) oyHash_GetPointer( hash4, oyOBJECT_POINTER_S); if(!cmm_ptr4) { cmm_ptr4 = oyPointer_New(0); } if(!oyPointer_GetPointer(cmm_ptr4)) { size = 0; /* 3b. ask CMM */ ptr = oyFilterNode_ContextToMem_( node, &size, oyAllocateFunc_); if(!ptr || !size) { oyOption_s * ct = oyOptions_Find( core_->options_, "////context", oyNAME_PATTERN ); oyMessageFunc_p( oyMSG_DBG, (oyStruct_s*) node, OY_DBG_FORMAT_ "device link creation failed", OY_DBG_ARGS_); if(!(oyOption_GetFlags( ct ) & oyOPTIONATTRIBUTE_EDIT)) { char * pattern = oyFilterNode_GetFallback_( node, 1 ); oyMessageFunc_p( oyMSG_WARN, (oyStruct_s*) node, OY_DBG_FORMAT_ "create core from fallback: %s", OY_DBG_ARGS_, pattern ); error = oyFilterNode_SetFromPattern_( node, 1, pattern ); if(error) { error = 1; oyMessageFunc_p( oyMSG_ERROR, (oyStruct_s*) node, OY_DBG_FORMAT_ "no device link for caching\n%s", OY_DBG_ARGS_, oyFilterNode_GetText( (oyFilterNode_s*)node,oyNAME_NICK)); goto clean; } else core_ = node->core; ptr = oyFilterNode_ContextToMem_( node, &size, oyAllocateFunc_ ); oyFree_m_( pattern ); } if(!ptr || !size) { oyMessageFunc_p( oyMSG_ERROR, (oyStruct_s*) node, OY_DBG_FORMAT_ "no device link for caching\n%s", OY_DBG_ARGS_, oyFilterNode_GetText( (oyFilterNode_s*)node,oyNAME_NICK)); error = 1; oyPointer_Release( &cmm_ptr4 ); } else if(oy_debug) oyMessageFunc_p( oyMSG_WARN, (oyStruct_s*) node, OY_DBG_FORMAT_ "use fallback CMM\n%s", OY_DBG_ARGS_, oyFilterNode_GetText( (oyFilterNode_s*)node, oyNAME_NICK )); } if(!error) { /* 3b.1. update the hash as the CMM can change options */ hash4 = oyFilterNode_GetHash_( node, 4 ); oyPointer_Release( &cmm_ptr4 ); cmm_ptr4 = (oyPointer_s*) oyHash_GetPointer( hash4, oyOBJECT_POINTER_S); hash7 = oyFilterNode_GetHash_( node, 7 ); if(!cmm_ptr4) cmm_ptr4 = oyPointer_New(0); error = oyPointer_Set( cmm_ptr4, core_->api4_->id_, core_->api4_->context_type, ptr, "oyPointerRelease", oyPointerRelease); oyPointer_SetSize( cmm_ptr4, size ); /* 3b.2. update cmm4 cache entry */ error = oyHash_SetPointer( hash4, (oyStruct_s*) cmm_ptr4); } } if(error <= 0 && cmm_ptr4 && oyPointer_GetPointer(cmm_ptr4)) { if(node->backend_data && node->backend_data->release) node->backend_data->release( (oyStruct_s**)&node->backend_data); if( oyStrcmp_( node->api7_->context_type, core_->api4_->context_type ) != 0 ) { cmm_ptr7 = oyPointer_New(0); error = oyPointer_Set( cmm_ptr7, node->api7_->id_, node->api7_->context_type, 0, 0, 0); /* 3b.3. search for a convertor and convert */ oyPointer_ConvertData( cmm_ptr4, cmm_ptr7, (oyFilterNode_s*)node ); node->backend_data = cmm_ptr7; /* 3b.4. update cmm7 cache entry */ error = oyHash_SetPointer( hash7, (oyStruct_s*) cmm_ptr7); } else node->backend_data = oyPointer_Copy( cmm_ptr4, 0 ); } if(oy_debug && getenv("OY_DEBUG_WRITE")) { int id = oyFilterNode_GetId( (oyFilterNode_s*)node ); char * file_name = 0; oyAllocHelper_m_( file_name, char, 80, 0, return 1 ); sprintf( file_name, "dbg_color_dl-node[%d].icc", id ); if(ptr && size && node->backend_data) oyWriteMemToFile_( file_name, ptr, size ); oyFree_m_(file_name); } } else
/** Function oyConfigs_FromDeviceClass * @memberof oyConfigs_s * @brief Ask a module for device informations or other direct calls * * @param[in] device_type the device type ::oyFILTER_REG_TYPE, * defaults to OY_TYPE_STD (optional) * @param[in] device_class the device class, e.g. "monitor", * ::oyFILTER_REG_APPLICATION * @param[in] options options to pass to the module, for zero * the usage instructions are requested, * a option "device_name" can be used * as filter * @param[out] devices the devices * @param[in] object the optional object * @return 0 - good, >= 1 - error * * @verbatim // pass empty options to the module to get a usage message oyOptions_s * options = 0; int error = oyConfigs_FromDeviceClass( OY_TYPE_STD, "monitor", options, 0, 0 ); @endverbatim * * @version Oyranos: 0.1.10 * @since 2009/01/28 (Oyranos: 0.1.10) * @date 2009/01/30 */ OYAPI int OYEXPORT oyConfigs_FromDeviceClass ( const char * device_type, const char * device_class, oyOptions_s * options, oyConfigs_s ** devices, oyObject_s object ) { int error = !device_class || !device_class[0]; oyConfig_s * device = 0; oyConfigs_s * configs = 0; int i, j, j_n; uint32_t count = 0, * rank_list = 0; char ** texts = 0, * device_class_registration = 0; const char * tmp = 0, * device_name = 0; if(error > 0) { WARNc_S( "\n No device_class argument provided. Give up" ); return 0; } /** 1. obtain detailed and expensive device informations */ if(options) { options = oyOptions_Copy( options, 0 ); device_name = oyOptions_FindString( options, "device_name", 0 ); } /** 1.2.1 build a device class registration string */ if(error <= 0) { device_class_registration = oyDeviceRegistrationCreate_( device_type, device_class, device_name, device_class_registration ); error = !device_class_registration; } /** 1.2.2 get all device class module names */ if(error <= 0) error = oyConfigDomainList ( device_class_registration, &texts, &count, &rank_list, 0 ); if(devices && !*devices) *devices = oyConfigs_New( object ); /** 1.3 ask each module */ for( i = 0; i < count; ++i ) { const char * registration_domain = texts[i]; /** 1.3.1 call into module */ error = oyConfigs_FromDomain( registration_domain, options, &configs, object); if(devices && *devices) j_n = oyConfigs_Count( configs ); else j_n = 0; for( j = 0; j < j_n; ++j ) { device = oyConfigs_Get( configs, j ); if(device_name) { /** 1.3.1.1 Compare the device_name with the device_name option * and collect the matching devices. */ tmp = oyConfig_FindString( device, "device_name", 0 ); if(tmp && oyStrcmp_( tmp, device_name ) == 0) oyConfigs_MoveIn( *devices, &device, -1 ); } else /** 1.3.1.2 ... or collect all device configurations */ oyConfigs_MoveIn( *devices, &device, -1 ); oyConfig_Release( &device ); } oyConfigs_Release( &configs ); } if(devices) j_n = oyConfigs_Count( *devices ); else j_n = 0; for( j = 0; j < j_n; ++j ) { device = oyConfigs_Get( *devices, j ); /** The basic call on how to obtain the configuration is added here as * the objects name. "properties" and "list" are known. */ if(oyOptions_FindString( options, "command", "properties" ) || oyOptions_FindString( options, "oyNAME_DESCRIPTION", 0 )) oyObject_SetName( device->oy_, "properties", oyNAME_NAME ); else if(oyOptions_FindString( options, "list", 0 )) oyObject_SetName( device->oy_, "list", oyNAME_NAME ); oyConfig_Release( &device ); } oyOptions_Release( &options ); return error; }
/** * Function oyStruct_ObservationCount * @memberof oyObserver_s * @brief return the number of object<->model references * * The function lists by default (0) models and observers. Both * types are individually selectable in the flags. * * @param object which observes a model * @param flags select: * - 0 : all * - 1 : show observers count * - 2 : show models count * @return count * * @version Oyranos: 0.9.7 * @date 2018/10/04 * @since 2018/09/29 (Oyranos: 0.9.7) */ OYAPI int OYEXPORT oyStruct_ObservationCount ( oyStruct_s * object, uint32_t flags ) { int observed = 0; int i,n = 0; oyOption_s_ * o = NULL; oyOptions_s_ * handles = NULL; int error = 0; if(object && object->oy_) handles = (oyOptions_s_*) object->oy_->handles_; if(handles) n = oyStructList_Count( handles->list_ ); for(i = 0; i < n; ++i) { o = (oyOption_s_*) oyStructList_Get_( (oyStructList_s_*)(handles->list_), i ); if( (!flags || flags & 0x02) && oyStrcmp_( o->registration, OY_SIGNAL_MODELS ) == 0) { if(object) { oyStructList_s * models = 0; int j_n,j; models = (oyStructList_s*)oyOption_GetStruct( (oyOption_s*) o, oyOBJECT_STRUCT_LIST_S ); if(!error) { j_n = oyStructList_Count( models ); for(j = 0; j < j_n; ++j) { oyObserver_s * obs; obs = (oyObserver_s*) oyStructList_GetType( models, j, oyOBJECT_OBSERVER_S ); if(obs && obs->observer == object) ++observed; } } } } if( (!flags || flags & 0x01) && oyStrcmp_( o->registration, OY_SIGNAL_OBSERVERS ) == 0) { if(object) { oyStructList_s * observers = 0; int j_n,j; observers = (oyStructList_s*)oyOption_GetStruct( (oyOption_s*) o, oyOBJECT_STRUCT_LIST_S ); if(!error) { j_n = oyStructList_Count( observers ); for(j = 0; j < j_n; ++j) { oyObserver_s * obs; obs = (oyObserver_s*) oyStructList_GetType( observers, j, oyOBJECT_OBSERVER_S ); if(obs && obs->model == object) ++observed; } } } } } return observed; }
int DeviceAttributes_ ( ppd_file_t * ppd, oyOptions_s * options, oyConfig_s * device, const char * ppd_file_location ) { oyOption_s * o = 0; int error = !device; oyOption_s * value3 = oyOptions_Find( options, "device_context", oyNAME_PATTERN ); const char * device_name = oyConfig_FindString( device, "device_name", 0 ); if(!error) { char * manufacturer= 0, * model=0, * serial=0, * device_settings = 0; const char * system_port = 0, * host = 0; const char * keyword = 0; ppd_attr_t * attrs = 0; int attr_n, i, j; char ** color_key_words = 0, * tmp = 0; int color_key_words_n = 0; if(!device_name && !value3 && !ppd_file_location && !ppd) { message(oyMSG_WARN, (oyStruct_s*)options, _DBG_FORMAT_ "The \"device_name\" and \"device_context\" is\n" " missed to select a appropriate device.", _DBG_ARGS_ ); error = 1; return error; } if(!ppd) { message( oyMSG_DBG, (oyStruct_s*)0, _DBG_FORMAT_ "\n" "No PPD obtained for ", _DBG_ARGS_, device_name ); error = -1; return error; } manufacturer = ppd->manufacturer; model = ppd->modelname; serial = 0; /* Not known at this time. */ system_port = device_name; host = cupsServer(); attrs = ppdFindAttr(ppd, "cupsICCProfile", 0); if(attrs && attrs->text) device_settings = attrs->text; if(error <= 0) { size_t size = 0; char * data = 0; oyConfig_s * d = device; oyRankMap * rank_map = oyRankMapCopy( oyConfig_GetRankMap( device ), oyAllocateFunc_ ); if(!rank_map) rank_map = oyRankMapCopy( _api8.rank_map, oyAllocateFunc_ ); OPTIONS_ADD( oyConfig_GetOptions(d,"backend_core"), manufacturer ) OPTIONS_ADD( oyConfig_GetOptions(d,"backend_core"), model ) OPTIONS_ADD( oyConfig_GetOptions(d,"backend_core"), serial ) OPTIONS_ADD( oyConfig_GetOptions(d,"backend_core"), system_port ) OPTIONS_ADD( oyConfig_GetOptions(d,"backend_core"), host ) OPTIONS_ADD( oyConfig_GetOptions(d,"backend_core"), device_settings ) if (value3) { /* open the PPD data */ if(ppd_file_location) { FILE * fp = fopen( ppd_file_location, "r" ); size_t lsize = 0; /* Find the total size. */ fseek(fp , 0, SEEK_END); lsize = ftell(fp); rewind (fp); /* Create buffer to read contents into a profile. */ data = (char*) malloc (sizeof(char)*lsize + 1); if (data == NULL) fputs ("Unable to open PPD size.",stderr); size = fread( data, 1, lsize, fp); data[size] = 0; } if(!error && data && size) { o = oyOption_FromRegistration( CMM_BASE_REG OY_SLASH "device_context.PPD.text", 0 ); error = !o; if(!error) error = oyOption_SetFromData( o, data, size ); if(!error) oyOptions_MoveIn( *oyConfig_GetOptions(device,"data"), &o, -1 ); } } /* Collect all ColorKeyWords. */ attr_n = ppd->num_attrs; for(i = 0; i < attr_n; i++) { char key[16]; keyword = ppd->attrs[i]->name; /* we support keys beginning with ColorKeyWords, e.g. "ColorKeyWords" "ColorKeyWords" ... */ snprintf( &key[0], 16, "%s", keyword ); key[14] = 0; if (strcmp(key, "ColorKeyWords") == 0) { if( tmp && tmp[oyStrlen_(tmp) - 1] != ';' ) STRING_ADD( tmp, ";" ); STRING_ADD( tmp, ppd->attrs[i]->value ); } } if(tmp) { color_key_words = oyStringSplit( tmp, ';', &color_key_words_n, oyAllocateFunc_); oyDeAllocateFunc_( tmp ); tmp = 0; } /* add the key/value pairs to the devices backend_core options. */ for(j = 0; j < color_key_words_n; ++j) { const char * keyword = color_key_words[j], * value = NULL; ppd_choice_t * c = ppdFindMarkedChoice( ppd, keyword ); ppd_option_t * o = ppdFindOption( ppd, keyword ); char * reg_name = 0; /* take the marked choice */ if(c) value = c->choice; /* fall back to a default */ else if(o) value = o->defchoice; else /* Scan PPD attributes for matching the ColorKeyWords and */ for(i = 0; i < attr_n; i++) if(oyStrcmp_( ppd->attrs[i]->name, keyword ) == 0) value = ppd->attrs[i]->value; STRING_ADD( reg_name, CMM_BASE_REG OY_SLASH ); STRING_ADD( reg_name, keyword ); if(value) { error= oyOptions_SetFromText( oyConfig_GetOptions(d,"backend_core"), reg_name, value, OY_CREATE_NEW ); oyRankMapAppend( &rank_map, reg_name, 2, -2, 0, 0,0 ); } if(reg_name) oyDeAllocateFunc_( reg_name ); reg_name = 0; } if( color_key_words && color_key_words_n) oyStringListRelease_( &color_key_words, color_key_words_n, oyDeAllocateFunc_ ); else { ppd_option_t * o; while((o = ppdNextOption(ppd)) != 0) { const char * value = 0; char * reg_name = 0; keyword = o->keyword; STRING_ADD( reg_name, CMM_BASE_REG OY_SLASH ); STRING_ADD( reg_name, keyword ); /* take the marked choice */ for(i = 0; i < o->num_choices; ++i) if(o->choices[i].marked) { value = o->choices[i].choice; break; } if(!value) value = o->defchoice; if(value) { error = oyOptions_SetFromText( oyConfig_GetOptions(d,"backend_core"), reg_name, value, OY_CREATE_NEW ); oyRankMapAppend( &rank_map, reg_name, 2, -2, 0, 0,0 ); } if(reg_name) oyDeAllocateFunc_( reg_name ); reg_name = 0; } } oyConfig_SetRankMap( device, rank_map ); oyRankMapRelease( &rank_map, oyDeAllocateFunc_ ); }
/** * @internal * Function oyOption_SetFromText_ * @memberof oyOption_s * @brief set a option value from a string * * @param obj the option * @param text the text to set * @param flags possible is OY_STRING_LIST * @return 0 - success, 1 - error * * @version Oyranos: 0.1.9 */ int oyOption_SetFromText_ ( oyOption_s_ * obj, const char * text, uint32_t flags ) { int error = !obj; char ** list = 0; int n = 0; if(error <= 0) { /* ignore the special case of assigning the same string twice. */ if(obj->value && obj->value_type == oyVAL_STRING && obj->value->string == text) return error; if(obj->value) { oyDeAlloc_f deallocateFunc = obj->oy_->deallocateFunc_; if( text ) { int j = 0; if( obj->value_type == oyVAL_STRING && obj->value->string ) { if(oyStrcmp_(text, obj->value->string) == 0) return error; } if( obj->value_type == oyVAL_STRING_LIST && obj->value->string_list ) while(obj->value->string_list[j]) { const char * value = obj->value->string_list[j]; if(value && oyStrcmp_(value, text)) return error; ++j; } } oyValueRelease( &obj->value, obj->value_type, deallocateFunc ); } obj->value = obj->oy_->allocateFunc_(sizeof(oyValue_u)); memset( obj->value, 0, sizeof(oyValue_u) ); if(oyToStringList_m(flags)) { /** Split for flags & OY_STRING_LIST at newline. */ list = oyStringSplit_( text, '\n', &n, obj->oy_->allocateFunc_ ); obj->value->string_list = list; list = 0; obj->value_type = oyVAL_STRING_LIST; } else { if(text) obj->value->string = oyStringCopy_( text, obj->oy_->allocateFunc_ ); obj->value_type = oyVAL_STRING; } obj->flags |= oyOPTIONATTRIBUTE_EDIT; oyStruct_ObserverSignal( (oyStruct_s*)obj, oySIGNAL_DATA_CHANGED, 0 ); } return error; }
/** @internal * Function oyXML2XFORMsCmdLineSelect1Handler * @brief build a UI for a xf:select1 XFORMS sequence * * This function is a simple demonstration. * * @param[in] cur libxml2 node * @param[in] collected_elements parsed and requested elements * @param[in] user_data toolkit context * @return error * * @version Oyranos: 0.1.10 * @since 2009/08/29 (Oyranos: 0.1.10) * @date 2009/09/04 */ int oyXML2XFORMsCmdLineSelect1Handler( xmlNodePtr cur, oyOptions_s * collected_elements, oyPointer user_data ) { int is_default, choices_n = 0; const char * default_value = 0, * tmp, * label, * value, * help, * xpath = 0; char * default_key = 0, *key = 0; oyFormsArgs_s * forms_args = user_data; int print = forms_args ? forms_args->print : 1; xmlNodePtr select1, choices = 0, items; if(oy_debug && default_value && print) printf( "found default: \"%s\"\n", default_value ); if(cur) { if(oyXMLNodeNameIs(cur, "xf:select1")) { select1 = cur->children; default_value = oyXFORMsModelGetXPathValue( cur, "ref", &xpath ); } else select1 = 0; while(select1) { if(oyXMLNodeNameIs( select1, "xf:label") && print) printf( " %s:\n", oyXML2NodeValue(select1) ); else if(oyXMLNodeNameIs( select1, "xf:help") && print & 0x02) { printf( " [%s]\n", oyXML2NodeValue(select1) ); } else { if(oyXMLNodeNameIs(select1, "xf:choices")) choices = select1->children; else choices = 0; } while(choices) { label = tmp = value = help = 0; is_default = 0; if(oyXMLNodeNameIs( choices, "xf:item")) items = choices->children; else items = 0; while(items) { if(oyXMLNodeNameIs( items, "xf:label") && print) label = oyXML2NodeValue( items ); if(oyXMLNodeNameIs( items, "xf:value") && print) value = oyXML2NodeValue( items ); if(oyXMLNodeNameIs( items, "xf:help") && print) help = oyXML2NodeValue( items ); items = items->next; } if(value || label) { /* detect default */ if(value && default_value && oyStrcmp_(default_value,value) == 0) { is_default = 1; } if(!value) value = label; if(!label) label = value; /* append the choice * store the label and value in user_data() for evaluating results*/ if(print & 0x04) { tmp = 0; if(print & 0x02) tmp = label; help = tmp?help? (strstr(help,tmp) ? &help[strlen(tmp)] : help):"":""; printf( " --%s=\"%s\"%s%s%s%s%s%s\n", xpath+1, oyNoEmptyString_m_(value), is_default ? " *":"", tmp ? " [" : "", tmp?tmp:"", (help && strlen(help))?": ":"", help, tmp?"]":"" ); } if( !(print & 0x02) && !(print & 0x04) && is_default ) printf( " --%s=\"%s\"\n", xpath+1, oyNoEmptyString_m_(value) ); ++choices_n; } choices = choices->next; } select1 = select1->next; } } /* collect results */ if(xpath && forms_args) oyOptions_SetFromText( (oyOptions_s**)&forms_args->xforms_data_model_, xpath+1, default_value, OY_CREATE_NEW ); if(default_key) oyFree_m_( default_key ); if(key) oyFree_m_( key ); /*printf("collected:\n%s", oyOptions_GetText( collected_elements, oyNAME_NICK));*/ return 0; }