
/* sel.c */

/* This file provides the function set_selections() to accept package
 * names on stdin.  (Note that the function is meant to be called only
 * when the corresponding command-line option has been invoked.)
 *
 */

#include "sel.h"
#include "alloc.h"
#include "gen.h"

struct hsearch_data sel;

int set_selections( void ) {

  int  n_sel = 0;
  char name[SEL_SIZE_LINE+2];
  if ( !hcreate_r( HASH_SIZE, &sel ) ) error(
    EPERM, 0,
    "cannot create selection hash"
  );

  while ( fgets( name, SEL_SIZE_LINE+2, stdin ) ) {

    if ( !strchr( name, '\n' ) )
      error( EIO, 0, "%s\n%s", SEL_IO_ERROR_MSG, name );

    /* Skip blank lines. */
    if ( isspace(*name) ) {
      char *p = name;
      while (*++p) if ( !isspace(*p) )
        error( EIO, 0, "%s\n%s", SEL_IO_ERROR_MSG, name );
      continue;
    }

    /* Truncate the input line to the read the package name only. */
    {
      int possible_dpkg_format = 0;
      char *p = name;
      while ( !isspace(*p) ) ++p;
      if ( *p != '\n' ) possible_dpkg_format = 1;
      *p++ = '\0';
      if ( possible_dpkg_format ) {
        while ( isspace(*p) && *p != '\n' ) ++p;
        if ( *p != '\n' ) {
          char *q = p;
          while ( !isspace(*q) ) ++q;
          *q++ = '\0';
          while (*q) if ( !isspace(*q++) )
            error( EIO, 0, "%s\n%s", SEL_IO_ERROR_MSG, name );
          if (
            ENFORCE_STR_DPKG_INSTALL
            && strcmp( STR_DPKG_INSTALL, p )
          ) goto set_selections_end_input_line;
        }
      }
    }

    /* Record the package name.  (On the wishlist:  Replace the rigid
     * old-style hash here with a more flexible modern hash.) */
    {
      ENTRY entry, *ep;
      entry.key  = malloc2( strlen(name) + 1 );
      strcpy( entry.key, name );
      entry.data = 0;
      if ( !hsearch_r( entry, ENTER, &ep, &sel ) ) error(
        ENOMEM, 0,
        "too many package names to -s"
      );
    }

    ++n_sel;

    set_selections_end_input_line:;

  }

  return n_sel;

}

