/* $Id: user.c,v 1.6 2001/12/27 17:43:45 richdawe Exp $ */

/*
 *  user.c - Functions for zippo for use in user interface code.
 *  Copyright (C) 2000, 2001 by Richard Dawe
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "common.h"

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <libzippo/package.h>
#include <libzippo/dsm.h>
#include <libzippo/user.h>

/* -----------------------------
 * - user_parse_package_string -
 * ----------------------------- */

/*
 * Parse 'str', putting the package name into 'buf' (up to 'buflen' bytes
 * including nul) and putting the version into 'ver'. The package string
 * should be of the form:
 *
 * <name> <version numbers> (<type>)
 *
 * e.g. grep 2.2 (binaries)
 *
 * On success 1 is returned, else 0.
 *
 * If no type is specified, it defaults to wildcard.
 */

int
user_parse_package_string (const char *str, char *buf, size_t buflen,
			   PACKAGE_VERSION *ver)
{
  PACKAGE_INFO package; /* Only used for extracting package type */
  char      *ourstr = NULL;
  char      *p      = NULL;
  char      *q      = NULL;
  ptrdiff_t  cnt    = 0;

  /* Work on a copy of the string. */
  ourstr = strdup(str);
  if (ourstr == NULL)
    return(0);

  /* Initialise variables */
  *buf = '\0';
  memset(ver, 0, sizeof(*ver));
  memset(&package, 0, sizeof(package));

  /* Get the name */
  for (p = ourstr; (*p != '\0') && !isspace(*p); p++) {;}
  cnt = p - ourstr;  
  cnt = (buflen <= cnt) ? buflen - 1 : cnt; /* Don't overrun the buffer */
  strncpy(buf, ourstr, cnt);
  buf[cnt] = '\0';

  /* Skip whitespace before version */
  while (isspace(*p)) { p++; }

  /* Is the version number present, or have we reached the type? */
  if (*p != '(') {
    /* Parse the version */
    if (dsm_parse_wildcard_version(p, ver) != DSM_OK) {
      free(ourstr);
      return(0);
    }
  }

  /* If no version was present, set a wildcard match. */
  if (!ver->has_version)
    package_version_wildcard(ver);

  /* Get the package type, if any. */
  p = strrchr(p, '(');
  if (p != NULL) {
    p++;
    q = strchr(p, ')');
    if (q != NULL)
      *q = '\0';

    if (   dsm_parse_wildcard_type("user_parse_package_string", p, &package)
	!= DSM_OK) {
      free(ourstr);
      return(0);
    }

    ver->has_version = 1;
    ver->has_type    = 1;
    ver->type        = package.version.type;
  } else {
    /* Default to a wildcard version */
    ver->has_version = 1;
    ver->has_type    = 1;
    ver->type        = TYPE_WILDCARD;
  }

  /* Tidy up */
  free(ourstr);

  /* Done */
  return(1);
}
