mirror of https://github.com/ecmwf/eccodes.git
169 lines
4.5 KiB
C
169 lines
4.5 KiB
C
/*
|
|
* Copyright 2005-2018 ECMWF.
|
|
*
|
|
* This software is licensed under the terms of the Apache Licence Version 2.0
|
|
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
*
|
|
* In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
|
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
|
*/
|
|
|
|
/*
|
|
* Description: concept index
|
|
*
|
|
*/
|
|
|
|
#include "grib_api_internal.h"
|
|
|
|
static grib_concept_index_entry* index_entry_new(grib_context* c,grib_concept_index_keys* keys) {
|
|
grib_concept_index_entry* entry=NULL;
|
|
|
|
Assert(keys);
|
|
|
|
if (!c) c=grib_context_get_default();
|
|
|
|
entry=grib_context_malloc_clear(c,sizeof(grib_concept_index_entry));
|
|
if (!entry)
|
|
grib_context_log(c,GRIB_LOG_FATAL,"grib_concept_index_entry unable to allocate");
|
|
e=entry;
|
|
|
|
while (keys && keys->name) {
|
|
e->name=grib_context_strdup(c,keys->name);
|
|
e->type=keys->type;
|
|
e->next=grib_context_malloc_clear(c,sizeof(grib_concept_index_entry));
|
|
if (!e->next)
|
|
grib_context_log(c,GRIB_LOG_FATAL,"grib_concept_index_entry unable to allocate");
|
|
|
|
e=e->next;
|
|
keys=keys->next;
|
|
}
|
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
static void index_entry_delete(grib_context* c,grib_concept_index_entry* entry) {
|
|
grib_concept_index_entry* e;
|
|
while (entry) {
|
|
e=entry;
|
|
entry=entry->next;
|
|
grib_context_free(c,e->name);
|
|
grib_context_free(c,e->value);
|
|
grib_context_free(c,e);
|
|
}
|
|
}
|
|
|
|
static int index_insert_entry(grib_concept_index* index,grib_concept_index_entry* entry,void* object) {
|
|
|
|
int err=0;
|
|
int found=0;
|
|
grib_conditions_tree* cur=index->conditions;
|
|
grib_conditions_tree* prev=index->conditions;
|
|
grib_concept_index_keys* keys=index->keys;
|
|
|
|
while (keys->name) {
|
|
|
|
if (!cur) {
|
|
cur=grib_context_malloc_clear_persistent(index->context,sizeof(grib_conditions_tree));
|
|
if (!cur)
|
|
grib_context_log(index->context,GRIB_LOG_FATAL,"index_insert_entry unable to allocate");
|
|
prev->next=cur;
|
|
}
|
|
value = entry->value ? entry->value : "*";
|
|
while (cur && (!cur->value || (found=!strcmp(cur->value,value))==0) ) cur=cur->next;
|
|
|
|
if (!found) {
|
|
cur->next=grib_context_malloc_clear_persistent(index->context,sizeof(grib_conditions_tree));
|
|
if (!cur->next)
|
|
grib_context_log(index->context,GRIB_LOG_FATAL,"index_insert_entry unable to allocate");
|
|
cur=cur->next;
|
|
}
|
|
|
|
cur->value=grib_context_strdup(index->context,value);
|
|
entry=entry->next;
|
|
keys=keys->next;
|
|
prev=cur;
|
|
cur=cur->next_key;
|
|
}
|
|
|
|
while (cur) {
|
|
prev=cur;
|
|
cur=cur->next_key;
|
|
}
|
|
|
|
prev->object=object;
|
|
|
|
return err;
|
|
}
|
|
|
|
static void index_add_conditions(grib_concept_index* index,grib_concept_condition* condition) {
|
|
grib_concept_condition* c=condition;
|
|
char s[512]={0,};
|
|
grib_concept_index_entry* e;;
|
|
grib_concept_index_entry* entry=index_entry_new(index->context,index->keys);;
|
|
|
|
while (c) {
|
|
size_t size=512;
|
|
int type;
|
|
e=entry;
|
|
type = grib_expression_native_type(0,c->expression);
|
|
switch(type)
|
|
{
|
|
case GRIB_TYPE_LONG:
|
|
grib_expression_evaluate_long(0,c->expression,&lres);
|
|
sprintf(s,"%ld",lres);
|
|
break;
|
|
|
|
case GRIB_TYPE_DOUBLE:
|
|
grib_expression_evaluate_double(0,c->expression,&dres);
|
|
sprintf(s,"%g",dres);
|
|
break;
|
|
|
|
case GRIB_TYPE_STRING:
|
|
grib_expression_evaluate_string(0,c->expression,s,&size,&err);
|
|
break;
|
|
|
|
default:
|
|
Assert(0);
|
|
break;
|
|
}
|
|
|
|
while (e->name && strcmp(e->name,c->name))
|
|
e=e->next;
|
|
|
|
e->type=type;
|
|
e->value=grib_context_strdup(index->context,s);
|
|
if (!e->name) {
|
|
e->name=grib_context_strdup(index->context,c->name);
|
|
e->next=grib_context_malloc_clear_persistent(index->context,sizeof(grib_concept_index_entry));
|
|
if (!e->next)
|
|
grib_context_log(index->context,GRIB_LOG_FATAL,"index_add_conditions unable to allocate");
|
|
}
|
|
|
|
c=c->next;
|
|
}
|
|
|
|
index_insert_entry(index,entry,condition->name);
|
|
|
|
index_entry_delete(index->context,entry);
|
|
}
|
|
|
|
grib_concept_index* grib_concept_index_new_from_concept(grib_context* c,grib_concept_value* concept,int *err) {
|
|
grib_concept_index* index;
|
|
|
|
if (!c) c=grib_context_get_default();
|
|
|
|
index=grib_context_malloc_clear_persistent(c,sizeof(grib_concept_index));
|
|
index->keys=grib_context_malloc_clear_persistent(c,sizeof(grib_concept_index_key));
|
|
index->conditions=grib_context_malloc_clear_persistent(c,sizeof(grib_conditions_tree));
|
|
index->conditions=grib_context_malloc_clear_persistent(c,sizeof(grib_conditions_tree));
|
|
index->context=c;
|
|
|
|
while (concept) {
|
|
index_add_conditions(index,concept->conditions,err);
|
|
concept=concept->next;
|
|
}
|
|
|
|
return index;
|
|
}
|