/* parse_query_string.c Sep 04 */ /* Takes a command-line argument "formatted like a JGOFS QUERY_ */ /* STRING". If no argument, uses the value of the QUERY_STRING */ /* env var. */ /* Uses query_string_routines to divide the argument into pieces. */ /* Reassembles those pieces into a string designed to be processed */ /* by a perl program (or other reg exp engine) */ /* May return other strings, but in original version does not */ /* Output: */ /* If the output matches /^\s*\*\*\*\s*ERROR\s*\*\*\*/ /* (*** ERROR *** at the start of the string, w/various spaces */ /* allowed), there has been an error of some kind (presumably */ /* there will be more text). The process exit status will be */ /* non-zero as well. */ /* Otherwise, 2 logical fields are output, separated by a space. */ /* The first field does not have any spaces. The 2nd field may. */ /* The second field is a list of strings returned by this program */ /* In the original version, 1 string is returned by this program. */ /* That string is a list of "QUERY_STRING arguments" */ /* The first field is a list of separator characters that can be */ /* used to split and subsplit the 2nd field. The first character */ /* of this field is used to separate the strings returned by this */ /* program. The second character of this field is used to separate */ /* the "QUERY_STRING argument return string" into individual */ /* "QUERY_STRING arguments". Future implementations may add more */ /* separation characters */ /* Sample usage: */ /* Step 1: Get program output (example ignores error situations) */ /* $output = `/wherever/parse_query_string`; */ /* Step 2: Get separators */ /* ($separators,$rest) = split (/ /,$output,2); */ /* If $rest is not defined, there was no QUERY_STRING */ /* Step 3: ID separators */ /* ($parse_query_return_sep,$query_string_arg_sep,@seps) = */ /* split //,$separators; */ /* Step 4: Get parse_query_string returns */ /* ($query_string_arg_list,@other_returns) = */ /* split /$parse_query_return_sep/,$rest; */ /* Step 5: Get "QUERY_STRING arguments" */ /* @query_string_args = */ /* split /$query_string_arg_sep/,$query_string_arg_list; */ #define PQS_VERSION "parse_query_string version 1.0 27 Mar 2008" /* 27 Mar 08 v 1.0 WJS */ /* Apparently this was never used after it was written in 2004, */ /* judged by the compilation warnings just now (one of which was a */ /* typo that would have resulted in an unsatis ref. Fix those */ #include "core.h" /* PQS = parse_query_string; QS - QUERY_STRING */ /* The space is documented above, so changing it would invalidate */ /* everything, (given that we haven't bothered to make the defns */ /* below available to a perl program) */ /* The comma is the "traditional" QS separator, but nothing should */ /* break if that gets changed. */ /* The exclamation point will only get used if this program returns */ /* "more stuff", so it's kind of a less-desirable separator */ /* Defined as 1 character strings for coding convenience */ #define PQS_SEPARATORS_RETURN_ARGS_SEPARATOR " " #define PREFERRED_PQS_RETURN_ARGS_SEPARATOR "!" #define PREFERRED_QS_SEPARATOR "," char **split_query_string(); Logical add_id_to_err(); /* from utils.c */ /************************************************************************/ void err(s,t) char *s,*t; { char *new_s,*new_t; add_id_to_err(&new_s,&new_t,s,t,PQS_VERSION); printf (" *** ERROR *** %s %s",new_s,new_t); exit(ERROR_EXIT_STATUS); /* Defined in core.h */ } char *pqs_return_vers() /* Routine exists mostly to force .h file version string into this */ /* module, but we could call it if we want. Note string must not be */ /* global or we'll have conflicts if another routine similarly */ /* includes the version string */ { static char version[] = PQS_VERSION"/"COREH_VERSION; return version; } Logical search_qs(pieces,search_char) char **pieces; char search_char; /* Return TRUE if search_char is in any of pieces */ { char **ptrptr; ptrptr = pieces; while (*ptrptr != NULL) { if (strchr(*ptrptr,search_char) != NULL) return TRUE; ptrptr++; } return FALSE; } int main(argc,argv) int argc; char *argv[]; { char *string_to_parse; char **pieces_of_query_string; int npieces; /* List of separators in order of preference (after the "preferred */ /* ones). Add/rearrange/delete at will */ char separators[] = ",/|_-!@#$%^&*\?:;"; char *pqs_return_args_separator,*qs_separator; char *ptr,*sep_ptr; char **ptrptr; if (argc > 2) err("Too many arguments. Max = 1",""); else string_to_parse = (argc == 1) ? getenv("QUERY_STRING") : argv[1]; if (string_to_parse == NULL) {/* No QUERY_STRING (or null argv[0]!) */ printf ("/"); /* Any non-space will do */ exit (0); } /* Can't have space in separators... */ while ( (ptr = strchr(separators,*PQS_SEPARATORS_RETURN_ARGS_SEPARATOR)) != NULL ) strcpy (ptr,ptr+1); pieces_of_query_string = split_query_string(string_to_parse,&npieces); sep_ptr = separators; pqs_return_args_separator = PREFERRED_PQS_RETURN_ARGS_SEPARATOR; while (*pqs_return_args_separator != '\0') { if (search_qs(pieces_of_query_string,*pqs_return_args_separator)) pqs_return_args_separator = sep_ptr++; else /* Search other potential return strings if/when they arise */ break; } if (*pqs_return_args_separator == '\0') err ("Cannot find character that is not in output set. Character list = ", separators); /* pqs_return_args_separator cannot be in anything returned by */ /* this program, so once it's ID'ed, remove it from the candidate */ /* list */ while ( (ptr = strchr(separators,*pqs_return_args_separator)) != NULL ) strcpy (ptr,ptr+1); /* Find a character not in any of the query string pieces */ sep_ptr = separators; qs_separator = PREFERRED_QS_SEPARATOR; while (*qs_separator != '\0') { if (search_qs(pieces_of_query_string,*qs_separator)) qs_separator = sep_ptr++; else break; } if (*qs_separator == '\0') err ("Cannot find character that is not in output set. Character list = ", separators); /* Find a character not in the next return string. Note that */ /* qs_separator can be used here, too. */ printf("%c%c%c",*pqs_return_args_separator, *qs_separator, *PQS_SEPARATORS_RETURN_ARGS_SEPARATOR); ptrptr = pieces_of_query_string; while (*(ptrptr+1) != NULL) { printf ("%s%c",*ptrptr,*qs_separator); ptrptr++; } printf ("%s",*ptrptr); /* If more stuff is to be returned, print */ /* *pqs_return_args_separator here, then go on */ exit(0); }