EVOLUTION-MANAGER
Edit File: param.cpp
/* put parameters in linked list and retrieve */ #include <ctype.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "proj.h" #include "proj_internal.h" static void unquote_string(char* param_str) { size_t len = strlen(param_str); // Remove leading and terminating spaces after equal sign const char* equal = strstr(param_str, "=\""); if( equal && equal - param_str + 1 > 2 && param_str[len-1] == '"' ) { size_t dst = equal + 1 - param_str; size_t src = dst + 1; for( ; param_str[src]; dst++, src++) { if( param_str[src] == '"' ) { if( param_str[src+1] == '"' ) { src++; } else { break; } } param_str[dst] = param_str[src]; } param_str[dst] = '\0'; } } /* create parameter list entry */ paralist *pj_mkparam(const char *str) { paralist *newitem; if((newitem = (paralist *)pj_malloc(sizeof(paralist) + strlen(str))) != nullptr) { newitem->used = 0; newitem->next = nullptr; if (*str == '+') ++str; (void)strcpy(newitem->param, str); unquote_string(newitem->param); } return newitem; } /* As pj_mkparam, but payload ends at first whitespace, rather than at end of <str> */ paralist *pj_mkparam_ws (const char *str, const char **next_str) { paralist *newitem; size_t len = 0; if (nullptr==str) return nullptr; /* Find start and length of string */ while (isspace (*str)) str++; if (*str == '+') str++; bool in_string = false; for( ; str[len] != '\0'; len++ ) { if( in_string ) { if( str[len] == '"' && str[len+1] == '"' ) { len++; } else if( str[len] == '"' ) { in_string = false; } } else if( str[len] == '=' && str[len+1] == '"' ) { in_string = true; } else if( isspace(str[len]) ) { break; } } if( next_str ) *next_str = str + len; /* Use calloc to automagically 0-terminate the copy */ newitem = (paralist *) pj_calloc (1, sizeof(paralist) + len + 1); if (nullptr==newitem) return nullptr; memmove(newitem->param, str, len); unquote_string(newitem->param); newitem->used = 0; newitem->next = nullptr; return newitem; } /**************************************************************************************/ paralist *pj_param_exists (paralist *list, const char *parameter) { /*************************************************************************************** Determine whether a given parameter exists in a paralist. If it does, return a pointer to the corresponding list element - otherwise return 0. In support of the pipeline syntax, the search is terminated once a "+step" list element is reached, in which case a 0 is returned, unless the parameter searched for is actually "step", in which case a pointer to the "step" list element is returned. This function is equivalent to the pj_param (...) call with the "opt" argument set to the parameter name preceeeded by a 't'. But by using this one, one avoids writing the code allocating memory for a new copy of parameter name, and prepending the t (for compile time known names, this is obviously not an issue). ***************************************************************************************/ paralist *next = list; const char *c = strchr (parameter, '='); size_t len = strlen (parameter); if (c) len = c - parameter; if (list==nullptr) return nullptr; for (next = list; next; next = next->next) { if (0==strncmp (parameter, next->param, len) && (next->param[len]=='=' || next->param[len]==0)) { next->used = 1; return next; } if (0==strcmp (parameter, "step")) return nullptr; } return nullptr; } /************************************************************************/ /* pj_param() */ /* */ /* Test for presence or get parameter value. The first */ /* character in `opt' is a parameter type which can take the */ /* values: */ /* */ /* `t' - test for presence, return TRUE/FALSE in PROJVALUE.i */ /* `i' - integer value returned in PROJVALUE.i */ /* `d' - simple valued real input returned in PROJVALUE.f */ /* `r' - degrees (DMS translation applied), returned as */ /* radians in PROJVALUE.f */ /* `s' - string returned in PROJVALUE.s */ /* `b' - test for t/T/f/F, return in PROJVALUE.i */ /* */ /* Search is terminated when "step" is found, in which case */ /* 0 is returned, unless "step" was the target searched for. */ /* */ /************************************************************************/ PROJVALUE pj_param (projCtx ctx, paralist *pl, const char *opt) { int type; unsigned l; PROJVALUE value = {0}; if ( ctx == nullptr ) ctx = pj_get_default_ctx(); type = *opt++; if (nullptr==strchr ("tbirds", type)) { fprintf(stderr, "invalid request to pj_param, fatal\n"); exit(1); } pl = pj_param_exists (pl, opt); if (type == 't') { value.i = pl != nullptr; return value; } /* Not found */ if (nullptr==pl) { /* Return value after the switch, so that the return path is */ /* taken in all cases */ switch (type) { case 'b': case 'i': value.i = 0; break; case 'd': case 'r': value.f = 0.; break; case 's': value.s = nullptr; break; } return value; } /* Found parameter - now find its value */ pl->used |= 1; l = (int) strlen(opt); opt = pl->param + l; if (*opt == '=') ++opt; switch (type) { case 'i': /* integer input */ value.i = atoi(opt); break; case 'd': /* simple real input */ value.f = pj_atof(opt); break; case 'r': /* degrees input */ value.f = dmstor_ctx(ctx, opt, nullptr); break; case 's': /* char string */ value.s = (char *) opt; break; case 'b': /* boolean */ switch (*opt) { case 'F': case 'f': value.i = 0; break; case '\0': case 'T': case 't': value.i = 1; break; default: pj_ctx_set_errno (ctx, PJD_ERR_INVALID_BOOLEAN_PARAM); value.i = 0; break; } break; } return value; }