1cdef extern from * nogil: 2 3 ctypedef struct _n_PetscOptions 4 ctypedef _n_PetscOptions* PetscOptions 5 6 PetscErrorCode PetscOptionsCreate(PetscOptions*) 7 PetscErrorCode PetscOptionsDestroy(PetscOptions*) 8 PetscErrorCode PetscOptionsView(PetscOptions, PetscViewer) 9 PetscErrorCode PetscOptionsClear(PetscOptions) 10 11 PetscErrorCode PetscOptionsPrefixPush(PetscOptions, char[]) 12 PetscErrorCode PetscOptionsPrefixPop(PetscOptions) 13 14 PetscErrorCode PetscOptionsHasName(PetscOptions, char[], char[], PetscBool*) 15 PetscErrorCode PetscOptionsUsed(PetscOptions, char[], PetscBool*) 16 PetscErrorCode PetscOptionsSetAlias(PetscOptions, char[], char[]) 17 PetscErrorCode PetscOptionsSetValue(PetscOptions, char[], char[]) 18 PetscErrorCode PetscOptionsClearValue(PetscOptions, char[]) 19 20 PetscErrorCode PetscOptionsInsertString(PetscOptions, char[]) 21 PetscErrorCode PetscOptionsInsertFile(PetscOptions, char[]) 22 PetscErrorCode PetscOptionsGetAll(PetscOptions, char*[]) 23 24 PetscErrorCode PetscOptionsGetBool(PetscOptions, char[], char[], PetscBool*, PetscBool*) 25 PetscErrorCode PetscOptionsGetBoolArray(PetscOptions, char[], char[], PetscBool[], PetscInt*, PetscBool*) 26 PetscErrorCode PetscOptionsGetInt(PetscOptions, char[], char[], PetscInt*, PetscBool*) 27 PetscErrorCode PetscOptionsGetIntArray(PetscOptions, char[], char[], PetscInt[], PetscInt*, PetscBool*) 28 PetscErrorCode PetscOptionsGetReal(PetscOptions, char[], char[], PetscReal*, PetscBool*) 29 PetscErrorCode PetscOptionsGetRealArray(PetscOptions, char[], char[], PetscReal[], PetscInt*, PetscBool*) 30 PetscErrorCode PetscOptionsGetScalar(PetscOptions, char[], char[], PetscScalar*, PetscBool*) 31 PetscErrorCode PetscOptionsGetScalarArray(PetscOptions, char[], char[], PetscScalar[], PetscInt*, PetscBool*) 32 PetscErrorCode PetscOptionsGetString(PetscOptions, char[], char[], char[], size_t, PetscBool*) 33 34 ctypedef struct _p_PetscToken 35 ctypedef _p_PetscToken* PetscToken 36 PetscErrorCode PetscTokenCreate(char[], char, PetscToken*) 37 PetscErrorCode PetscTokenDestroy(PetscToken*) 38 PetscErrorCode PetscTokenFind(PetscToken, const char*[]) 39 PetscErrorCode PetscOptionsValidKey(char[], PetscBool*) 40 41# 42 43cdef getprefix(prefix, deft=None): 44 if prefix is None: 45 prefix = deft 46 elif isinstance(prefix, Options): 47 prefix = prefix.prefix 48 elif isinstance(prefix, Object): 49 prefix = prefix.getOptionsPrefix() 50 elif not isinstance(prefix, str): 51 raise TypeError('option prefix must be string') 52 if not prefix: 53 return None 54 if prefix.count(' '): 55 raise ValueError('option prefix should not have spaces') 56 if prefix.startswith('-'): 57 raise ValueError('option prefix should not start with a hyphen') 58 return prefix 59 60# 61 62cdef opt2str(const char *pre, const char *name): 63 p = bytes2str(pre) if pre!=NULL else None 64 n = bytes2str(name) if name[0]!=c'-' else bytes2str(&name[1]) 65 return '(prefix:%s, name:%s)' % (p, n) 66 67cdef getopt_Bool(PetscOptions opt, const char *pre, const char *name, object deft): 68 cdef PetscBool value = PETSC_FALSE 69 cdef PetscBool flag = PETSC_FALSE 70 CHKERR(PetscOptionsGetBool(opt, pre, name, &value, &flag)) 71 if flag==PETSC_TRUE: return toBool(value) 72 if deft is not None: return toBool(asBool(deft)) 73 raise KeyError(opt2str(pre, name)) 74 75cdef getopt_BoolArray(PetscOptions opt, const char *pre, const char *name, object deft): 76 cdef PetscBool value[1024], *ivalue = value, *ivaluedeft = NULL 77 cdef PetscInt nmax = 1024, ndeft = 0 78 cdef PetscBool flag = PETSC_FALSE 79 cdef object unused 80 if deft is not None: 81 deft = [toBool(asBool(d)) for d in deft] 82 deft = iarray_b(deft, &ndeft, &ivaluedeft) 83 if ndeft > nmax: 84 unused = oarray_b(empty_b(ndeft), &nmax, &ivalue) 85 memcpy(ivalue, ivaluedeft, <size_t>ndeft*sizeof(PetscBool)) 86 CHKERR(PetscOptionsGetBoolArray(opt, pre, name, ivalue, &nmax, &flag)) 87 if flag==PETSC_TRUE: return array_b(nmax, ivalue).astype('bool') 88 if deft is not None: return deft.astype('bool') 89 raise KeyError(opt2str(pre, name)) 90 91cdef getopt_Int(PetscOptions opt, const char *pre, const char *name, object deft): 92 cdef PetscInt value = 0 93 cdef PetscBool flag = PETSC_FALSE 94 CHKERR(PetscOptionsGetInt(opt, pre, name, &value, &flag)) 95 if flag==PETSC_TRUE: return toInt(value) 96 if deft is not None: return toInt(asInt(deft)) 97 raise KeyError(opt2str(pre, name)) 98 99cdef getopt_IntArray(PetscOptions opt, const char *pre, const char *name, object deft): 100 cdef PetscInt value[1024], *ivalue = value, *ivaluedeft = NULL 101 cdef PetscInt nmax = 1024, ndeft = 0 102 cdef PetscBool flag = PETSC_FALSE 103 cdef object unused 104 if deft is not None: 105 deft = iarray_i(deft, &ndeft, &ivaluedeft) 106 if ndeft > nmax: 107 unused = oarray_i(empty_i(ndeft), &nmax, &ivalue) 108 memcpy(ivalue, ivaluedeft, <size_t>ndeft*sizeof(PetscInt)) 109 CHKERR(PetscOptionsGetIntArray(opt, pre, name, ivalue, &nmax, &flag)) 110 if flag==PETSC_TRUE: return array_i(nmax, ivalue) 111 if deft is not None: return deft 112 raise KeyError(opt2str(pre, name)) 113 114cdef getopt_Real(PetscOptions opt, const char *pre, const char *name, object deft): 115 cdef PetscReal value = 0 116 cdef PetscBool flag = PETSC_FALSE 117 CHKERR(PetscOptionsGetReal(opt, pre, name, &value, &flag)) 118 if flag==PETSC_TRUE: return toReal(value) 119 if deft is not None: return toReal(asReal(deft)) 120 raise KeyError(opt2str(pre, name)) 121 122cdef getopt_RealArray(PetscOptions opt, const char *pre, const char *name, object deft): 123 cdef PetscReal value[1024], *ivalue = value, *ivaluedeft = NULL 124 cdef PetscInt nmax = 1024, ndeft = 0 125 cdef PetscBool flag = PETSC_FALSE 126 cdef object unused 127 if deft is not None: 128 deft = iarray_r(deft, &ndeft, &ivaluedeft) 129 if ndeft > nmax: 130 unused = oarray_r(empty_r(ndeft), &nmax, &ivalue) 131 memcpy(ivalue, ivaluedeft, <size_t>ndeft*sizeof(PetscReal)) 132 CHKERR(PetscOptionsGetRealArray(opt, pre, name, ivalue, &nmax, &flag)) 133 if flag==PETSC_TRUE: return array_r(nmax, ivalue) 134 if deft is not None: return deft 135 raise KeyError(opt2str(pre, name)) 136 137cdef getopt_Scalar(PetscOptions opt, const char *pre, const char *name, object deft): 138 cdef PetscScalar value = 0 139 cdef PetscBool flag = PETSC_FALSE 140 CHKERR(PetscOptionsGetScalar(opt, pre, name, &value, &flag)) 141 if flag==PETSC_TRUE: return toScalar(value) 142 if deft is not None: return toScalar(asScalar(deft)) 143 raise KeyError(opt2str(pre, name)) 144 145cdef getopt_ScalarArray(PetscOptions opt, const char *pre, const char *name, object deft): 146 cdef PetscScalar value[1024], *ivalue = value, *ivaluedeft = NULL 147 cdef PetscInt nmax = 1024, ndeft = 0 148 cdef PetscBool flag = PETSC_FALSE 149 cdef object unused 150 if deft is not None: 151 deft = iarray_s(deft, &ndeft, &ivaluedeft) 152 if ndeft > nmax: 153 unused = oarray_s(empty_s(ndeft), &nmax, &ivalue) 154 memcpy(ivalue, ivaluedeft, <size_t>ndeft*sizeof(PetscScalar)) 155 CHKERR(PetscOptionsGetScalarArray(opt, pre, name, ivalue, &nmax, &flag)) 156 if flag==PETSC_TRUE: return array_s(nmax, ivalue) 157 if deft is not None: return deft 158 raise KeyError(opt2str(pre, name)) 159 160cdef getopt_String(PetscOptions opt, const char *pre, const char *name, object deft): 161 cdef char value[1024+1] 162 cdef PetscBool flag = PETSC_FALSE 163 CHKERR(PetscOptionsGetString(opt, pre, name, value, 1024, &flag)) 164 if flag==PETSC_TRUE: return bytes2str(value) 165 if deft is not None: return str(deft) 166 raise KeyError(opt2str(pre, name)) 167 168cdef enum PetscOptType: 169 OPT_BOOL 170 OPT_BOOLARRAY 171 OPT_INT 172 OPT_INTARRAY 173 OPT_REAL 174 OPT_REALARRAY 175 OPT_SCALAR 176 OPT_SCALARARRAY 177 OPT_STRING 178 179cdef getpair(prefix, name, const char **pr, const char **nm): 180 # -- 181 cdef const char *p = NULL 182 prefix = str2bytes(prefix, &p) 183 if p != NULL and p[0] == c'-': 184 p = &p[1] 185 # -- 186 cdef const char *n = NULL 187 name = str2bytes(name, &n) 188 if n != NULL and n[0] != c'-': 189 name = b'-' + name 190 name = str2bytes(name, &n) 191 # -- 192 pr[0] = p 193 nm[0] = n 194 return (prefix, name) 195 196cdef getopt(PetscOptions opt, PetscOptType otype, prefix, name, deft): 197 cdef const char *pr = NULL 198 cdef const char *nm = NULL 199 cdef object unused = getpair(prefix, name, &pr, &nm) 200 if otype == OPT_BOOL : return getopt_Bool (opt, pr, nm, deft) 201 if otype == OPT_BOOLARRAY : return getopt_BoolArray (opt, pr, nm, deft) 202 if otype == OPT_INT : return getopt_Int (opt, pr, nm, deft) 203 if otype == OPT_INTARRAY : return getopt_IntArray (opt, pr, nm, deft) 204 if otype == OPT_REAL : return getopt_Real (opt, pr, nm, deft) 205 if otype == OPT_REALARRAY : return getopt_RealArray (opt, pr, nm, deft) 206 if otype == OPT_SCALAR : return getopt_Scalar (opt, pr, nm, deft) 207 if otype == OPT_SCALARARRAY : return getopt_ScalarArray (opt, pr, nm, deft) 208 if otype == OPT_STRING : return getopt_String (opt, pr, nm, deft) 209 210 211# simple minded options parser 212 213cdef tokenize(options): 214 cdef PetscToken t = NULL 215 cdef const char *s = NULL 216 cdef const char *p = NULL 217 options = str2bytes(options, &s) 218 cdef list tokens = [] 219 CHKERR(PetscTokenCreate(s, c' ', &t)) 220 try: 221 CHKERR(PetscTokenFind(t, <const char**>&p)) 222 while p != NULL: 223 tokens.append(bytes2str(p)) 224 CHKERR(PetscTokenFind(t, <const char**>&p)) 225 finally: 226 CHKERR(PetscTokenDestroy(&t)) 227 return tokens 228 229cdef bint iskey(key): 230 cdef const char *k = NULL 231 cdef PetscBool b = PETSC_FALSE 232 if key: 233 key = str2bytes(key, &k) 234 CHKERR(PetscOptionsValidKey(k, &b)) 235 if b == PETSC_TRUE: 236 return True 237 return False 238 239cdef gettok(tokens): 240 if tokens: 241 return tokens.pop(0) 242 else: 243 return None 244 245cdef getkey(key, prefix): 246 if not iskey(key): 247 return None 248 key = key[1:] 249 if key[0] == '-': 250 key = key[1:] 251 if not key.startswith(prefix): 252 return None 253 return key.replace(prefix, '', 1) 254 255cdef parseopt(options, prefix): 256 if isinstance(options, str): 257 tokens = tokenize(options) 258 else: 259 tokens = list(options) 260 prefix = prefix or '' 261 # parser loop 262 opts = {} 263 first = gettok(tokens) 264 while first: 265 key = getkey(first, prefix) 266 if not key: 267 first = gettok(tokens) 268 else: 269 second = gettok(tokens) 270 if getkey(second, prefix): 271 value = None 272 first = second 273 else: 274 value = second 275 first = gettok(tokens) 276 opts[key] = value 277 # we are done 278 return opts 279