src/table.c
static bool
cut_numeric_value(char *str, int xmin, int xmax, double *d, bool border0, bool *isnull, char **nullstr)
{

#define BUFFER_MAX_SIZE			101

	char		buffer[BUFFER_MAX_SIZE];
	char	   *buffptr;
	char	   *after_last_nospace = NULL;
	char	   *first_nospace_nodigit = NULL;
	char		decimal_point = '\0';
	bool		only_digits = false;
	bool		only_digits_with_point = false;
	bool		skip_initial_spaces = true;
	int			x = 0;
	long		mp = 1;

	*isnull = false;

	if (str)
	{
		after_last_nospace = buffptr = buffer;
		memset(buffer, 0, BUFFER_MAX_SIZE);

		while (*str)
		{
			int		chrlen = charlen(str);

			if (x > xmin || (border0 && x >= xmin))
			{
				char	c =  *str;

				if (skip_initial_spaces)
				{
					if (c == ' ')
					{
						x += 1;
						str += 1;
						continue;
					}

					/* first char should be a digit */
					if (!isdigit(c))
					{
						char	   *_nullstr = *nullstr;
						size_t		len;
						char	   *saved_str = str;

						after_last_nospace = saved_str;

						/*
						 * We should to check nullstr if exists, or we should to save
						 * this string as nullstr.
						 */
						while (*str)
						{
							if (*str != ' ')
								after_last_nospace = str + chrlen;

							x += dsplen(str);
							str += chrlen;

							if (x >= xmax)
								break;

							if (*str)
								chrlen = charlen(str);
						}

						len = after_last_nospace - saved_str;

						if (_nullstr)
						{
							if (strlen(_nullstr) == len)
								*isnull = strncmp(_nullstr, saved_str, len) == 0;
							else
								*isnull = false;
						}
						else
						{
							_nullstr = smalloc(len + 1);

							memcpy(_nullstr, saved_str, len);
							_nullstr[len] = '\0';

							*isnull = true;
							*nullstr = _nullstr;
						}

						return false;
					}

					skip_initial_spaces = false;
					only_digits = true;
				}

				memcpy(buffptr, str, chrlen);

				/* trim from right */
				if (c != ' ')
				{
					bool	only_digits_prev = only_digits;
					bool	only_digits_with_point_prev = only_digits_with_point;

					after_last_nospace = buffptr + chrlen;
					if (after_last_nospace - buffer > (BUFFER_MAX_SIZE - 1))
					{
						/* too long string - should not be translated to number */
						return false;
					}

					if (c == '.' || c == ',')
					{
						if (only_digits)
						{
							only_digits = false;
							only_digits_with_point = true;
							decimal_point = c;
						}
						else
							return false;
					}
					else if (!isdigit(c))
					{
						only_digits = false;
						only_digits_with_point = false;
					}

					/* Save point of chage between digits and other */
					if ((only_digits_prev || only_digits_with_point_prev) &&
					   !(only_digits || only_digits_with_point))
					{
						first_nospace_nodigit = buffptr;
					}
				}
				buffptr += chrlen;
			}

			x += dsplen(str);
			str += chrlen;

			if (x >= xmax)
				break;
		} /* while (*str) */

		/* trim spaces from right */
		*after_last_nospace = '\0';

		if (first_nospace_nodigit)
		{
			if (nstreq(first_nospace_nodigit, "bytes"))
				mp = 1l;
			else if (nstreq(first_nospace_nodigit, "kB"))
				mp = 1024l;
			else if (nstreq(first_nospace_nodigit, "MB"))
				mp = 1024l * 1024;
			else if (nstreq(first_nospace_nodigit, "GB"))
				mp = 1024l * 1024 * 1024;
			else if (nstreq(first_nospace_nodigit, "TB"))
				mp = 1024l * 1024 * 1024 * 1024;
			else
				/* unknown unit */
				return false;

			*first_nospace_nodigit = '\0';
		}

		if (decimal_point == ',')
		{
			char   *ptr = buffer;

			while (*ptr)
			{
				if (*ptr == ',')
					*ptr = '.';
				ptr += 1;
			}
		}

		errno = 0;
		*d = strtod(buffer, NULL);
		if (errno == 0)
		{
			*d = *d * mp;
			return true;
		}
	}

	return false;
}
/*
 * Try to cut numeric (double) value from row defined by specified xmin, xmax positions.
 * Units (bytes, kB, MB, GB, TB) are supported. Returns true, when returned value is valid.
 */
