/* substr.c -- construct and return a substring
 *
 * Beau Grantham (beau@thedarkmere.net)
 * 2006/04/14
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
 * 
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define SUBSTR_WARN 1   // boolean 0|1

/* Usage:
 *
 * substr(char *str, int pos, int len);
 * 
 * This will return a substring of a given string, with a given
 * start position and length. Length may be negative, denoting that
 * the start value will be the final character of the substring.
 *
 * substr("substring", 0, 4)                        => "subs"
 * substr("substring", 3, 3)                        => "str"
 * substr("substring", strlen("substring"), -6))    => "string"
 *
 * Exceptions: (prints warning when SUBSTR_WARN is enabled)
 * substr("substring", 3, -1000)                    => "sub"
 * substr("substring", 3, 1000)                     => "string"
 *
 */

char *substr(char *str, int pos, int len) {
   int  i,
        start,
        end;
   char *sub;

   // substring("string", -1, 2);
   if (pos < 0) {
      fprintf(stderr, "substr(): Illegal start position (0 <= pos <= %d).\n", strlen(str));
      return NULL;
   }

   // substring("string", 2, -4);
   if ((pos + len) < 0) {
      len = -pos;
      if (SUBSTR_WARN)
         fprintf(stderr, "substr(): Warning: Minimum string bounds exceeded (truncating).\n");
   }

   // substring("string", 3, 7);
   if ((pos + len) > strlen(str)) {
      len = strlen(str) - pos;
      if (SUBSTR_WARN)
         fprintf(stderr, "substr(): Warning: Maximum string bounds exceeded (truncating).\n");
   }

   // allocate space for substring
   if ((sub = (char *) malloc (sizeof (char) *(((len < 0) ? (len * -1) : len) + 1))) == NULL) {
      fprintf(stderr, "substr(): Memory allocation exceeded.\n");
      return NULL;
   }

   // determine start and end location
   start = pos + ((len < 0) ? len : 0);
   end   = ((len < 0) ? pos : pos + len);
	
   // create substring
   for (i = start; i < end; i++)
      sub[i - start] = str[i];
   sub[i] = '\0';

   return sub;
}
