|
version 1.1, 2012/02/17 15:09:30
|
version 1.1.1.4, 2021/03/17 00:32:36
|
|
Line 3
|
Line 3
|
| * |
* |
| * Copyright (C) 1998 Andrew Tridgell |
* Copyright (C) 1998 Andrew Tridgell |
| * Copyright (C) 2002 Martin Pool |
* Copyright (C) 2002 Martin Pool |
| * Copyright (C) 2004, 2005, 2006 Wayne Davison | * Copyright (C) 2004-2020 Wayne Davison |
| * |
* |
| * This program is free software; you can redistribute it and/or modify |
* 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 |
* it under the terms of the GNU General Public License as published by |
|
Line 20
|
Line 20
|
| */ |
*/ |
| |
|
| #include "rsync.h" |
#include "rsync.h" |
| |
#include "itypes.h" |
| |
|
| #ifndef HAVE_STRDUP | static char number_separator; |
| char *strdup(char *s) | |
| | char get_number_separator(void) |
| { |
{ |
| int len = strlen(s) + 1; | if (!number_separator) { |
| char *ret = (char *)malloc(len); | char buf[32]; |
| if (ret) | snprintf(buf, sizeof buf, "%f", 3.14); |
| memcpy(ret, s, len); | if (strchr(buf, '.') != NULL) |
| return ret; | number_separator = ','; |
| | else |
| | number_separator = '.'; |
| | } |
| | |
| | return number_separator; |
| } |
} |
| #endif |
|
| |
|
| |
char get_decimal_point(void) |
| |
{ |
| |
return get_number_separator() == ',' ? '.' : ','; |
| |
} |
| |
|
| #ifndef HAVE_GETCWD |
#ifndef HAVE_GETCWD |
| char *getcwd(char *buf, int size) |
char *getcwd(char *buf, int size) |
| { |
{ |
|
Line 76
|
Line 87
|
| |
|
| #ifndef HAVE_STRPBRK |
#ifndef HAVE_STRPBRK |
| /** |
/** |
| * Find the first ocurrence in @p s of any character in @p accept. | * Find the first occurrence in @p s of any character in @p accept. |
| * |
* |
| * Derived from glibc |
* Derived from glibc |
| **/ |
**/ |
|
Line 149 int sys_gettimeofday(struct timeval *tv)
|
Line 160 int sys_gettimeofday(struct timeval *tv)
|
| return gettimeofday(tv, NULL); |
return gettimeofday(tv, NULL); |
| #else |
#else |
| return gettimeofday(tv); |
return gettimeofday(tv); |
| |
#endif |
| |
} |
| |
|
| |
/* Return the int64 number as a string. If the human_flag arg is non-zero, |
| |
* we may output the number in K, M, G, or T units. If we don't add a unit |
| |
* suffix, we will append the fract string, if it is non-NULL. We can |
| |
* return up to 4 buffers at a time. */ |
| |
char *do_big_num(int64 num, int human_flag, const char *fract) |
| |
{ |
| |
static char bufs[4][128]; /* more than enough room */ |
| |
static unsigned int n; |
| |
char *s; |
| |
int len, negated; |
| |
|
| |
if (human_flag && !number_separator) |
| |
(void)get_number_separator(); |
| |
|
| |
n = (n + 1) % (sizeof bufs / sizeof bufs[0]); |
| |
|
| |
if (human_flag > 1) { |
| |
int mult = human_flag == 2 ? 1000 : 1024; |
| |
if (num >= mult || num <= -mult) { |
| |
double dnum = (double)num / mult; |
| |
char units; |
| |
if (num < 0) |
| |
dnum = -dnum; |
| |
if (dnum < mult) |
| |
units = 'K'; |
| |
else if ((dnum /= mult) < mult) |
| |
units = 'M'; |
| |
else if ((dnum /= mult) < mult) |
| |
units = 'G'; |
| |
else if ((dnum /= mult) < mult) |
| |
units = 'T'; |
| |
else { |
| |
dnum /= mult; |
| |
units = 'P'; |
| |
} |
| |
if (num < 0) |
| |
dnum = -dnum; |
| |
snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units); |
| |
return bufs[n]; |
| |
} |
| |
} |
| |
|
| |
s = bufs[n] + sizeof bufs[0] - 1; |
| |
if (fract) { |
| |
len = strlen(fract); |
| |
s -= len; |
| |
strlcpy(s, fract, len + 1); |
| |
} else |
| |
*s = '\0'; |
| |
|
| |
len = 0; |
| |
|
| |
if (!num) |
| |
*--s = '0'; |
| |
if (num < 0) { |
| |
/* A maximum-size negated number can't fit as a positive, |
| |
* so do one digit in negated form to start us off. */ |
| |
*--s = (char)(-(num % 10)) + '0'; |
| |
num = -(num / 10); |
| |
len++; |
| |
negated = 1; |
| |
} else |
| |
negated = 0; |
| |
|
| |
while (num) { |
| |
if (human_flag) { |
| |
if (len == 3) { |
| |
*--s = number_separator; |
| |
len = 1; |
| |
} else |
| |
len++; |
| |
} |
| |
*--s = (char)(num % 10) + '0'; |
| |
num /= 10; |
| |
} |
| |
|
| |
if (negated) |
| |
*--s = '-'; |
| |
|
| |
return s; |
| |
} |
| |
|
| |
/* Return the double number as a string. If the human_flag option is > 1, |
| |
* we may output the number in K, M, G, or T units. The buffer we use for |
| |
* our result is either a single static buffer defined here, or a buffer |
| |
* we get from do_big_num(). */ |
| |
char *do_big_dnum(double dnum, int human_flag, int decimal_digits) |
| |
{ |
| |
static char tmp_buf[128]; |
| |
#if SIZEOF_INT64 >= 8 |
| |
char *fract; |
| |
|
| |
snprintf(tmp_buf, sizeof tmp_buf, "%.*f", decimal_digits, dnum); |
| |
|
| |
if (!human_flag || (dnum < 1000.0 && dnum > -1000.0)) |
| |
return tmp_buf; |
| |
|
| |
for (fract = tmp_buf+1; isDigit(fract); fract++) {} |
| |
|
| |
return do_big_num((int64)dnum, human_flag, fract); |
| |
#else |
| |
/* A big number might lose digits converting to a too-short int64, |
| |
* so let's just return the raw double conversion. */ |
| |
snprintf(tmp_buf, sizeof tmp_buf, "%.*f", decimal_digits, dnum); |
| |
return tmp_buf; |
| #endif |
#endif |
| } |
} |