/*
 * tools/lib/lvm_get_col_numbers.c
 *
 * Copyright (C)  1997 - 2000  Heinz Mauelshagen, Sistina Software
 *
 * August 1998
 * September 1999
 * January 2000
 *
 *
 * This LVM library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This LVM 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this LVM library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA
 *
 */

/*
 * Changelog
 *
 *    29/10/1999 - fixed possible free() bug
 *    31/01/2000 - use debug_enter()/debug_leave()
 *
 */

#include <liblvm.h>

#define	LVM_CHECK_NUMBER(a,b) \
   if ( ( a = lvm_check_number ( b, FALSE)) < 0) { \
      fprintf ( stderr, "%s -- option extend argument %s is " \
                        "no number\n\n", \
                        cmd, b); \
      ret = -1; \
      goto lvm_get_col_numbers_end; \
   }


int lvm_get_col_numbers ( char *optarg, long **ptr) {
   long ext_count = 0;
   long new_count = 0;
   long start = 0;
   long end = 0;
   int ret = 0;
   long **ptr_sav = NULL;
   char *range_ptr = NULL;
   char *col_ptr = NULL;
   char *col_ptr2 = NULL;

   debug_enter ( "lvm_get_col_numbers -- CALLED\n");

   if ( optarg == NULL || ptr == NULL) {
      ret = -LVM_EPARAM;
      goto lvm_get_col_numbers_end;
   }

   if ( strchr ( optarg, ':') == NULL) {
      *ptr = NULL;
      ret = 0;
      goto lvm_get_col_numbers_end;
   }

   col_ptr = optarg;
   while ( ( col_ptr = strchr ( col_ptr, ':')) != NULL) {
      *col_ptr++ = 0;
      if ( *col_ptr != 0) {
         if ( ( col_ptr2 = strchr ( col_ptr, ':')) != NULL)
            *col_ptr2 = 0;
         if ( ( range_ptr = strchr ( col_ptr, '-')) != NULL) {
            *range_ptr++ = 0;
            LVM_CHECK_NUMBER ( start, col_ptr);
            LVM_CHECK_NUMBER ( end, range_ptr);
            if ( start < end) new_count = end - start + 2;
            else {
               fprintf ( stderr, "%s -- %s is not smaller than %s\n\n",
                                 cmd, col_ptr, range_ptr);
               ret = -1;
               goto lvm_get_col_numbers_end;
            }
            col_ptr = range_ptr;
         } else {
            new_count = 2;
            LVM_CHECK_NUMBER ( start, col_ptr);
            end = start;
         }

         ptr_sav = ptr;
         if ( ( *ptr = realloc ( *ptr,
                                 ( ext_count + new_count) *
                                 sizeof ( int))) == NULL) {
            free ( ptr_sav);
            *ptr = NULL;
            fprintf ( stderr, "%s -- realloc error "
                              "in file %s [line %d]\n\n",
                              cmd,
                              __FILE__, __LINE__);
            ret = -1;
            goto lvm_get_col_numbers_end;
         } else ptr_sav = NULL;

         while ( start <= end) (*ptr)[ext_count++] = start++;
         (*ptr)[ext_count] = -1;

         if ( col_ptr2 != NULL) *col_ptr2 = ':';
      }
   }

lvm_get_col_numbers_end:

   debug_leave ( "lvm_get_col_numbers -- LEAVING\n");
   return ret;
}