Try to cut numeric (double) value from row defined by specified xmin, xmax positions.
Units (bytes, kB, MB, GB, TB) are supported. Returns true, when returned value is valid.
Try to cut numeric ( double ) value from row defined by specified xmin xmax positions . Units ( bytes kB MB GB TB ) are supported . Returns true when returned value is valid .
static bool
cut_numeric_value(char *str, int xmin, int xmax, double *d, bool border0, bool *isnull, char **nullstr)
{
#define BUFFER_MAX_SIZE			101
	char		buffer[BUFFER_MAX_SIZE];
	char	   *buffptr;
	char	   *after_last_nospace = NULL;
	char	   *first_nospace_nodigit = NULL;
	char		decimal_point = '\0';
	bool		only_digits = false;
	bool		only_digits_with_point = false;
	bool		skip_initial_spaces = true;
	int			x = 0;
	long		mp = 1;
	*isnull = false;
	if (str)
	{
		after_last_nospace = buffptr = buffer;
		memset(buffer, 0, BUFFER_MAX_SIZE);
		while (*str)
		{
			int		chrlen = charlen(str);
			if (x > xmin || (border0 && x >= xmin))
			{
				char	c =  *str;
				if (skip_initial_spaces)
				{
					if (c == ' ')
					{
						x += 1;
						str += 1;
						continue;
					}
					if (!isdigit(c))
					{
						char	   *_nullstr = *nullstr;
						size_t		len;
						char	   *saved_str = str;
						after_last_nospace = saved_str;
						while (*str)
						{
							if (*str != ' ')
								after_last_nospace = str + chrlen;
							x += dsplen(str);
							str += chrlen;
							if (x >= xmax)
								break;
							if (*str)
								chrlen = charlen(str);
						}
						len = after_last_nospace - saved_str;
						if (_nullstr)
						{
							if (strlen(_nullstr) == len)
								*isnull = strncmp(_nullstr, saved_str, len) == 0;
							else
								*isnull = false;
						}
						else
						{
							_nullstr = smalloc(len + 1);
							memcpy(_nullstr, saved_str, len);
							_nullstr[len] = '\0';
							*isnull = true;
							*nullstr = _nullstr;
						}
						return false;
					}
					skip_initial_spaces = false;
					only_digits = true;
				}
				memcpy(buffptr, str, chrlen);
				if (c != ' ')
				{
					bool	only_digits_prev = only_digits;
					bool	only_digits_with_point_prev = only_digits_with_point;
					after_last_nospace = buffptr + chrlen;
					if (after_last_nospace - buffer > (BUFFER_MAX_SIZE - 1))
					{
						return false;
					}
					if (c == '.' || c == ',')
					{
						if (only_digits)
						{
							only_digits = false;
							only_digits_with_point = true;
							decimal_point = c;
						}
						else
							return false;
					}
					else if (!isdigit(c))
					{
						only_digits = false;
						only_digits_with_point = false;
					}
					if ((only_digits_prev || only_digits_with_point_prev) &&
					   !(only_digits || only_digits_with_point))
					{
						first_nospace_nodigit = buffptr;
					}
				}
				buffptr += chrlen;
			}
			x += dsplen(str);
			str += chrlen;
			if (x >= xmax)
				break;
		} 
		*after_last_nospace = '\0';
		if (first_nospace_nodigit)
		{
			if (nstreq(first_nospace_nodigit, "bytes"))
				mp = 1l;
			else if (nstreq(first_nospace_nodigit, "kB"))
				mp = 1024l;
			else if (nstreq(first_nospace_nodigit, "MB"))
				mp = 1024l * 1024;
			else if (nstreq(first_nospace_nodigit, "GB"))
				mp = 1024l * 1024 * 1024;
			else if (nstreq(first_nospace_nodigit, "TB"))
				mp = 1024l * 1024 * 1024 * 1024;
			else
				return false;
			*first_nospace_nodigit = '\0';
		}
		if (decimal_point == ',')
		{
			char   *ptr = buffer;
			while (*ptr)
			{
				if (*ptr == ',')
					*ptr = '.';
				ptr += 1;
			}
		}
		errno = 0;
		*d = strtod(buffer, NULL);
		if (errno == 0)
		{
			*d = *d * mp;
			return true;
		}
	}
	return false;
}
static bool cut_numeric_value ( char * str , int xmin , int xmax , double * d , bool border0 , bool * isnull , char * * nullstr ) { #define BUFFER_MAX_SIZE 			101 char buffer [ BUFFER_MAX_SIZE ] ; char * buffptr ; char * after_last_nospace = NULL ; char * first_nospace_nodigit = NULL ; char decimal_point = ' \0 ' ; bool only_digits = false ; bool only_digits_with_point = false ; bool skip_initial_spaces = true ; int x = 0 ; long mp = 1 ; * isnull = false ; if ( str ) { after_last_nospace = buffptr = buffer ; memset ( buffer , 0 , BUFFER_MAX_SIZE ) ; while ( * str ) { int chrlen = charlen ( str ) ; if ( x > xmin || ( border0 && x >= xmin ) ) { char c = * str ; if ( skip_initial_spaces ) { if ( c == ' ' ) { x += 1 ; str += 1 ; continue ; } if ( ! isdigit ( c ) ) { char * _nullstr = * nullstr ; size_t len ; char * saved_str = str ; after_last_nospace = saved_str ; while ( * str ) { if ( * str != ' ' ) after_last_nospace = str + chrlen ; x += dsplen ( str ) ; str += chrlen ; if ( x >= xmax ) break ; if ( * str ) chrlen = charlen ( str ) ; } len = after_last_nospace - saved_str ; if ( _nullstr ) { if ( strlen ( _nullstr ) == len ) * isnull = strncmp ( _nullstr , saved_str , len ) == 0 ; else * isnull = false ; } else { _nullstr = smalloc ( len + 1 ) ; memcpy ( _nullstr , saved_str , len ) ; _nullstr [ len ] = ' \0 ' ; * isnull = true ; * nullstr = _nullstr ; } return false ; } skip_initial_spaces = false ; only_digits = true ; } memcpy ( buffptr , str , chrlen ) ; if ( c != ' ' ) { bool only_digits_prev = only_digits ; bool only_digits_with_point_prev = only_digits_with_point ; after_last_nospace = buffptr + chrlen ; if ( after_last_nospace - buffer > ( BUFFER_MAX_SIZE - 1 ) ) { return false ; } if ( c == ' ' || c == ' ' ) { if ( only_digits ) { only_digits = false ; only_digits_with_point = true ; decimal_point = c ; } else return false ; } else if ( ! isdigit ( c ) ) { only_digits = false ; only_digits_with_point = false ; } if ( ( only_digits_prev || only_digits_with_point_prev ) && ! ( only_digits || only_digits_with_point ) ) { first_nospace_nodigit = buffptr ; } } buffptr += chrlen ; } x += dsplen ( str ) ; str += chrlen ; if ( x >= xmax ) break ; } * after_last_nospace = ' \0 ' ; if ( first_nospace_nodigit ) { if ( nstreq ( first_nospace_nodigit , " " ) ) mp = 1l ; else if ( nstreq ( first_nospace_nodigit , " " ) ) mp = 1024l ; else if ( nstreq ( first_nospace_nodigit , " " ) ) mp = 1024l * 1024 ; else if ( nstreq ( first_nospace_nodigit , " " ) ) mp = 1024l * 1024 * 1024 ; else if ( nstreq ( first_nospace_nodigit , " " ) ) mp = 1024l * 1024 * 1024 * 1024 ; else return false ; * first_nospace_nodigit = ' \0 ' ; } if ( decimal_point == ' ' ) { char * ptr = buffer ; while ( * ptr ) { if ( * ptr == ' ' ) * ptr = ' ' ; ptr += 1 ; } } errno = 0 ; * d = strtod ( buffer , NULL ) ; if ( errno == 0 ) { * d = * d * mp ; return true ; } } return false ; }
Try to cut numeric (double) value from row defined by specified xmin, xmax positions.
Try to cut numeric ( double ) value from row defined by specified xmin xmax positions .
/* first char should be a digit */ /*
						 * We should to check nullstr if exists, or we should to save
						 * this string as nullstr.
						 */ /* trim from right */ /* too long string - should not be translated to number */ /* Save point of chage between digits and other */ /* while (*str) */ /* trim spaces from right */ /* unknown unit */