/*@@ @file GHExtension.c @date Tue 9th Feb 1999 @author Gabrielle Allen @desc IOUtil GH extension stuff. @enddesc @version $Id$ @@*/ #include #include #include #include "cctk.h" #include "util_String.h" #include "cctk_Parameters.h" #include "cctk_GNU.h" #include "ioHDF5UtilGH.h" /* the rcs ID and its dummy function to use it */ static char *rcsid = "$Id$"; CCTK_FILEVERSION(BetaThorns_IOHDF5Util_ParseVars_c) /* prototypes of routines defined in this source file */ void IOHDF5Util_ParseVarsForOutput (const char *output_varstring, ioHDF5Geo_t *output_request_list[]); static void IOHDF5Util_ParseOutputRequest (int vindex, const char *optstring, void *arg); static ioHDF5Geo_t *IOHDF5Util_DefaultIORequest (int vindex); /* prototypes of external routines for which no header files exist */ int CCTK_RegexMatch (const char *string, const char *pattern, const int nmatch, regmatch_t *pmatch); /* =============================================================== utility routines used by other IO thorns ===============================================================*/ /*@@ @routine IOUtil_ParseVarsForOutput @date Sat March 6 1999 @author Gabrielle Allen @desc Sets each flag in the do_output[] do_output to true if var[i] could be found in the list of variable names. var_list my also contain group names of variables as well as the special keyword "all" which indicates that output is requested on all variables. @enddesc @history @endhistory @var var_list @vdesc list of variables and/or group names @vtype const char * @vio in @endvar @var do_output @vdesc do_output of flags indicating output was requested for var[i] @vtype char [] @vio out @endvar @@*/ void IOHDF5Util_ParseVarsForOutput (const char *output_varstring, ioHDF5Geo_t *output_request_list[]) { int i; /* free current list of output requests */ for (i = CCTK_NumVars () - 1; i >= 0; i--) { if (output_request_list[i]) { free (output_request_list[i]->origin); free (output_request_list[i]); output_request_list[i] = NULL; } } /* generate new list of output requests */ CCTK_TraverseString (output_varstring, IOHDF5Util_ParseOutputRequest, output_request_list, CCTK_GROUP_OR_VAR); } static void IOHDF5Util_ParseOutputRequest (int vindex, const char *optstring, void *arg) { DECLARE_CCTK_PARAMETERS regmatch_t gmatch[6], *dmatch; int matched; char *token, *separator; char *substring, *parsestring, *regexstring; int i, j; int bytes; ioHDF5Geo_t **output_requests, *new_request; output_requests = (ioHDF5Geo_t **) arg; /* allocate a new IO request structure and initialize it with defaults */ new_request = IOHDF5Util_DefaultIORequest (vindex); if (! optstring) { output_requests[vindex] = new_request; return; } /* parse the hyperslab information */ matched = CCTK_RegexMatch (optstring, "\\[" "\\{([0-9]+)\\}" /* dimension */ "\\{([0-9,()]+)\\}" /* direction */ "\\{([0-9,]+)\\}" /* origin */ "\\{([-0-9,]+)\\}" /* length */ "\\{([0-9,]+)\\}" /* downsample */ "\\]", 6, gmatch); if (matched <= 0) { CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Couldn't parse hyperslab parameter '%s'", optstring); free (new_request); return; } /* SLAB DIMENSION */ new_request->sdim = 0; bytes = (int) (gmatch[1].rm_eo - gmatch[1].rm_so); if (gmatch[1].rm_so != -1 && bytes > 0) { new_request->sdim = atoi (optstring + gmatch[1].rm_so); } if (new_request->sdim <= 0 || new_request->sdim > new_request->vdim) { CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Invalid or no dimension given in hyperslab parameter '%s'", optstring); free (new_request); return; } /* DIRECTION */ i = 0; bytes = (int) (gmatch[2].rm_eo - gmatch[2].rm_so); if (gmatch[2].rm_so != -1 && bytes > 0) { substring = strdup (optstring + gmatch[2].rm_so); substring[bytes] = 0; dmatch = (regmatch_t *) malloc ((new_request->sdim + 1) * sizeof (regmatch_t)); regexstring = (char *) malloc (new_request->sdim * sizeof ("\\(([0-9,]+)\\)")); regexstring[0] = 0; for (i = 0; i < new_request->sdim; i++) { strcat (regexstring, "\\(([0-9,]+)\\)"); } matched = CCTK_RegexMatch (substring, regexstring, new_request->sdim + 1, dmatch); free (regexstring); if (matched <= 0) { CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Couldn't parse direction vectors in hyperslab " "parameter '%s'.", optstring); free (dmatch); free (new_request); return; } for (j = 0; j < new_request->sdim; j++) { i = 0; bytes = (int) (dmatch[j + 1].rm_eo - dmatch[j + 1].rm_so); if (dmatch[j + 1].rm_so != -1 && bytes > 0) { parsestring = strdup (substring + dmatch[j + 1].rm_so); parsestring[bytes] = 0; token = parsestring; while ((separator = strchr (token, ',')) != NULL) { *separator = 0; new_request->direction[j * new_request->vdim + i] = atoi (token); if (++i >= new_request->vdim) { break; } token = separator + 1; } new_request->direction[j * new_request->vdim + i++] = atoi (token); free (parsestring); } free (substring); if (i < new_request->vdim) { CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Direction vectors are incomplete or missing in hyperslab " "parameter '%s'.", optstring); free (new_request); return; } } } if (i < new_request->vdim) { CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Direction vectors are incomplete or missing in hyperslab " "parameter '%s'.", optstring); free (new_request); return; } /* ORIGIN */ i = 0; bytes = (int) (gmatch[3].rm_eo - gmatch[3].rm_so); if (gmatch[3].rm_so != -1 && bytes > 0) { substring = strdup (optstring + gmatch[3].rm_so); substring[bytes] = 0; token = substring; while ((separator = strchr (token, ',')) != NULL) { *separator = 0; new_request->origin[i] = atoi (token); if (++i >= new_request->vdim) { break; } token = separator + 1; } new_request->origin[i++] = atoi (token); free (substring); } if (i < new_request->vdim) { CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Origin vector is incomplete or missing in hyperslab " "parameter '%s'.", optstring); free (new_request); return; } /* LENGTH */ i = 0; bytes = (int) (gmatch[4].rm_eo - gmatch[4].rm_so); if(gmatch[4].rm_so != -1 && bytes > 0) { substring = strdup (optstring + gmatch[4].rm_so); substring[bytes] = 0; token = substring; while ((separator = strchr (token, ',')) != NULL) { *separator = 0; new_request->length[i] = atoi (token); if (++i >= new_request->sdim) { break; } token = separator + 1; } new_request->length[i++] = atoi (token); free (substring); } if (i < new_request->sdim) { CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Length vector is incomplete or missing in hyperslab " "parameter '%s'.", optstring); free (new_request); return; } /* DOWNSAMPLING */ i = 0; bytes = (int) (gmatch[5].rm_eo - gmatch[5].rm_so); if(gmatch[5].rm_so != -1 && bytes > 0) { substring = strdup (optstring + gmatch[5].rm_so); substring[bytes] = 0; token = substring; while ((separator = strchr (token, ',')) != NULL) { *separator = 0; new_request->downsample[i] = atoi (token); if (++i >= new_request->sdim) { break; } token = separator + 1; } new_request->downsample[i++] = atoi (token); free (substring); } if (i < new_request->sdim) { CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Downsampling vector is incomplete or missing in hyperslab " "parameter '%s'.", optstring); free (new_request); return; } /* assign the output request */ output_requests[vindex] = new_request; #ifdef IOHDF5UTIL_DEBUG printf("Geometry Data: \n"); printf(" Argument/Slab dimension: %d / %d \n", new_request->vdim,new_request->sdim); printf(" Origin: "); for (i=0;ivdim;i++) printf("%s %d ", new_request->origin[i]); printf("\n Downs : "); for (i=0;isdim;i++) printf(" %d ", new_request->downsample[i]); printf("\n Length: "); for (i=0;isdim;i++) printf(" %d ", new_request->length[i]); printf("\n Dirs : "); for (i=0;isdim;i++) printf(" %d ", new_request->direction[i]); printf("\n\n"); #endif USE_CCTK_PARAMETERS } static ioHDF5Geo_t *IOHDF5Util_DefaultIORequest (int vindex) { DECLARE_CCTK_PARAMETERS int i; ioHDF5Geo_t *request; const char *argument, *token; /* allocate a new IO request structure */ request = (ioHDF5Geo_t *) malloc (sizeof (ioHDF5Geo_t)); /* get the variable's dimension set it also to be the default hyperslab dimension */ request->vdim = request->sdim = CCTK_GroupDimFromVarI (vindex); request->origin = (int *) calloc (4 + request->sdim, request->vdim * sizeof (int)); request->length = request->origin + 1 * request->vdim; request->downsample = request->origin + 2 * request->vdim; request->actlen = request->origin + 3 * request->vdim; request->direction = request->origin + 4 * request->vdim; for (i = 0; i < request->vdim; i++) { request->length[i] = -1; request->downsample[i] = 1; request->direction[i * request->vdim + i] = 1; } #if 0 FIXME: parse default hyperslab parameters /* Origin */ i=0; argument = origin; while((token = Util_StrSep(&argument,","))) { request->origin[i++]=atoi(token); } request->downsample[i] = atoi(argument); /* Direction */ i=0; argument = direction; while((token = Util_StrSep(&argument,","))) { request->direction[i++]=atoi(token); } request->downsample[i] = atoi(argument); /* Downsample */ i=0; argument = downsampling; while((token = Util_StrSep(&argument,","))) { request->downsample[i++]=atoi(token); } request->downsample[i] = atoi(argument); /* Length */ i=0; argument = length; while((token = Util_StrSep(&argument,","))) { request->length[i++]=atoi(token); } request->length[i] = atoi(argument); #endif return (request); }