diff options
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/Makefile.in | 10 | ||||
-rw-r--r-- | erts/emulator/beam/atom.names | 1 | ||||
-rw-r--r-- | erts/emulator/beam/beam_load.c | 5 | ||||
-rw-r--r-- | erts/emulator/beam/bif.c | 17 | ||||
-rw-r--r-- | erts/emulator/beam/bif.tab | 1 | ||||
-rwxr-xr-x | erts/emulator/beam/erl_bif_info.c | 4 | ||||
-rw-r--r-- | erts/emulator/beam/erl_init.c | 53 | ||||
-rw-r--r-- | erts/emulator/beam/erl_unicode.c | 63 | ||||
-rw-r--r-- | erts/emulator/beam/ops.tab | 2 | ||||
-rw-r--r-- | erts/emulator/beam/packet_parser.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/sys.h | 14 | ||||
-rw-r--r-- | erts/emulator/drivers/common/efile_drv.c | 2 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_sys_common_misc.c | 204 | ||||
-rw-r--r-- | erts/emulator/test/decode_packet_SUITE.erl | 3 | ||||
-rw-r--r-- | erts/emulator/test/num_bif_SUITE.erl | 22 | ||||
-rwxr-xr-x | erts/emulator/utils/gen_git_version | 40 |
16 files changed, 334 insertions, 109 deletions
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 3e44bbb8db..7033ea0a3d 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -20,6 +20,8 @@ include $(ERL_TOP)/make/target.mk include ../vsn.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk +include $(TARGET)/gen_git_version.mk + ENABLE_ALLOC_TYPE_VARS = @ENABLE_ALLOC_TYPE_VARS@ HIPE_ENABLED=@HIPE_ENABLED@ @@ -196,7 +198,7 @@ else EMU_CC = @EMU_CC@ endif WFLAGS = @WFLAGS@ -CFLAGS = @STATIC_CFLAGS@ $(TYPE_FLAGS) $(FLAVOR_FLAGS) $(DEFS) $(WFLAGS) $(THR_DEFS) $(ARCHCFLAGS) +CFLAGS = @STATIC_CFLAGS@ $(TYPE_FLAGS) $(FLAVOR_FLAGS) $(DEFS) $(WFLAGS) $(THR_DEFS) $(ARCHCFLAGS) $(GIT_VSN) HCC = @HCC@ LD = @LD@ DEXPORT = @DEXPORT@ @@ -1006,6 +1008,12 @@ DEP_FLAGS=-MM $(MG_FLAG) $(CFLAGS) $(INCLUDES) -Idrivers/common -Idrivers/$(ERLA SYS_SRC=$(ALL_SYS_SRC) endif +.PHONY: $(TARGET)/gen_git_version.mk +$(TARGET)/gen_git_version.mk: +# We touch beam/erl_bif.info.c if we regenerated the git version to force a +# rebuild. + if $(gen_verbose)utils/gen_git_version $@; then touch beam/erl_bif_info.c; fi + .PHONY: depend ifdef VOID_EMULATOR depend: diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names index f138324e1f..ce60bb9bbc 100644 --- a/erts/emulator/beam/atom.names +++ b/erts/emulator/beam/atom.names @@ -269,6 +269,7 @@ atom hipe_architecture atom http httph https http_response http_request http_header http_eoh http_error http_bin httph_bin atom id atom if_clause +atom ignore atom imports atom in atom in_exiting diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index f57fa2bfbb..81c1ea749a 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -1853,7 +1853,10 @@ load_code(LoaderState* stp) unsigned tag; switch (last_op->a[arg].val) { - case 0: /* Floating point number */ + case 0: + /* Floating point number. + * Not generated by the compiler in R16B and later. + */ { Eterm* hp; /* XXX:PaN - Halfword should use ARCH_64 variant instead */ diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 46f76624a5..df084e1185 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -2963,15 +2963,14 @@ BIF_RETTYPE float_to_list_2(BIF_ALIST_2) Eterm* tp = tuple_val(arg); if (*tp == arity_two && is_small(tp[2])) { decimals = signed_val(tp[2]); - if (decimals > 0 && decimals < sizeof(fbuf) - 6 /* "X." ++ "e+YY" */) - switch (tp[1]) { - case am_decimals: - fmt_type = FMT_FIXED; - continue; - case am_scientific: - fmt_type = FMT_SCIENTIFIC; - continue; - } + switch (tp[1]) { + case am_decimals: + fmt_type = FMT_FIXED; + continue; + case am_scientific: + fmt_type = FMT_SCIENTIFIC; + continue; + } } } goto badarg; diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index 4aaf466008..e313188901 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -522,6 +522,7 @@ bif erlang:nif_error/2 bif prim_file:internal_name2native/1 bif prim_file:internal_native2name/1 bif prim_file:internal_normalize_utf8/1 +bif prim_file:is_translatable/1 bif file:native_name_encoding/0 # diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index a601e4fb39..8582a8954b 100755 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -69,7 +69,11 @@ static char erts_system_version[] = ("Erlang " ERLANG_OTP_RELEASE " [no-c-stack-objects]" #endif #ifndef OTP_RELEASE +#ifdef ERLANG_GIT_VERSION + " [source-" ERLANG_GIT_VERSION "]" +#else " [source]" +#endif #endif #ifdef ARCH_64 #if HALFWORD_HEAP diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 223c9c4d7e..ec3e0d54cb 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -981,19 +981,64 @@ erl_start(int argc, char **argv) break; case 'f': if (!strncmp(argv[i],"-fn",3)) { + int warning_type = ERL_FILENAME_WARNING_WARNING; arg = get_arg(argv[i]+3, argv[i+1], &i); switch (*arg) { case 'u': - erts_set_user_requested_filename_encoding(ERL_FILENAME_UTF8); + switch (*(argv[i]+4)) { + case 'w': + case 0: + break; + case 'i': + warning_type = ERL_FILENAME_WARNING_IGNORE; + break; + case 'e': + warning_type = ERL_FILENAME_WARNING_ERROR; + break; + default: + erts_fprintf(stderr, "bad type of warnings for " + "wrongly coded filename: %s\n", argv[i]+4); + erts_usage(); + } + erts_set_user_requested_filename_encoding + ( + ERL_FILENAME_UTF8, + warning_type + ); break; case 'l': - erts_set_user_requested_filename_encoding(ERL_FILENAME_LATIN1); + erts_set_user_requested_filename_encoding + ( + ERL_FILENAME_LATIN1, + warning_type + ); break; case 'a': - erts_set_user_requested_filename_encoding(ERL_FILENAME_UNKNOWN); + switch (*(argv[i]+4)) { + case 'w': + case 0: + break; + case 'i': + warning_type = ERL_FILENAME_WARNING_IGNORE; + break; + case 'e': + warning_type = ERL_FILENAME_WARNING_ERROR; + break; + default: + erts_fprintf(stderr, "bad type of warnings for " + "wrongly coded filename: %s\n", argv[i]+4); + erts_usage(); + } + erts_set_user_requested_filename_encoding + ( + ERL_FILENAME_UNKNOWN, + warning_type + ); break; default: - erts_fprintf(stderr, "bad filename encoding %s, can be (l,u or a)\n", arg); + erts_fprintf(stderr, "bad filename encoding %s, can be " + "(l,u or a, optionally followed by w, " + "i or e)\n", arg); erts_usage(); } break; diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c index 99108af937..80982f3760 100644 --- a/erts/emulator/beam/erl_unicode.c +++ b/erts/emulator/beam/erl_unicode.c @@ -2573,8 +2573,20 @@ BIF_RETTYPE prim_file_internal_native2name_1(BIF_ALIST_1) case ERL_FILENAME_UTF8: bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc); if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK) { + Eterm *hp = HAlloc(BIF_P,3); + Eterm warn_type = NIL; erts_free_aligned_binary_bytes(temp_alloc); - goto noconvert; + switch (erts_get_filename_warning_type()) { + case ERL_FILENAME_WARNING_IGNORE: + warn_type = am_ignore; + break; + case ERL_FILENAME_WARNING_ERROR: + warn_type = am_error; + break; + default: + warn_type = am_warning; + } + BIF_RET(TUPLE2(hp,am_error,warn_type)); } num_built = 0; num_eaten = 0; @@ -2607,9 +2619,8 @@ BIF_RETTYPE prim_file_internal_native2name_1(BIF_ALIST_1) erts_free_aligned_binary_bytes(temp_alloc); BIF_RET(ret); default: - goto noconvert; + break; } - noconvert: BIF_RET(BIF_ARG_1); } @@ -2646,6 +2657,52 @@ BIF_RETTYPE prim_file_internal_normalize_utf8_1(BIF_ALIST_1) BIF_RET(ret); } +BIF_RETTYPE prim_file_is_translatable_1(BIF_ALIST_1) +{ + ERTS_DECLARE_DUMMY(Eterm real_bin); + ERTS_DECLARE_DUMMY(Uint offset); + Uint size; + Uint num_chars; + Uint bitsize; + ERTS_DECLARE_DUMMY(Uint bitoffs); + byte *temp_alloc = NULL; + byte *bytes; + byte *err_pos; + int status; + + if (is_not_binary(BIF_ARG_1)) { + BIF_ERROR(BIF_P,BADARG); + } + size = binary_size(BIF_ARG_1); + ERTS_GET_REAL_BIN(BIF_ARG_1, real_bin, offset, bitoffs, bitsize); + if (bitsize != 0) { + BIF_ERROR(BIF_P,BADARG); + } + if (size == 0) { + BIF_RET(am_true); + } + + /* + * If the encoding is latin1, the pathname is always translatable. + */ + switch (erts_get_native_filename_encoding()) { + case ERL_FILENAME_LATIN1: + BIF_RET(am_true); + case ERL_FILENAME_WIN_WCHAR: + if (erts_get_user_requested_filename_encoding() == ERL_FILENAME_LATIN1) { + BIF_RET(am_true); + } + } + + /* + * Check whether the binary contains legal UTF-8 sequences. + */ + bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc); + status = erts_analyze_utf8(bytes, size, &err_pos, &num_chars, NULL); + erts_free_aligned_binary_bytes(temp_alloc); + BIF_RET(status == ERTS_UTF8_OK ? am_true : am_false); +} + BIF_RETTYPE file_native_name_encoding_0(BIF_ALIST_0) { switch (erts_get_native_filename_encoding()) { diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab index 6764e88c81..8a79b4910e 100644 --- a/erts/emulator/beam/ops.tab +++ b/erts/emulator/beam/ops.tab @@ -1021,7 +1021,7 @@ bif0 u$bif:erlang:node/0 Dst=d => node Dst bif1 Fail Bif=u$bif:erlang:get/1 Src=s Dst=d => i_get Src Dst -bif2 Jump=j u$bif:erlang:element/2 S1=s S2=s Dst=d => gen_element(Jump, S1, S2, Dst) +bif2 Jump=j u$bif:erlang:element/2 S1=s S2=rxy Dst=d => gen_element(Jump, S1, S2, Dst) bif1 Fail Bif Literal=q Dst => move Literal x | bif1 Fail Bif x Dst bif1 p Bif S1 Dst => bif1_body Bif S1 Dst diff --git a/erts/emulator/beam/packet_parser.c b/erts/emulator/beam/packet_parser.c index 1e301e3593..7c9b2d444a 100644 --- a/erts/emulator/beam/packet_parser.c +++ b/erts/emulator/beam/packet_parser.c @@ -67,7 +67,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) #define HTTP_HDR_HASH_SIZE 53 #define HTTP_METH_HASH_SIZE 13 -#define HTTP_MAX_NAME_LEN 20 +#define HTTP_MAX_NAME_LEN 50 static char tspecial[128]; diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index 249a9c05c2..9416a91480 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -1029,10 +1029,22 @@ char* win32_errorstr(int); #define ERL_FILENAME_UTF8_MAC (3) #define ERL_FILENAME_WIN_WCHAR (4) +/************************************************************************ + * If a filename in for example list_dir is not in the right encoding, it + * will be skipped in the resulting list, but depending on a startup setting + * we will inform the user in different ways. These macros define the + * different reactions to wrongly coded filenames. In the error case an + * exception will be thrown by prim_file. + ************************************************************************/ +#define ERL_FILENAME_WARNING_WARNING (0) +#define ERL_FILENAME_WARNING_IGNORE (1) +#define ERL_FILENAME_WARNING_ERROR (2) + int erts_get_native_filename_encoding(void); /* The set function is only to be used by erl_init! */ -void erts_set_user_requested_filename_encoding(int encoding); +void erts_set_user_requested_filename_encoding(int encoding, int warning); int erts_get_user_requested_filename_encoding(void); +int erts_get_filename_warning_type(void); void erts_init_sys_common_misc(void); diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c index fda6cf2e53..2279fec72a 100644 --- a/erts/emulator/drivers/common/efile_drv.c +++ b/erts/emulator/drivers/common/efile_drv.c @@ -2263,6 +2263,8 @@ file_stop(ErlDrvData e) desc->fd = FILE_FD_INVALID; desc->flags = 0; cq_execute(desc); + } else { + EF_FREE(desc); } } else { if (desc->fd != FILE_FD_INVALID) { diff --git a/erts/emulator/sys/common/erl_sys_common_misc.c b/erts/emulator/sys/common/erl_sys_common_misc.c index 1bf5fa89f4..0b31c125e5 100644 --- a/erts/emulator/sys/common/erl_sys_common_misc.c +++ b/erts/emulator/sys/common/erl_sys_common_misc.c @@ -47,14 +47,16 @@ /* Written once and only once */ static int filename_encoding = ERL_FILENAME_UNKNOWN; +static int filename_warning = ERL_FILENAME_WARNING_WARNING; #if defined(__WIN32__) || defined(__DARWIN__) static int user_filename_encoding = ERL_FILENAME_UTF8; /* Default unicode on windows */ #else static int user_filename_encoding = ERL_FILENAME_LATIN1; #endif -void erts_set_user_requested_filename_encoding(int encoding) +void erts_set_user_requested_filename_encoding(int encoding, int warning) { user_filename_encoding = encoding; + filename_warning = warning; } int erts_get_user_requested_filename_encoding(void) @@ -62,6 +64,11 @@ int erts_get_user_requested_filename_encoding(void) return user_filename_encoding; } +int erts_get_filename_warning_type(void) +{ + return filename_warning; +} + void erts_init_sys_common_misc(void) { #if defined(__WIN32__) @@ -107,9 +114,9 @@ int erts_get_native_filename_encoding(void) } /* For internal use by sys_double_to_chars_fast() */ -static char* float_first_trailing_zero(char* p) +static char* find_first_trailing_zero(char* p) { - for (--p; *p == '0' && *(p-1) == '0'; --p); + for (; *(p-1) == '0'; --p); if (*(p-1) == '.') ++p; return p; } @@ -120,34 +127,83 @@ sys_double_to_chars(double fp, char *buffer, size_t buffer_size) return sys_double_to_chars_ext(fp, buffer, buffer_size, SYS_DEFAULT_FLOAT_DECIMALS); } +/* Convert float to string using fixed point notation. + * decimals must be >= 0 + * if compact != 0, the trailing 0's will be truncated + */ int -sys_double_to_chars_fast(double f, char *outbuf, int maxlen, int decimals, int compact) +sys_double_to_chars_fast(double f, char *buffer, int buffer_size, int decimals, + int compact) { - enum { - FRAC_SIZE = 52 - , EXP_SIZE = 11 - , EXP_MASK = (1ll << EXP_SIZE) - 1 - , FRAC_MASK = (1ll << FRAC_SIZE) - 1 - , FRAC_MASK2 = (1ll << (FRAC_SIZE + 1)) - 1 - , MAX_FLOAT = 1ll << (FRAC_SIZE+1) + /* Note that some C compilers don't support "static const" propagation + * so we use a defines */ + #define SYS_DOUBLE_RND_CONST 0.55555555555555555 + #define FRAC_SIZE 52 + #define EXP_SIZE 11 + #define EXP_MASK ((1ll << EXP_SIZE) - 1) + #define MAX_DECIMALS (sizeof(cs_sys_double_pow10) \ + / sizeof(cs_sys_double_pow10[0])) + #define FRAC_MASK ((1ll << FRAC_SIZE) - 1) + #define FRAC_MASK2 ((1ll << (FRAC_SIZE + 1)) - 1) + #define MAX_FLOAT (1ll << (FRAC_SIZE+1)) + + static const double cs_sys_double_pow10[] = { + SYS_DOUBLE_RND_CONST / 1ll, + SYS_DOUBLE_RND_CONST / 10ll, + SYS_DOUBLE_RND_CONST / 100ll, + SYS_DOUBLE_RND_CONST / 1000ll, + SYS_DOUBLE_RND_CONST / 10000ll, + SYS_DOUBLE_RND_CONST / 100000ll, + SYS_DOUBLE_RND_CONST / 1000000ll, + SYS_DOUBLE_RND_CONST / 10000000ll, + SYS_DOUBLE_RND_CONST / 100000000ll, + SYS_DOUBLE_RND_CONST / 1000000000ll, + SYS_DOUBLE_RND_CONST / 10000000000ll, + SYS_DOUBLE_RND_CONST / 100000000000ll, + SYS_DOUBLE_RND_CONST / 1000000000000ll, + SYS_DOUBLE_RND_CONST / 10000000000000ll, + SYS_DOUBLE_RND_CONST / 100000000000000ll, + SYS_DOUBLE_RND_CONST / 1000000000000000ll, + SYS_DOUBLE_RND_CONST / 10000000000000000ll, + SYS_DOUBLE_RND_CONST / 100000000000000000ll, + SYS_DOUBLE_RND_CONST / 1000000000000000000ll }; - long long mantissa, int_part, int_part2, frac_part; + long long mantissa, int_part = 0, frac_part = 0; short exp; - int sign, i, n, m, max; - double absf; + int max; + int neg; + double fr; union { long long L; double F; } x; - char c, *p = outbuf; - int digit, roundup; + char *p = buffer; + + if (decimals < 0) + return -1; - x.F = f; + /* Round the number to given decimal places. The number of 5's in the + * SYS_DOUBLE_RND_CONST constant is chosen such that adding any more 5's doesn't + * change the double precision of the number, i.e.: + * 1> term_to_binary(0.55555555555555555, [{minor_version, 1}]). + * <<131,70,63,225,199,28,113,199,28,114>> + * 2> term_to_binary(0.5555555555555555555, [{minor_version, 1}]). + * <<131,70,63,225,199,28,113,199,28,114>> + */ + if (f >= 0) { + neg = 0; + fr = decimals < MAX_DECIMALS ? (f + cs_sys_double_pow10[decimals]) : f; + x.F = fr; + } else { + neg = 1; + fr = decimals < MAX_DECIMALS ? (f - cs_sys_double_pow10[decimals]) : f; + x.F = -fr; + } exp = (x.L >> FRAC_SIZE) & EXP_MASK; mantissa = x.L & FRAC_MASK; - sign = x.L >= 0 ? 1 : -1; + if (exp == EXP_MASK) { if (mantissa == 0) { - if (sign == -1) + if (neg) *p++ = '-'; *p++ = 'i'; *p++ = 'n'; @@ -158,101 +214,79 @@ sys_double_to_chars_fast(double f, char *outbuf, int maxlen, int decimals, int c *p++ = 'n'; } *p = '\0'; - return p - outbuf; + return p - buffer; } exp -= EXP_MASK >> 1; mantissa |= (1ll << FRAC_SIZE); - frac_part = 0; - int_part = 0; - absf = f * sign; - - /* Don't bother with optimizing too large numbers and decimals */ - if (absf > MAX_FLOAT || decimals > maxlen-17) { - int len = erts_snprintf(outbuf, maxlen, "%.*f", decimals, f); - if (len >= maxlen) + + /* Don't bother with optimizing too large numbers or too large precision */ + if (x.F > MAX_FLOAT || decimals >= MAX_DECIMALS) { + int len = erts_snprintf(buffer, buffer_size, "%.*f", decimals, f); + char* p = buffer + len; + if (len >= buffer_size) return -1; - p = outbuf + len; /* Delete trailing zeroes */ if (compact) - p = float_first_trailing_zero(outbuf + len); + p = find_first_trailing_zero(p); *p = '\0'; - return p - outbuf; - } - - if (exp >= FRAC_SIZE) + return p - buffer; + } else if (exp >= FRAC_SIZE) { int_part = mantissa << (exp - FRAC_SIZE); - else if (exp >= 0) { + } else if (exp >= 0) { int_part = mantissa >> (FRAC_SIZE - exp); frac_part = (mantissa << (exp + 1)) & FRAC_MASK2; - } - else /* if (exp < 0) */ + } else /* if (exp < 0) */ { frac_part = (mantissa & FRAC_MASK2) >> -(exp + 1); + } - if (int_part == 0) { - if (sign == -1) + if (!int_part) { + if (neg) *p++ = '-'; *p++ = '0'; } else { - int ret; + int ret, i, n; while (int_part != 0) { - int_part2 = int_part / 10; - *p++ = (char)(int_part - ((int_part2 << 3) + (int_part2 << 1)) + '0'); - int_part = int_part2; + long long j = int_part / 10; + *p++ = (char)(int_part - ((j << 3) + (j << 1)) + '0'); + int_part = j; } - if (sign == -1) + if (neg) *p++ = '-'; /* Reverse string */ - ret = p - outbuf; + ret = p - buffer; for (i = 0, n = ret/2; i < n; i++) { - int j = ret - i - 1; - c = outbuf[i]; - outbuf[i] = outbuf[j]; - outbuf[j] = c; + int j = ret - i - 1; + char c = buffer[i]; + buffer[i] = buffer[j]; + buffer[j] = c; } } - if (decimals != 0) + + if (decimals > 0) { + int i; *p++ = '.'; - max = maxlen - (p - outbuf) - 1 /* leave room for trailing '\0' */; - if (max > decimals) + max = buffer_size - (p - buffer) - 1 /* leave room for trailing '\0' */; + + if (decimals > max) + return -1; /* the number is not large enough to fit in the buffer */ + max = decimals; - for (m = 0; m < max; m++) { - /* frac_part *= 10; */ - frac_part = (frac_part << 3) + (frac_part << 1); - *p++ = (char)((frac_part >> (FRAC_SIZE + 1)) + '0'); - frac_part &= FRAC_MASK2; - } + for (i = 0; i < max; i++) { + /* frac_part *= 10; */ + frac_part = (frac_part << 3) + (frac_part << 1); - roundup = 0; - /* Rounding - look at the next digit */ - frac_part = (frac_part << 3) + (frac_part << 1); - digit = (frac_part >> (FRAC_SIZE + 1)); - if (digit > 5) - roundup = 1; - else if (digit == 5) { - frac_part &= FRAC_MASK2; - if (frac_part != 0) roundup = 1; - } - if (roundup) { - char d; - int pos = p - outbuf - 1; - do { - d = outbuf[pos]; - if (d == '-') break; - if (d == '.') continue; - if (++d != ':') { - outbuf[pos] = d; - break; - } - outbuf[pos] = '0'; - } while (--pos); + *p++ = (char)((frac_part >> (FRAC_SIZE + 1)) + '0'); + frac_part &= FRAC_MASK2; + } + + /* Delete trailing zeroes */ + if (compact) + p = find_first_trailing_zero(p); } - /* Delete trailing zeroes */ - if (compact && *(p - 1) == '0') - p = float_first_trailing_zero(--p); *p = '\0'; - return p - outbuf; + return p - buffer; } diff --git a/erts/emulator/test/decode_packet_SUITE.erl b/erts/emulator/test/decode_packet_SUITE.erl index 4acbe8c6e0..1714551e15 100644 --- a/erts/emulator/test/decode_packet_SUITE.erl +++ b/erts/emulator/test/decode_packet_SUITE.erl @@ -403,6 +403,9 @@ http_request(Msg) -> {"Other-Field: with some text\r\n", {http_header,0, "Other-Field" ,undefined, "with some text"}, {http_header,0,<<"Other-Field">>,undefined,<<"with some text">>}}, + {"Make-sure-a-LONG-HEaDer-fIeLd-is-fORMATTED-NicelY: with some text\r\n", + {http_header,0, "Make-Sure-A-Long-Header-Field-Is-Formatted-Nicely" ,undefined, "with some text"}, + {http_header,0,<<"Make-Sure-A-Long-Header-Field-Is-Formatted-Nicely">>,undefined,<<"with some text">>}}, {"Multi-Line: Once upon a time in a land far far away,\r\n" " there lived a princess imprisoned in the highest tower\r\n" " of the most haunted castle.\r\n", diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl index bf33c337ee..c625e655ce 100644 --- a/erts/emulator/test/num_bif_SUITE.erl +++ b/erts/emulator/test/num_bif_SUITE.erl @@ -128,10 +128,17 @@ t_float_to_list(Config) when is_list(Config) -> "-1.00000000000000000000e+00" = float_to_list(-1.0, []), "-1.00000000000000000000" = float_to_list(-1.0, [{decimals, 20}]), {'EXIT', {badarg, _}} = (catch float_to_list(1.0, [{decimals, -1}])), - {'EXIT', {badarg, _}} = (catch float_to_list(1.0, [{decimals, 250}])), + {'EXIT', {badarg, _}} = (catch float_to_list(1.0, [{decimals, 254}])), + {'EXIT', {badarg, _}} = (catch float_to_list(1.0, [{scientific, 250}])), {'EXIT', {badarg, _}} = (catch float_to_list(1.0e+300, [{decimals, 1}])), "1.0e+300" = float_to_list(1.0e+300, [{scientific, 1}]), - "1.0" = float_to_list(1.0, [{decimals, 249}, compact]), + "1.0" = float_to_list(1.0, [{decimals, 249}, compact]), + "1" = float_to_list(1.0, [{decimals, 0}]), + "2" = float_to_list(1.9, [{decimals, 0}]), + "123456789012345680.0" = erlang:float_to_list( + 123456789012345678.0, [{decimals, 236}, compact]), + {'EXIT', {badarg, _}} = (catch float_to_list( + 123456789012345678.0, [{decimals, 237}])), Expected = "1." ++ string:copies("0", 249) ++ "e+00", Expected = float_to_list(1.0, [{scientific, 249}, compact]), @@ -139,7 +146,8 @@ t_float_to_list(Config) when is_list(Config) -> X2 = float_to_list(1.0, [{scientific, 20}]), X1 = X2, "1.000e+00" = float_to_list(1.0, [{scientific, 3}]), - "1.000" = float_to_list(1.0, [{decimals, 3}]), + "1.000" = float_to_list(1.0, [{decimals, 3}]), + "1.0" = float_to_list(1.0, [{decimals, 1}]), "1.0" = float_to_list(1.0, [{decimals, 3}, compact]), "1.12" = float_to_list(1.123, [{decimals, 2}]), "1.123" = float_to_list(1.123, [{decimals, 3}]), @@ -148,6 +156,14 @@ t_float_to_list(Config) when is_list(Config) -> "1.12300" = float_to_list(1.123, [{decimals, 5}]), "1.123" = float_to_list(1.123, [{decimals, 5}, compact]), "1.1234" = float_to_list(1.1234,[{decimals, 6}, compact]), + "1.01" = float_to_list(1.005, [{decimals, 2}]), + "-1.01" = float_to_list(-1.005,[{decimals, 2}]), + "0.999" = float_to_list(0.999, [{decimals, 3}]), + "-0.999" = float_to_list(-0.999,[{decimals, 3}]), + "1.0" = float_to_list(0.999, [{decimals, 2}, compact]), + "-1.0" = float_to_list(-0.999,[{decimals, 2}, compact]), + "0.5" = float_to_list(0.5, [{decimals, 1}]), + "-0.5" = float_to_list(-0.5, [{decimals, 1}]), "2.333333" = erlang:float_to_list(7/3, [{decimals, 6}, compact]), "2.333333" = erlang:float_to_list(7/3, [{decimals, 6}]), "0.00000000000000000000e+00" = float_to_list(0.0, [compact]), diff --git a/erts/emulator/utils/gen_git_version b/erts/emulator/utils/gen_git_version new file mode 100755 index 0000000000..d93a97cbbb --- /dev/null +++ b/erts/emulator/utils/gen_git_version @@ -0,0 +1,40 @@ +#!/bin/sh + +OUTPUT_FILE=$1 + +if command -v git 2>&1 >/dev/null && + test -d $ERL_TOP/.git -o -f $ERL_TOP/.git +then + VSN=`git describe --match "OTP_R[0-9][0-9][A-B]*" HEAD` + case "$VSN" in + OTP_R*-g*) + VSN=`echo $VSN | sed -e 's/.*-g\\(.*\\)/\\1/g'` ;; + *) VSN="na" ;; + esac +else + VSN="na" +fi + + +# Only update the file if there has been a change to +# the version number. +if test -r $OUTPUT_FILE +then + VC=`sed -n -e 's/^.*"\\\\"\\(.*\\)\\\\"".*/\\1/p' < $OUTPUT_FILE` +else + VC=unset +fi +echo "VSN = $VSN" +echo "VC = $VC" +if test "$VSN" != "$VC" +then + echo "# Automatically generated by $0 - DO NOT EDIT." > $OUTPUT_FILE + if test "$VSN" = "na" + then + echo "# GIT_VSN=-DERLANG_GIT_VERSION=\"\\\"$VSN\\\"\"" >> $OUTPUT_FILE + else + echo "GIT_VSN=-DERLANG_GIT_VERSION=\"\\\"$VSN\\\"\"" >> $OUTPUT_FILE + fi + exit 0 +fi +exit 1
\ No newline at end of file |