/*		parse_query_string	Sep 04				*/
/*  Output:								*/
/*      Returns pointer to array of character string pointers.  Returns	*/
/*    NULL only if there is no QUERY_STRING environment variable	*/
/*    Array ends with a NULL pointer.  Note that length of array before	*/
/*    the NULL pointer can be 0.  This occurs if input is non-NULL but	*/
/*    empty.								*/ 
/*      Each char string pointer points to a method parameter (rules 	*/
/*    below).  Note that any method parameter can be the empty string.	*/
/*  Input:								*/
/*	pointer to character string to parse.  If NULL, parse_query_	*/
/*    string uses the value of the environment variable QUERY_STRING	*/
/*	pointer to integer into which the number of parameters is	*/
/*    returned.  If NULL, the number of parameters is not returned	*/

/*  Parsing rules:							*/
/*      Parameters are separated by commas.  Commas inside parentheses	*/
/*    are ignored.  Consecutive commas generate empty parameters	*/
/*		[These are the "original" serv rules]			*/

/*  Errors:								*/
/*	Calls functions err or errn if dynamic memory cannot be allo-	*/
/*    cated, or if there is a "parenthesis problem".  err is called	*/
/*    with 2 pointers to character strings.  errn is called with 1	*/
/*    such pointer and an integer.					*/

/*  Programs required:							*/
/*	err(s,t) is expected to be provided by the calling program to	*/
/*    deal w/error messages.						*/
/*	errn & strdupl from the JGOFS library are needed		*/
/*	getenv & malloc from the system library are needed		*/

#define QUERY_STRING_VERSION "query_string_routines version 1.0  3 Sep 2004"

#include <stdlib.h>
#include <string.h>
#include "query_string_routines.h"

char *query_string_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[] = QUERY_STRING_VERSION"/"QUERY_STRINGH_VERSION;
  return version;
}

char **parse_query_string(par,npars_return)
char *par;
int *npars_return;
{
char *getenv();
void err();
void errn();
char *strdupl();

char **parptr;
int npars,nparens,max_pars;
char *sp;
char *buffer;

if (par == NULL) par = getenv("QUERY_STRING");

npars = 0;

if (par == NULL) {
  parptr = NULL;
} else {

  strdupl(&buffer,par,"copying parameter in parse_query_string");

    /*  Every parameter is at least 1 char long w/1 char separator...	*/
    /*  except that 1 param need not have a separator.  Hence the "2 +"	*/
    /*  Add another 1 for a terminating NULL pointer			*/
  max_pars = 2 + 1 + strlen(buffer)/2;
  parptr = (char **)malloc(max_pars*sizeof(char *));
  if (parptr == NULL) 
    errn("parse_query_string: Could not get character ptrs.  Tried to get ",
	 max_pars);

  parptr[npars++] = buffer;

  nparens = 0;
  sp = buffer;
  while (*sp != '\0') {
    switch (*sp) {
      case '(':
	nparens++;
	break;
      case ')':
	nparens--;
	if (nparens < 0) 
	  err ("parse_query_string: Unmatched parens.  String = ", par);
	break;
      case ',':
	if (nparens == 0) {
          *sp = '\0';
          parptr[npars++] = sp+1;
	}
        break;
      default:
        break;
    }
    sp++;
  }

  if (nparens != 0) 
	err ("parse_query_string: Unmatched parens.  String = ", par);
  parptr[npars] = NULL;
}

if (npars_return != NULL) *npars_return = npars;
return parptr;
}
