[med-svn] [praat] 01/03: Imported Upstream version 5.4.6
Rafael Laboissière
rlaboiss-guest at moszumanska.debian.org
Sat Mar 14 22:36:30 UTC 2015
This is an automated email from the git hooks/post-receive script.
rlaboiss-guest pushed a commit to branch master
in repository praat.
commit 8f11966720af2013a5f8e424efb4b3ee21fc7ec0
Author: Rafael Laboissiere <rafael at laboissiere.net>
Date: Sat Mar 14 17:33:19 2015 -0300
Imported Upstream version 5.4.6
---
dwtools/LongSound_extensions.cpp | 3 +-
dwtools/Sound_extensions.cpp | 14 +-
external/espeak/speech.h | 2 +-
external/flac/flac_share_alloc.h | 2 +
external/mp3/mp3.cpp | 4 +
fon/Matrix.cpp | 6 +-
fon/Pitch.cpp | 2 +-
fon/Praat_tests.cpp | 34 +-
fon/Praat_tests_enums.h | 8 +-
fon/Sampled_def.h | 2 +-
fon/Sound_files.cpp | 41 +--
fon/TimeSoundAnalysisEditor.cpp | 50 +--
fon/WordList.cpp | 12 +-
fon/manual_tutorials.cpp | 7 +-
fon/praat_Sound_init.cpp | 2 +-
main/main_Praat.cpp | 11 +-
sys/Collection.cpp | 58 ++--
sys/Graphics.cpp | 2 +
sys/GraphicsScreen.cpp | 2 +-
sys/Graphics_enums.h | 13 +-
sys/Graphics_record.cpp | 8 +-
sys/Graphics_text.cpp | 43 ++-
sys/GuiList.cpp | 6 +-
sys/GuiMenu.cpp | 2 +-
sys/GuiText.cpp | 16 +-
sys/TextEditor.cpp | 4 +-
sys/abcio.cpp | 680 +++++++++++++++++++++------------------
sys/abcio.h | 28 +-
sys/melder.cpp | 2 +-
sys/melder.h | 417 ++++++++++++++----------
sys/melder_alloc.cpp | 97 ++++--
sys/melder_audiofiles.cpp | 459 ++++++++++++++++----------
sys/melder_debug.cpp | 20 +-
sys/melder_files.cpp | 32 +-
sys/melder_ftoa.cpp | 38 ++-
sys/melder_readtext.cpp | 86 ++---
sys/melder_strings.cpp | 208 ++++++------
sys/melder_textencoding.cpp | 350 ++++++++++++--------
sys/melder_writetext.cpp | 262 +++++++--------
sys/oo.h | 9 +-
sys/oo_DESCRIPTION.h | 4 +-
sys/oo_READ_BINARY.h | 4 +-
sys/praat.cpp | 10 +
sys/praat_logo.cpp | 6 +-
sys/praat_objectMenus.cpp | 2 +-
sys/praat_version.h | 10 +-
test/fon/data.praat | Bin 6455 -> 13426 bytes
test/fon/soundFiles.praat | 9 +
test/runAllTests.praat | 33 +-
49 files changed, 1827 insertions(+), 1293 deletions(-)
diff --git a/dwtools/LongSound_extensions.cpp b/dwtools/LongSound_extensions.cpp
index 020ad1c..a8175fa 100644
--- a/dwtools/LongSound_extensions.cpp
+++ b/dwtools/LongSound_extensions.cpp
@@ -198,7 +198,8 @@ void LongSounds_appendToExistingSoundFile (Collection me, MelderFile file) {
autofile f = Melder_fopen (file, "r+b");
file -> filePointer = f; // essential !!
double sampleRate_d;
- long startOfData, numberOfSamples;
+ long startOfData;
+ int32 numberOfSamples;
int numberOfChannels, encoding;
int audioFileType = MelderFile_checkSoundFile (file, &numberOfChannels,
&encoding, &sampleRate_d, &startOfData, &numberOfSamples);
diff --git a/dwtools/Sound_extensions.cpp b/dwtools/Sound_extensions.cpp
index 35916af..8d174d5 100644
--- a/dwtools/Sound_extensions.cpp
+++ b/dwtools/Sound_extensions.cpp
@@ -158,7 +158,7 @@ static void u1read (Sound me, FILE *f) {
static void i2write (Sound me, FILE *f, int littleEndian, long *nClip) {
double *s = my z[1], min = -32768, max = 32767;
- void (*put) (int, FILE *) = littleEndian ? binputi2LE : binputi2;
+ void (*put) (int16_t, FILE *) = littleEndian ? binputi2LE : binputi2;
*nClip = 0;
for (long i = 1; i <= my nx; i++) {
double sample = floor (s[i] * 32768 + 0.5);
@@ -175,7 +175,7 @@ static void i2write (Sound me, FILE *f, int littleEndian, long *nClip) {
static void i2read (Sound me, FILE *f, int littleEndian) {
double *s = my z[1];
- int (*get) (FILE *) = littleEndian ? bingeti2LE : bingeti2;
+ int16_t (*get) (FILE *) = littleEndian ? bingeti2LE : bingeti2;
for (long i = 1; i <= my nx; i++) {
s[i] = get (f) / 32768.;
}
@@ -183,7 +183,7 @@ static void i2read (Sound me, FILE *f, int littleEndian) {
static void u2write (Sound me, FILE *f, int littleEndian, long *nClip) {
double *s = my z[1], min = 0, max = 65535;
- void (*put) (unsigned int, FILE *) = littleEndian ? binputu2LE : binputu2;
+ void (*put) (uint16_t, FILE *) = littleEndian ? binputu2LE : binputu2;
*nClip = 0;
for (long i = 1; i <= my nx; i++) {
double sample = floor ( (s[i] + 1) * 65535 / 2 + 0.5);
@@ -208,7 +208,7 @@ static void u2read (Sound me, FILE *f, int littleEndian) {
static void i4write (Sound me, FILE *f, int littleEndian, long *nClip) {
double *s = my z[1]; double min = -2147483648.0, max = 2147483647.0;
- void (*put) (long, FILE *) = littleEndian ? binputi4LE : binputi4;
+ void (*put) (int32_t, FILE *) = littleEndian ? binputi4LE : binputi4;
*nClip = 0;
for (long i = 1; i <= my nx; i++) {
double sample = floor (s[i] * 2147483648.0 + 0.5);
@@ -225,7 +225,7 @@ static void i4write (Sound me, FILE *f, int littleEndian, long *nClip) {
static void i4read (Sound me, FILE *f, int littleEndian) {
double *s = my z[1];
- long (*get) (FILE *) = littleEndian ? bingeti4LE : bingeti4;
+ int32_t (*get) (FILE *) = littleEndian ? bingeti4LE : bingeti4;
for (long i = 1; i <= my nx; i++) {
s[i] = get (f) / 2147483648.;
}
@@ -234,7 +234,7 @@ static void i4read (Sound me, FILE *f, int littleEndian) {
static void u4write (Sound me, FILE *f, int littleEndian, long *nClip) {
double *s = my z[1]; double min = 0.0, max = 4294967295.0;
- void (*put) (unsigned long, FILE *) = littleEndian ? binputu4LE : binputu4;
+ void (*put) (uint32_t, FILE *) = littleEndian ? binputu4LE : binputu4;
*nClip = 0;
for (long i = 1; i <= my nx; i++) {
double sample = floor (s[i] * 4294967295.0 + 0.5);
@@ -251,7 +251,7 @@ static void u4write (Sound me, FILE *f, int littleEndian, long *nClip) {
static void u4read (Sound me, FILE *f, int littleEndian) {
double *s = my z[1];
- long (*get) (FILE *) = littleEndian ? bingeti4LE : bingeti4;
+ int32_t (*get) (FILE *) = littleEndian ? bingeti4LE : bingeti4;
for (long i = 1; i <= my nx; i++) {
s[i] = get (f) / 2147483648.0 - 1.0;
}
diff --git a/external/espeak/speech.h b/external/espeak/speech.h
index 24c8bfd..7f1dc96 100644
--- a/external/espeak/speech.h
+++ b/external/espeak/speech.h
@@ -26,7 +26,7 @@
#ifdef _WIN32
wchar_t * Melder_peekUtf8ToWcs (const char *string);
- const utf16_t * Melder_peekWcsToUtf16 (const wchar_t *string);
+ const uint16_t * Melder_peekWcsToUtf16 (const wchar_t *string);
#endif
// conditional compilation options
diff --git a/external/flac/flac_share_alloc.h b/external/flac/flac_share_alloc.h
index 34cde29..c746d61 100644
--- a/external/flac/flac_share_alloc.h
+++ b/external/flac/flac_share_alloc.h
@@ -33,6 +33,7 @@
#endif
#include <stdlib.h> /* for size_t, malloc(), etc */
+/* ppgb 20141231
#ifndef SIZE_MAX
# ifndef SIZE_T_MAX
# ifdef _MSC_VER
@@ -43,6 +44,7 @@
# endif
# define SIZE_MAX SIZE_T_MAX
#endif
+*/
#ifndef FLaC__INLINE
#define FLaC__INLINE inline // ppgb 20071120
diff --git a/external/mp3/mp3.cpp b/external/mp3/mp3.cpp
index c110c45..c7b7191 100644
--- a/external/mp3/mp3.cpp
+++ b/external/mp3/mp3.cpp
@@ -273,6 +273,7 @@ int mp3f_analyze (MP3_FILE mp3f)
last * mp3f -> samples_per_frame / (float)mp3f -> frequency));
#endif /* MP3_DEBUG */
+if(status!=-1) // ppgb 2015-01-17
mp3f_seek (mp3f, 0);
end:
@@ -323,12 +324,15 @@ int mp3f_seek (MP3_FILE mp3f, MP3F_OFFSET sample)
-- frame;
if ( frame ) /* ...and the first frame it decodes is useless */
-- frame;
+Melder_assert (mp3f -> frames_per_location > 0);
+Melder_assert (mp3f -> num_locations > 0);
location = frame / mp3f -> frames_per_location;
if (location >= mp3f -> num_locations)
location = mp3f -> num_locations - 1;
frame = location * mp3f -> frames_per_location;
base = frame * mp3f -> samples_per_frame;
+Melder_assert (location >= 0);
offset = mp3f -> locations [location];
if (fseek (mp3f -> f, offset, SEEK_SET) < 0)
return 0;
diff --git a/fon/Matrix.cpp b/fon/Matrix.cpp
index 0e6705a..85db3bc 100644
--- a/fon/Matrix.cpp
+++ b/fon/Matrix.cpp
@@ -436,10 +436,10 @@ void Matrix_movie (Matrix me, Graphics g) {
Matrix Matrix_readAP (MelderFile file) {
try {
autofile f = Melder_fopen (file, "rb");
- short header [256];
+ int16_t header [256];
for (long i = 0; i < 256; i ++)
header [i] = bingeti2LE (f);
- double samplingFrequency = header [100];
+ double samplingFrequency = header [100]; // converting up (from 16 to 54 bytes)
Melder_casual ("Sampling frequency %.10g.", samplingFrequency);
autoMatrix me = Matrix_create (0, header [34], header [34] /* Number of frames. */, 1, 0.5,
0, header [35], header [35] /* Number of words per frame. */, 1, 0.5);
@@ -451,7 +451,7 @@ Matrix Matrix_readAP (MelderFile file) {
Melder_casual ("... Loading %d frames of %d words ...", header [34], header [35]);
for (long i = 1; i <= my nx; i ++)
for (long j = 1; j <= my ny; j ++)
- my z [j] [i] = bingeti2LE (f);
+ my z [j] [i] = bingeti2LE (f); // converting up (from 16 to 54 bytes)
/*
* Get pitch frequencies.
diff --git a/fon/Pitch.cpp b/fon/Pitch.cpp
index 0a3fb9f..7f3ed01 100644
--- a/fon/Pitch.cpp
+++ b/fon/Pitch.cpp
@@ -753,7 +753,7 @@ Pitch Pitch_smooth (Pitch me, double bandWidth) {
long firstVoiced = 0, lastVoiced = 0;
for (long i = 1; i <= matrix1 -> nx; i ++) {
double f = matrix1 -> z [1] [i];
- if (f) {
+ if (f != 0.0) {
if (! firstVoiced) firstVoiced = i;
lastVoiced = i;
sound1 -> z [1] [i + matrix1 -> nx] = f;
diff --git a/fon/Praat_tests.cpp b/fon/Praat_tests.cpp
index f266d55..41a738c 100644
--- a/fon/Praat_tests.cpp
+++ b/fon/Praat_tests.cpp
@@ -14,7 +14,7 @@
int Praat_tests (int itest, wchar_t *arg1, wchar_t *arg2, wchar_t *arg3, wchar_t *arg4) {
- long i, n = wcstol (arg1, NULL, 10);
+ unsigned long i, n = wcstoul (arg1, NULL, 10);
double x, t;
(void) arg1;
(void) arg2;
@@ -58,6 +58,38 @@ int Praat_tests (int itest, wchar_t *arg1, wchar_t *arg2, wchar_t *arg3, wchar_t
t = Melder_stopwatch ();
MelderInfo_writeLine (Melder_double (sum));
} break;
+ case kPraatTests_TIME_FLOAT_TO_UNSIGNED_BUILTIN: {
+ uint64_t sum = 0;
+ double fn = n;
+ for (double fi = 1.0; fi <= fn; fi = fi + 1.0)
+ sum += (uint32_t) fi;
+ t = Melder_stopwatch (); // 2.59 // 1.60
+ MelderInfo_writeLine (Melder_double (sum));
+ } break;
+ case kPraatTests_TIME_FLOAT_TO_UNSIGNED_EXTERN: {
+ uint64_t sum = 0;
+ double fn = n;
+ for (double fi = 1.0; fi <= fn; fi = fi + 1.0)
+ sum += (uint32_t) ((int32_t) (fi - 2147483648.0) + 2147483647L + 1);
+ t = Melder_stopwatch (); // 1.60
+ MelderInfo_writeLine (Melder_double (sum));
+ } break;
+ case kPraatTests_TIME_UNSIGNED_TO_FLOAT_BUILTIN: {
+ double sum = 0.0;
+ uint32_t nu = (uint32_t) n;
+ for (uint32_t iu = 1; iu <= nu; iu ++)
+ sum += (double) iu;
+ t = Melder_stopwatch (); // 1.35
+ MelderInfo_writeLine (Melder_double (sum));
+ } break;
+ case kPraatTests_TIME_UNSIGNED_TO_FLOAT_EXTERN: {
+ double sum = 0.0;
+ uint32_t nu = (uint32_t) n;
+ for (uint32_t iu = 1; iu <= nu; iu ++)
+ sum += (double) (int32_t) (iu - 2147483647L - 1) + 2147483648.0;
+ t = Melder_stopwatch (); // 0.96
+ MelderInfo_writeLine (Melder_double (sum));
+ } break;
}
MelderInfo_writeLine (Melder_single (t / n * 1e9), L" nanoseconds");
MelderInfo_close ();
diff --git a/fon/Praat_tests_enums.h b/fon/Praat_tests_enums.h
index bd746ed..0039524 100644
--- a/fon/Praat_tests_enums.h
+++ b/fon/Praat_tests_enums.h
@@ -1,5 +1,5 @@
/* Praat_tests_enums.h */
-/* Paul Boersma, 16 June 2014 */
+/* Paul Boersma, 2 January 2015 */
enums_begin (kPraatTests, 0)
enums_add (kPraatTests, 0, _, L"_")
@@ -9,6 +9,10 @@ enums_begin (kPraatTests, 0)
enums_add (kPraatTests, 4, TIME_SORT, L"TimeSort")
enums_add (kPraatTests, 5, TIME_INTEGER, L"TimeInteger")
enums_add (kPraatTests, 6, TIME_FLOAT, L"TimeFloat")
-enums_end (kPraatTests, 6, CHECK_RANDOM_1009_2009)
+ enums_add (kPraatTests, 7, TIME_FLOAT_TO_UNSIGNED_BUILTIN, L"TimeFloatToUnsigned_builtin")
+ enums_add (kPraatTests, 8, TIME_FLOAT_TO_UNSIGNED_EXTERN, L"TimeFloatToUnsigned_extern")
+ enums_add (kPraatTests, 9, TIME_UNSIGNED_TO_FLOAT_BUILTIN, L"TimeUnsignedToFloat_builtin")
+ enums_add (kPraatTests, 10, TIME_UNSIGNED_TO_FLOAT_EXTERN, L"TimeUnsignedToFloat_extern")
+enums_end (kPraatTests, 10, CHECK_RANDOM_1009_2009)
/* End of file Praat_tests_enums.h */
diff --git a/fon/Sampled_def.h b/fon/Sampled_def.h
index 9255c29..bce9e20 100644
--- a/fon/Sampled_def.h
+++ b/fon/Sampled_def.h
@@ -21,7 +21,7 @@
#define ooSTRUCT Sampled
oo_DEFINE_CLASS (Sampled, Function)
- oo_LONG (nx)
+ oo_INT32 (nx)
oo_DOUBLE (dx)
oo_DOUBLE (x1)
diff --git a/fon/Sound_files.cpp b/fon/Sound_files.cpp
index f471a7d..8be0de7 100644
--- a/fon/Sound_files.cpp
+++ b/fon/Sound_files.cpp
@@ -1,6 +1,6 @@
/* Sound_files.cpp
*
- * Copyright (C) 1992-2011,2012,2014 Paul Boersma & David Weenink
+ * Copyright (C) 1992-2011,2012,2014,2015 Paul Boersma & David Weenink
*
* 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
@@ -71,7 +71,8 @@ Sound Sound_readFromSoundFile (MelderFile file) {
autoMelderFile mfile = MelderFile_open (file);
int numberOfChannels, encoding;
double sampleRate;
- long startOfData, numberOfSamples;
+ long startOfData;
+ int32 numberOfSamples;
int fileType = MelderFile_checkSoundFile (file, & numberOfChannels, & encoding, & sampleRate, & startOfData, & numberOfSamples);
if (fileType == 0)
Melder_throw ("Not an audio file.");
@@ -91,14 +92,14 @@ Sound Sound_readFromSoundFile (MelderFile file) {
Sound Sound_readFromSesamFile (MelderFile file) {
try {
autofile f = Melder_fopen (file, "rb");
- long header [1 + 128];
+ int32_t header [1 + 128];
for (long i = 1; i <= 128; i ++)
header [i] = bingeti4LE (f);
/*
* Try SESAM header.
*/
- double samplingFrequency = header [126];
- long numberOfSamples = header [127];
+ double samplingFrequency = header [126]; // converting up (from 32 to 54 bits)
+ int32_t numberOfSamples = header [127];
if (samplingFrequency == 0.0 || numberOfSamples == 0) {
/*
* Try LVS header.
@@ -109,8 +110,8 @@ Sound Sound_readFromSesamFile (MelderFile file) {
if (numberOfSamples < 1 || numberOfSamples > 1000000000 || samplingFrequency < 10.0 || samplingFrequency > 100000000.0)
Melder_throw ("Not a correct SESAM or LVS file.");
autoSound me = Sound_createSimple (1, numberOfSamples / samplingFrequency, samplingFrequency);
- for (long i = 1; i <= numberOfSamples; i ++) {
- my z [1] [i] = bingeti2LE (f) * (1.0 / 2048); // 12 bits
+ for (int32_t i = 1; i <= numberOfSamples; i ++) {
+ my z [1] [i] = (double) bingeti2LE (f) * (1.0 / 2048); // 12 bits
}
f.close (file);
return me.transfer();
@@ -135,7 +136,7 @@ Sound Sound_readFromBellLabsFile (MelderFile file) {
char *endOfTag = strchr (tag + 4, '\n');
if (endOfTag == NULL)
Melder_throw ("Second line missing or too long.");
- unsigned long tagLength = endOfTag - tag + 1; // probably 12
+ unsigned long tagLength = (endOfTag - tag) + 1; // probably 12
unsigned long headerLength = atol (tag + 4);
if (headerLength <= 0)
Melder_throw ("Wrong header-length info.");
@@ -175,7 +176,7 @@ Sound Sound_readFromBellLabsFile (MelderFile file) {
*/
fseek (f, tagLength + headerLength, SEEK_SET);
for (unsigned long i = 1; i <= numberOfSamples; i ++)
- my z [1] [i] = bingeti2 (f) * (1.0 / 32768); // 16-bits big-endian
+ my z [1] [i] = (double) bingeti2 (f) * (1.0 / 32768); // 16-bits big-endian
f.close (file);
return me.transfer();
@@ -204,17 +205,17 @@ Sound Sound_readFromKayFile (MelderFile file) {
if (fread (data, 1, 4, f) < 4) readError ();
if (! strnequ (data, "HEDR", 4) && ! strnequ (data, "HDR8", 4))
Melder_throw ("Missing HEDR or HDR8 chunk. Please report to paul.boersma at uva.nl.");
- unsigned long chunkSize = bingetu4LE (f);
+ uint32_t chunkSize = bingetu4LE (f);
if (chunkSize & 1) ++ chunkSize;
if (chunkSize != 32 && chunkSize != 44)
Melder_throw ("Unknown chunk size %ld. Please report to paul.boersma at uva.nl.", chunkSize);
if (fread (data, 1, 20, f) < 20) readError ();
- double samplingFrequency = bingetu4LE (f);
- unsigned long numberOfSamples = bingetu4LE (f);
+ double samplingFrequency = bingetu4LE (f); // converting up (from 32 to 53 bits)
+ uint32_t numberOfSamples = bingetu4LE (f);
if (samplingFrequency <= 0 || samplingFrequency > 1e7 || numberOfSamples >= 1000000000)
Melder_throw ("Not a correct Kay file.");
- signed int tmp1 = bingeti2LE (f);
- signed int tmp2 = bingeti2LE (f);
+ int16_t tmp1 = bingeti2LE (f);
+ int16_t tmp2 = bingeti2LE (f);
long numberOfChannels = tmp1 == -1 || tmp2 == -1 ? 1 : 2;
if (chunkSize == 44)
if (fread (data, 1, 12, f) < 12) readError ();
@@ -237,7 +238,7 @@ Sound Sound_readFromKayFile (MelderFile file) {
autoSound me = Sound_createSimple (numberOfChannels, numberOfSamples / samplingFrequency, samplingFrequency);
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
for (unsigned long i = 1; i <= numberOfSamples; i ++) {
- my z [ichan] [i] = bingeti2LE (f) / 32768.0;
+ my z [ichan] [i] = (double) bingeti2LE (f) / 32768.0;
}
}
f.close (file);
@@ -284,17 +285,17 @@ void Sound_writeToSesamFile (Sound me, MelderFile file) {
header [6] = ((my nx - 1) >> 8) + 1; /* Number of disk blocks. */
header [64] = 32149; /* ILS magic. */
/* LVS header. */
- header [62] = floor (1 / my dx + 0.5); /* Sampling frequency, rounded to n Hz. */
+ header [62] = round (1 / my dx); /* Sampling frequency, rounded to n Hz. */
header [63] = -32000; /* Magic: "sampled signal." */
header [66] = 2047; /* Maximum absolute value: 12 bits. */
header [67] = 2047; /* LVS magic. */
header [68] = my nx % 256; /* Number of samples in last block. */
header [69] = 1; /* ? */
/* Sesam header. */
- header [126] = floor (1 / my dx + 0.5); /* Sampling frequency, rounded to n Hz. */
+ header [126] = round (1 / my dx); /* Sampling frequency, rounded to n Hz. */
header [127] = my nx; /* Number of samples. */
for (long i = 1; i <= 128; i ++) binputi4LE (header [i], f);
- for (long i = 1; i <= my nx; i ++) binputi2LE (floor (my z [1] [i] * 2048 + 0.5), f);
+ for (long i = 1; i <= my nx; i ++) binputi2LE (round (my z [1] [i] * 2048), f);
tail = 256 - my nx % 256;
if (tail == 256) tail = 0;
for (long i = 1; i <= tail; i ++) binputi2LE (0, f); /* Pad last block with zeroes. */
@@ -319,7 +320,7 @@ void Sound_writeToKayFile (Sound me, MelderFile file) {
strcpy (date, ctime (& today));
fwrite (date+4, 1, 20, file -> filePointer); // skip weekday
- binputi4LE (floor (1 / my dx + 0.5), file -> filePointer); // sampling frequency
+ binputi4LE (round (1 / my dx), file -> filePointer); // sampling frequency
binputi4LE (my nx, file -> filePointer); // number of samples
int maximumA = 0;
for (long i = 1; i <= my nx; i ++) {
@@ -333,7 +334,7 @@ void Sound_writeToKayFile (Sound me, MelderFile file) {
} else {
int maximumB = 0;
for (long i = 1; i <= my nx; i ++) {
- long value = floor (my z [2] [i] * 32768 + 0.5);
+ long value = round (my z [2] [i] * 32768);
if (value < - maximumB) maximumB = - value;
if (value > maximumB) maximumB = value;
}
diff --git a/fon/TimeSoundAnalysisEditor.cpp b/fon/TimeSoundAnalysisEditor.cpp
index 2809c09..8afa1f1 100644
--- a/fon/TimeSoundAnalysisEditor.cpp
+++ b/fon/TimeSoundAnalysisEditor.cpp
@@ -1868,32 +1868,34 @@ static void TimeSoundAnalysisEditor_v_draw_analysis (TimeSoundAnalysisEditor me)
if (! my p_pitch_show) textColour = Graphics_GREEN, alignment = Graphics_LEFT, y = my d_endWindow;
else if (! my p_spectrogram_show && ! my p_formant_show) textColour = Graphics_GREEN, alignment = Graphics_RIGHT, y = my d_startWindow;
else textColour = my p_spectrogram_show ? Graphics_LIME : Graphics_GREEN, alignment = Graphics_RIGHT, y = my d_endWindow;
- Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, my p_intensity_viewFrom, my p_intensity_viewTo);
- if (my d_intensity) {
- if (my d_startSelection == my d_endSelection) {
- intensityCursor = Vector_getValueAtX (my d_intensity, my d_startSelection, Vector_CHANNEL_1, Vector_VALUE_INTERPOLATION_LINEAR);
- } else {
- intensityCursor = Intensity_getAverage (my d_intensity, my d_startSelection, my d_endSelection, my p_intensity_averagingMethod);
+ if (my p_intensity_viewTo > my p_intensity_viewFrom) {
+ Graphics_setWindow (my d_graphics, my d_startWindow, my d_endWindow, my p_intensity_viewFrom, my p_intensity_viewTo);
+ if (my d_intensity) {
+ if (my d_startSelection == my d_endSelection) {
+ intensityCursor = Vector_getValueAtX (my d_intensity, my d_startSelection, Vector_CHANNEL_1, Vector_VALUE_INTERPOLATION_LINEAR);
+ } else {
+ intensityCursor = Intensity_getAverage (my d_intensity, my d_startSelection, my d_endSelection, my p_intensity_averagingMethod);
+ }
}
+ Graphics_setColour (my d_graphics, textColour);
+ intensityCursorVisible = NUMdefined (intensityCursor) && intensityCursor > my p_intensity_viewFrom && intensityCursor < my p_intensity_viewTo;
+ if (intensityCursorVisible) {
+ static const wchar_t *methodString [] = { L" (.5)", L" (μE)", L" (μS)", L" (μ)" };
+ Graphics_setTextAlignment (my d_graphics, alignment, Graphics_HALF);
+ Graphics_text3 (my d_graphics, y, intensityCursor, Melder_float (Melder_half (intensityCursor)), L" dB",
+ my d_startSelection == my d_endSelection ? L"" : methodString [my p_intensity_averagingMethod]);
+ }
+ if (! intensityCursorVisible || Graphics_dyWCtoMM (my d_graphics, intensityCursor - my p_intensity_viewFrom) > 5.0) {
+ Graphics_setTextAlignment (my d_graphics, alignment, Graphics_BOTTOM);
+ Graphics_text2 (my d_graphics, y, my p_intensity_viewFrom - Graphics_dyMMtoWC (my d_graphics, 0.5),
+ Melder_float (Melder_half (my p_intensity_viewFrom)), L" dB");
+ }
+ if (! intensityCursorVisible || Graphics_dyWCtoMM (my d_graphics, my p_intensity_viewTo - intensityCursor) > 5.0) {
+ Graphics_setTextAlignment (my d_graphics, alignment, Graphics_TOP);
+ Graphics_text2 (my d_graphics, y, my p_intensity_viewTo, Melder_float (Melder_half (my p_intensity_viewTo)), L" dB");
+ }
+ Graphics_setColour (my d_graphics, Graphics_BLACK);
}
- Graphics_setColour (my d_graphics, textColour);
- intensityCursorVisible = NUMdefined (intensityCursor) && intensityCursor > my p_intensity_viewFrom && intensityCursor < my p_intensity_viewTo;
- if (intensityCursorVisible) {
- static const wchar_t *methodString [] = { L" (.5)", L" (μE)", L" (μS)", L" (μ)" };
- Graphics_setTextAlignment (my d_graphics, alignment, Graphics_HALF);
- Graphics_text3 (my d_graphics, y, intensityCursor, Melder_float (Melder_half (intensityCursor)), L" dB",
- my d_startSelection == my d_endSelection ? L"" : methodString [my p_intensity_averagingMethod]);
- }
- if (! intensityCursorVisible || Graphics_dyWCtoMM (my d_graphics, intensityCursor - my p_intensity_viewFrom) > 5.0) {
- Graphics_setTextAlignment (my d_graphics, alignment, Graphics_BOTTOM);
- Graphics_text2 (my d_graphics, y, my p_intensity_viewFrom - Graphics_dyMMtoWC (my d_graphics, 0.5),
- Melder_float (Melder_half (my p_intensity_viewFrom)), L" dB");
- }
- if (! intensityCursorVisible || Graphics_dyWCtoMM (my d_graphics, my p_intensity_viewTo - intensityCursor) > 5.0) {
- Graphics_setTextAlignment (my d_graphics, alignment, Graphics_TOP);
- Graphics_text2 (my d_graphics, y, my p_intensity_viewTo, Melder_float (Melder_half (my p_intensity_viewTo)), L" dB");
- }
- Graphics_setColour (my d_graphics, Graphics_BLACK);
}
if (my p_spectrogram_show || my p_formant_show) {
static MelderString text = { 0 };
diff --git a/fon/WordList.cpp b/fon/WordList.cpp
index 059cd94..5e5c39c 100644
--- a/fon/WordList.cpp
+++ b/fon/WordList.cpp
@@ -50,7 +50,7 @@ static long WordList_count (WordList me) {
void structWordList :: v_info () {
structData :: v_info ();
long n = WordList_count (this);
- if (! length) length = wcslen (string);
+ if (! our length) our length = wcslen (our string);
MelderInfo_writeLine (L"Number of words: ", Melder_integer (n));
MelderInfo_writeLine (L"Number of characters: ", Melder_integer (length - n));
}
@@ -58,12 +58,12 @@ void structWordList :: v_info () {
void structWordList :: v_readBinary (FILE *f) {
wchar_t *current, *p;
int kar = 0;
- length = bingeti4 (f);
- if (length < 0)
- Melder_throw ("Wrong length ", length, ".");
- string = Melder_calloc (wchar_t, length + 1);
+ our length = bingeti4 (f);
+ if (our length < 0)
+ Melder_throw ("Wrong length ", our length, ".");
+ string = Melder_calloc (wchar_t, our length + 1);
p = current = string;
- if (length > 0) {
+ if (our length > 0) {
/*
* Read first word.
*/
diff --git a/fon/manual_tutorials.cpp b/fon/manual_tutorials.cpp
index 7007e82..4bab514 100644
--- a/fon/manual_tutorials.cpp
+++ b/fon/manual_tutorials.cpp
@@ -23,9 +23,14 @@
void manual_tutorials_init (ManPages me);
void manual_tutorials_init (ManPages me) {
-MAN_BEGIN (L"What's new?", L"ppgb", 20141228)
+MAN_BEGIN (L"What's new?", L"ppgb", 20150221)
INTRO (L"Latest changes in Praat.")
/*LIST_ITEM (L"• Manual page about @@drawing a vowel triangle at .")*/
+NORMAL (L"##5.4.06# (21 February 2015)")
+LIST_ITEM (L"• Windows: repaired a bug that could cause Praat to crash if a metafile resolution was 200 dpi.")
+NORMAL (L"##5.4.05# (13 February 2015)")
+LIST_ITEM (L"• Better support for big integer numbers on Windows XP.")
+LIST_ITEM (L"• Sound window: guarded against empty view ranges for the intensity curve.")
NORMAL (L"##5.4.04# (28 December 2014)")
LIST_ITEM (L"• Windows audio playback: if the sound has more channels than the audio hardware, distribute them evenly.")
NORMAL (L"##5.4.03# (18 December 2014)")
diff --git a/fon/praat_Sound_init.cpp b/fon/praat_Sound_init.cpp
index f9c876f..a2931b4 100644
--- a/fon/praat_Sound_init.cpp
+++ b/fon/praat_Sound_init.cpp
@@ -478,7 +478,7 @@ static void common_Sound_create (void *dia, Interpreter interpreter, bool allowM
double startTime = GET_REAL (L"Start time");
double endTime = GET_REAL (L"End time");
double samplingFrequency = GET_REAL (L"Sampling frequency");
- double numberOfSamples_real = floor ((endTime - startTime) * samplingFrequency + 0.5);
+ double numberOfSamples_real = round ((endTime - startTime) * samplingFrequency);
long numberOfSamples;
if (endTime <= startTime) {
if (endTime == startTime)
diff --git a/main/main_Praat.cpp b/main/main_Praat.cpp
index 314531c..4030e27 100644
--- a/main/main_Praat.cpp
+++ b/main/main_Praat.cpp
@@ -1,6 +1,6 @@
/* main_Praat.cpp
*
- * Copyright (C) 1992-2012,2013,2014 Paul Boersma
+ * Copyright (C) 1992-2012,2013,2014,2015 Paul Boersma
*
* 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
@@ -20,6 +20,11 @@
#include "praat.h"
#include "praat_version.h"
+#define UTF32_C(string) \
+ ({ static const wchar_t *_static_utf32_string = Melder_utf8ToWcs (string); _static_utf32_string; })
+
+static const char32_t *greeting = U"Hello?";
+
static void logo (Graphics g) {
Graphics_setWindow (g, 0, 1, 0.00, 0.80);
Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF);
@@ -41,13 +46,13 @@ static void logo (Graphics g) {
Graphics_text (g, 0.5, 0.33, L"www.praat.org");
Graphics_setFont (g, kGraphics_font_HELVETICA);
Graphics_setFontSize (g, 10);
- Graphics_text (g, 0.5, 0.16, L"Copyright © 1992–" xstr(PRAAT_YEAR) " by Paul Boersma and David Weenink");
+ Graphics_text (g, 0.5, 0.16, UTF32_C ("Copyright © 1992–" xstr(PRAAT_YEAR) " by Paul Boersma and David Weenink"));
}
int main (int argc, char *argv []) {
try {
praat_setLogo (130, 80, logo);
- praat_init ("Praat", argc, argv);
+ praat_init ("Praat", (unsigned int) argc, argv);
INCLUDE_LIBRARY (praat_uvafon_init)
INCLUDE_LIBRARY (praat_contrib_Ola_KNN_init)
praat_run ();
diff --git a/sys/Collection.cpp b/sys/Collection.cpp
index 2fcf47d..79a468b 100644
--- a/sys/Collection.cpp
+++ b/sys/Collection.cpp
@@ -73,7 +73,7 @@ bool structCollection :: v_equal (thou) {
"cannot compare items of class ", Thing_className ((Thing) thy item [i]), ".");
bool equal = Data_equal ((Data) item [i], (Data) thy item [i]);
//Melder_casual ("classCollection_equal: %d, items %ld, types %ls and %ls",
- // equal, i, Thing_className (my item [i]), Thing_className (thy item [i]));
+ // equal, (long) i, Thing_className (my item [i]), Thing_className (thy item [i]));
if (! equal) return false;
}
return true;
@@ -133,9 +133,9 @@ void structCollection :: v_readText (MelderReadText text) {
our item [i] = Thing_newFromClassNameA (klas);
Thing_version = -1; /* Override. */
our size ++;
- if (! Thing_member ((Thing) item [i], classData) || ! Data_canReadText ((Data) item [i]))
- Melder_throw ("Cannot read item of class ", Thing_className ((Thing) item [i]), " in collection.");
- Data_readText ((Data) item [i], text);
+ if (! Thing_member ((Thing) our item [i], classData) || ! Data_canReadText ((Data) our item [i]))
+ Melder_throw ("Cannot read item of class ", Thing_className ((Thing) our item [i]), " in collection.");
+ Data_readText ((Data) our item [i], text);
if (stringsRead == 3) {
if (line [n] == ' ') n ++; // skip space character
length = wcslen (line+n);
@@ -144,27 +144,27 @@ void structCollection :: v_readText (MelderReadText text) {
}
}
} else {
- long l_size = texgeti4 (text);
+ int32_t l_size = texgeti4 (text);
Collection_init (this, NULL, l_size);
- for (long i = 1; i <= l_size; i ++) {
+ for (int32_t i = 1; i <= l_size; i ++) {
long saveVersion = Thing_version; /* The version of the Collection... */
autostring8 className = texgets2 (text);
our item [i] = Thing_newFromClassNameA (className.peek());
our size ++;
- if (! Thing_member ((Thing) item [i], classData) || ! Data_canReadText ((Data) item [i]))
- Melder_throw ("Cannot read item of class ", Thing_className ((Thing) item [i]), " in collection.");
+ if (! Thing_member ((Thing) our item [i], classData) || ! Data_canReadText ((Data) our item [i]))
+ Melder_throw ("Cannot read item of class ", Thing_className ((Thing) our item [i]), " in collection.");
autostring objectName = texgetw2 (text);
- Thing_setName ((Thing) item [i], objectName.peek());
- Data_readText ((Data) item [i], text);
+ Thing_setName ((Thing) our item [i], objectName.peek());
+ Data_readText ((Data) our item [i], text);
Thing_version = saveVersion;
}
}
}
void structCollection :: v_writeBinary (FILE *f) {
- binputi4 (size, f);
- for (long i = 1; i <= size; i ++) {
- Thing thing = (Thing) item [i];
+ binputi4 (our size, f);
+ for (long i = 1; i <= our size; i ++) {
+ Thing thing = (Thing) our item [i];
ClassInfo classInfo = thing -> classInfo;
if (! Thing_member (thing, classData) || ! Data_canWriteBinary ((Data) thing))
Melder_throw ("Objects of class ", classInfo -> className, L" cannot be written.");
@@ -177,43 +177,43 @@ void structCollection :: v_writeBinary (FILE *f) {
void structCollection :: v_readBinary (FILE *f) {
if (Thing_version < 0) {
- long l_size = bingeti4 (f);
+ int32_t l_size = bingeti4 (f);
if (l_size < 0)
Melder_throw ("Empty collection.");
Collection_init (this, NULL, l_size);
- for (long i = 1; i <= l_size; i ++) {
+ for (int32_t i = 1; i <= l_size; i ++) {
char klas [200], name [2000];
- if (fscanf (f, "%s%s", klas, name) < 2)
+ if (fscanf (f, "%s%s", klas, name) < 2) // BUG
Melder_throw ("Cannot read class and name.");
- item [i] = Thing_newFromClassNameA (klas);
+ our item [i] = Thing_newFromClassNameA (klas);
Thing_version = -1; /* Override. */
our size ++;
- if (! Thing_member ((Thing) item [i], classData))
- Melder_throw ("Cannot read item of class ", Thing_className ((Thing) item [i]), ".");
+ if (! Thing_member ((Thing) our item [i], classData))
+ Melder_throw ("Cannot read item of class ", Thing_className ((Thing) our item [i]), ".");
if (fgetc (f) != ' ')
Melder_throw ("Cannot read space.");
- Data_readBinary ((Data) item [i], f);
- if (strcmp (name, "?")) Thing_setName ((Thing) item [i], Melder_peekUtf8ToWcs (name));
+ Data_readBinary ((Data) our item [i], f);
+ if (strcmp (name, "?")) Thing_setName ((Thing) our item [i], Melder_peekUtf8ToWcs (name));
}
} else {
- long l_size = bingeti4 (f);
+ int32_t l_size = bingeti4 (f);
if (Melder_debug == 44)
- Melder_casual ("structCollection :: v_readBinary: Reading %ld objects", l_size);
+ Melder_casual ("structCollection :: v_readBinary: Reading %ld objects", (long) l_size);
Collection_init (this, NULL, l_size);
- for (long i = 1; i <= l_size; i ++) {
+ for (int32_t i = 1; i <= l_size; i ++) {
long saveVersion = Thing_version; // the version of the Collection...
autostring8 klas = bingets1 (f);
if (Melder_debug == 44)
Melder_casual ("structCollection :: v_readBinary: Reading object of type %s", klas.peek());
- item [i] = Thing_newFromClassNameA (klas.peek());
+ our item [i] = Thing_newFromClassNameA (klas.peek());
our size ++;
- if (! Thing_member ((Thing) item [i], classData) || ! Data_canReadBinary ((Data) item [i]))
- Melder_throw ("Objects of class ", Thing_className ((Thing) item [i]), " cannot be read.");
+ if (! Thing_member ((Thing) our item [i], classData) || ! Data_canReadBinary ((Data) our item [i]))
+ Melder_throw ("Objects of class ", Thing_className ((Thing) our item [i]), " cannot be read.");
autostring name = bingetw2 (f);
if (Melder_debug == 44)
Melder_casual ("structCollection :: v_readBinary: Reading object with name %ls", name.peek());
- Thing_setName ((Thing) item [i], name.peek());
- Data_readBinary ((Data) item [i], f);
+ Thing_setName ((Thing) our item [i], name.peek());
+ Data_readBinary ((Data) our item [i], f);
Thing_version = saveVersion;
}
}
diff --git a/sys/Graphics.cpp b/sys/Graphics.cpp
index 04044cf..f7c7247 100644
--- a/sys/Graphics.cpp
+++ b/sys/Graphics.cpp
@@ -106,6 +106,8 @@ void Graphics_init (Graphics me, int resolution) {
my resolutionNumber = kGraphics_resolution_100;
} else if (resolution == 180) {
my resolutionNumber = kGraphics_resolution_180;
+ } else if (resolution == 200) {
+ my resolutionNumber = kGraphics_resolution_200;
} else if (resolution == 300) {
my resolutionNumber = kGraphics_resolution_300;
} else if (resolution == 360) {
diff --git a/sys/GraphicsScreen.cpp b/sys/GraphicsScreen.cpp
index f63e6b4..65609c5 100644
--- a/sys/GraphicsScreen.cpp
+++ b/sys/GraphicsScreen.cpp
@@ -232,7 +232,7 @@ void structGraphicsScreen :: v_flushWs () {
// Ik weet niet of dit is wat het zou moeten zijn ;)
//gdk_window_process_updates (d_window, TRUE); // this "works" but is incorrect because it's not the expose events that have to be carried out
//gdk_window_flush (d_window);
- //gdk_flush ();
+ gdk_flush ();
// TODO: een aanroep die de eventuele grafische buffer ledigt,
// zodat de gebruiker de grafica ziet ook al blijft Praat in hetzelfde event zitten
#elif cocoa
diff --git a/sys/Graphics_enums.h b/sys/Graphics_enums.h
index 3e5d4d7..9bef38f 100644
--- a/sys/Graphics_enums.h
+++ b/sys/Graphics_enums.h
@@ -1,6 +1,6 @@
/* Graphics_enums.h
*
- * Copyright (C) 1992-2007,2013,2014 Paul Boersma
+ * Copyright (C) 1992-2007,2013,2014,2015 Paul Boersma
*
* 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
@@ -35,11 +35,12 @@ enums_begin (kGraphics_resolution, 0)
enums_add (kGraphics_resolution, 0, 96, L"96 dpi")
enums_add (kGraphics_resolution, 1, 100, L"100 dpi")
enums_add (kGraphics_resolution, 2, 180, L"180 dpi")
- enums_add (kGraphics_resolution, 3, 300, L"300 dpi")
- enums_add (kGraphics_resolution, 4, 360, L"360 dpi")
- enums_add (kGraphics_resolution, 5, 600, L"600 dpi")
- enums_add (kGraphics_resolution, 6, 1200, L"1200 dpi")
-enums_end (kGraphics_resolution, 6, 100)
+ enums_add (kGraphics_resolution, 3, 200, L"200 dpi")
+ enums_add (kGraphics_resolution, 4, 300, L"300 dpi")
+ enums_add (kGraphics_resolution, 5, 360, L"360 dpi")
+ enums_add (kGraphics_resolution, 6, 600, L"600 dpi")
+ enums_add (kGraphics_resolution, 7, 1200, L"1200 dpi")
+enums_end (kGraphics_resolution, 7, 100)
enums_begin (kGraphics_colourScale, 0)
enums_add (kGraphics_colourScale, 0, GREY, L"grey")
diff --git a/sys/Graphics_record.cpp b/sys/Graphics_record.cpp
index 831c0d5..0568ba1 100644
--- a/sys/Graphics_record.cpp
+++ b/sys/Graphics_record.cpp
@@ -447,7 +447,7 @@ void Graphics_readRecordings (Graphics me, FILE *f) {
long old_irecord = my irecord;
long added_irecord = 0;
double *p = NULL, *endp = NULL;
- long numberOfArguments = 0;
+ signed long numberOfArguments = 0;
int opcode = 0;
try {
added_irecord = bingeti4 (f);
@@ -458,7 +458,7 @@ void Graphics_readRecordings (Graphics me, FILE *f) {
while (p < endp) {
opcode = (int) bingetr4 (f);
put (opcode);
- numberOfArguments = (long) bingetr4 (f);
+ numberOfArguments = (signed long) bingetr4 (f);
if (numberOfArguments == -1) {
numberOfArguments = bingeti4 (f);
}
@@ -467,7 +467,7 @@ void Graphics_readRecordings (Graphics me, FILE *f) {
put (bingetr4 (f)); // x
put (bingetr4 (f)); // y
put (bingetr4 (f)); // length
- if ((long) fread (++ p, 8, numberOfArguments - 3, f) < numberOfArguments - 3) // text
+ if (fread (++ p, 8, (size_t) numberOfArguments - 3, f) < (size_t) numberOfArguments - 3) // text
Melder_throw ("Error reading graphics recordings.");
p += numberOfArguments - 4;
} else if (opcode == IMAGE_FROM_FILE) {
@@ -476,7 +476,7 @@ void Graphics_readRecordings (Graphics me, FILE *f) {
put (bingetr4 (f)); // y1
put (bingetr4 (f)); // y2
put (bingetr4 (f)); // length
- if ((long) fread (++ p, 8, numberOfArguments - 5, f) < numberOfArguments - 5) // text
+ if (fread (++ p, 8, (size_t) numberOfArguments - 5, f) < (size_t) numberOfArguments - 5) // text
Melder_throw ("Error reading graphics recordings.");
p += numberOfArguments - 6;
} else {
diff --git a/sys/Graphics_text.cpp b/sys/Graphics_text.cpp
index 2d9a7e5..5dbb30e 100644
--- a/sys/Graphics_text.cpp
+++ b/sys/Graphics_text.cpp
@@ -387,15 +387,18 @@ static void charSize (I, _Graphics_widechar *lc) {
int normalSize = my fontSize * my resolution / 72.0;
lc -> size = lc -> size < 100 ? (3 * normalSize + 2) / 4 : normalSize;
- utf16_t codes16 [2];
+ char16_t codes16 [2];
int nchars = 1;
- if (lc -> kar > 0xFFFF) {
- utf32_t kar = lc -> kar - 0x10000;
- codes16 [0] = 0xD800 + (kar >> 10);
- codes16 [1] = 0xDC00 + (kar & 0x3FF);
+ if (lc -> kar > 0x00FFFF) {
+ char32_t kar = lc -> kar - 0x010000; // subtract the BMP
+ Melder_assert (lc -> kar <= 0x0FFFFF); // no more than 20 bits should remain
+ // encode the upper 10 bits
+ codes16 [0] = (char16) (0x00D800 | (kar >> 10)); // at most 0x00D800 | 0x0003FF = 0x00DBFF
+ // encode the lower 10 bits
+ codes16 [1] = (char16) (0x00DC00 | (kar & 0x0003FF)); // at most 0x00DC00 | 0x0003FF = 0x00DFFF
nchars = 2;
} else {
- codes16 [0] = lc -> kar;
+ codes16 [0] = (char16) lc -> kar; // guarded conversion down
}
NSString *s = [[NSString alloc]
initWithBytes: codes16
@@ -480,16 +483,20 @@ static void charSize (I, _Graphics_widechar *lc) {
OSStatus err = ATSUCreateTextLayout (& textLayout);
if (err != 0) Melder_fatal ("Graphics_text/ATSUCreateTextLayout: unknown MacOS error %d.", (int) err);
}
- utf16_t code16 [2];
+ char16_t code16 [2];
if (lc -> kar <= 0xFFFF) {
code16 [0] = lc -> kar;
- OSStatus err = ATSUSetTextPointerLocation (textLayout, & code16 [0], kATSUFromTextBeginning, kATSUToTextEnd, 1); // BUG: not 64-bit
+ OSStatus err = ATSUSetTextPointerLocation (textLayout,
+ (ConstUniCharArrayPtr) & code16 [0],
+ kATSUFromTextBeginning, kATSUToTextEnd, 1); // BUG: not 64-bit
if (err != 0) Melder_fatal ("Graphics_text/ATSUSetTextPointerLocation low Unicode: unknown MacOS error %d.", (int) err);
} else {
- utf32_t kar = lc -> kar - 0x10000;
+ char32_t kar = lc -> kar - 0x10000;
code16 [0] = 0xD800 + (kar >> 10);
code16 [1] = 0xDC00 + (kar & 0x3FF);
- OSStatus err = ATSUSetTextPointerLocation (textLayout, & code16 [0], kATSUFromTextBeginning, kATSUToTextEnd, 2); // BUG: not 64-bit
+ OSStatus err = ATSUSetTextPointerLocation (textLayout,
+ (ConstUniCharArrayPtr) & code16 [0],
+ kATSUFromTextBeginning, kATSUToTextEnd, 2); // BUG: not 64-bit
if (err != 0) Melder_fatal ("Graphics_text/ATSUSetTextPointerLocation high Unicode: unknown MacOS error %d.", (int) err);
}
static ATSUFontFallbacks fontFallbacks = NULL;
@@ -682,7 +689,7 @@ static void charSize (I, _Graphics_widechar *lc) {
}
static void charDraw (I, int xDC, int yDC, _Graphics_widechar *lc,
- const wchar_t *codes, const char *codes8, const utf16_t *codes16, int nchars, int width)
+ const wchar_t *codes, const char *codes8, const char16_t *codes16, int nchars, int width)
{
iam (Graphics);
//Melder_casual ("nchars %d first %d %c rightToLeft %d", nchars, lc->kar, lc -> kar, lc->rightToLeft);
@@ -812,7 +819,7 @@ static void charDraw (I, int xDC, int yDC, _Graphics_widechar *lc,
}
if (hasHighUnicodeValues) {
nchars = wcslen_utf16 (codes, 0);
- codes16 = Melder_peekWcsToUtf16 (codes);
+ codes16 = (const char16_t *) Melder_peekWcsToUtf16 (codes);
}
#if 1
CFStringRef s = CFStringCreateWithBytes (NULL, (const UInt8 *) codes16, nchars * 2, kCFStringEncodingUTF16LE, false);
@@ -917,10 +924,14 @@ static void charDraw (I, int xDC, int yDC, _Graphics_widechar *lc,
}
if (hasHighUnicodeValues) {
nchars = wcslen_utf16 (codes, 0);
- OSStatus err = ATSUSetTextPointerLocation (theAtsuiTextLayout, Melder_peekWcsToUtf16 (codes), kATSUFromTextBeginning, kATSUToTextEnd, nchars);
+ OSStatus err = ATSUSetTextPointerLocation (theAtsuiTextLayout,
+ (ConstUniCharArrayPtr) Melder_peekWcsToUtf16 (codes),
+ kATSUFromTextBeginning, kATSUToTextEnd, nchars);
if (err != 0) Melder_fatal ("Graphics_text/ATSUSetTextPointerLocation hasHighUnicodeValues true: unknown MacOS error %d.", (int) err);
} else {
- OSStatus err = ATSUSetTextPointerLocation (theAtsuiTextLayout, codes16, kATSUFromTextBeginning, kATSUToTextEnd, nchars);
+ OSStatus err = ATSUSetTextPointerLocation (theAtsuiTextLayout,
+ (ConstUniCharArrayPtr) codes16,
+ kATSUFromTextBeginning, kATSUToTextEnd, nchars);
if (err != 0) Melder_fatal ("Graphics_text/ATSUSetTextPointerLocation hasHighUnicodeValues false: unknown MacOS error %d.", (int) err);
}
static ATSUFontFallbacks fontFallbacks = NULL;
@@ -1273,7 +1284,7 @@ static long bufferSize;
static _Graphics_widechar *theWidechar;
static wchar_t *charCodes;
static char *charCodes8;
-static utf16_t *charCodes16;
+static char16_t *charCodes16;
static int initBuffer (const wchar_t *txt) {
try {
long sizeNeeded = wcslen (txt) + 1; /* It is true that some characters are split into two, but all of these are backslash sequences. */
@@ -1286,7 +1297,7 @@ static int initBuffer (const wchar_t *txt) {
theWidechar = Melder_calloc (_Graphics_widechar, sizeNeeded);
charCodes = Melder_calloc (wchar_t, sizeNeeded);
charCodes8 = Melder_calloc (char, sizeNeeded);
- charCodes16 = Melder_calloc (utf16_t, sizeNeeded);
+ charCodes16 = Melder_calloc (char16_t, sizeNeeded);
bufferSize = sizeNeeded;
}
return 1;
diff --git a/sys/GuiList.cpp b/sys/GuiList.cpp
index 14faa98..da8b9ef 100644
--- a/sys/GuiList.cpp
+++ b/sys/GuiList.cpp
@@ -319,7 +319,7 @@ Thing_implement (GuiList, GuiControl, 0);
strncpy (Melder_buffer1, text_utf8, dataLength);
Melder_buffer1 [dataLength] = '\0';
wchar_t *text_wcs = Melder_peekUtf8ToWcs (Melder_buffer1);
- const utf16_t *text_utf16 = Melder_peekWcsToUtf16 (text_wcs);
+ const char16_t *text_utf16 = (const char16_t *) Melder_peekWcsToUtf16 (text_wcs);
UniCharCount runLength = wcslen (text_wcs); // BUG
ATSUTextLayout textLayout;
ATSUStyle style;
@@ -331,7 +331,8 @@ Thing_implement (GuiList, GuiControl, 0);
ByteCount styleValueSizes [] = { sizeof (Fixed), sizeof (Boolean), sizeof (Boolean) };
ATSUAttributeValuePtr styleValues [] = { & fontSize, & boldStyle, & italicStyle };
ATSUSetAttributes (style, 3, styleAttributeTags, styleValueSizes, styleValues);
- OSStatus err = ATSUCreateTextLayoutWithTextPtr (text_utf16, kATSUFromTextBeginning, kATSUToTextEnd, runLength,
+ OSStatus err = ATSUCreateTextLayoutWithTextPtr ((ConstUniCharArrayPtr) text_utf16,
+ kATSUFromTextBeginning, kATSUToTextEnd, runLength,
1, & runLength, & style, & textLayout);
Melder_assert (err == 0);
ATSUAttributeTag attributeTags [] = { kATSUCGContextTag, kATSULineFontFallbacksTag };
@@ -784,7 +785,6 @@ void structGuiList :: f_replaceItem (const wchar_t *itemText, long position) {
GuiCocoaList *list = (GuiCocoaList *) d_widget;
NSString *nsString = [[NSString alloc] initWithUTF8String: Melder_peekWcsToUtf8 (itemText)];
[[list contents] replaceObjectAtIndex: position - 1 withObject: nsString];
- Melder_assert ([nsString retainCount] == 2);
[nsString release];
[[list tableView] reloadData];
#elif win
diff --git a/sys/GuiMenu.cpp b/sys/GuiMenu.cpp
index 095719b..cc5001b 100644
--- a/sys/GuiMenu.cpp
+++ b/sys/GuiMenu.cpp
@@ -66,7 +66,7 @@ void structGuiMenu :: v_destroy () {
return;
}
unichar character = [characters characterAtIndex: 0]; // there is now at least one character, so no range exception can be raised
- if (Melder_getTracing ()) {
+ if (Melder_isTracing) {
for (NSUInteger i = 0; i < [characters length]; i ++) {
unichar kar = [characters characterAtIndex: 0];
trace ("character [%d]: %d", (int) i, (int) kar);
diff --git a/sys/GuiText.cpp b/sys/GuiText.cpp
index e55ade6..532c5fd 100644
--- a/sys/GuiText.cpp
+++ b/sys/GuiText.cpp
@@ -1437,7 +1437,7 @@ void structGuiText :: f_replace (long from_pos, long to_pos, const wchar_t *text
Melder_free (winText);
UpdateWindow (d_widget -> window);
#elif mac
- long length = wcslen (text), i;
+ size_t length = wcslen (text);
wchar_t *macText = Melder_malloc_f (wchar_t, length + 1);
Melder_assert (d_widget -> widgetClass == xmTextWidgetClass);
wcsncpy (macText, text, length);
@@ -1445,7 +1445,7 @@ void structGuiText :: f_replace (long from_pos, long to_pos, const wchar_t *text
/*
* Replace all LF with CR.
*/
- for (i = 0; i < length; i ++) if (macText [i] == '\n') macText [i] = 13;
+ for (size_t i = 0; i < length; i ++) if (macText [i] == '\n') macText [i] = 13;
/*
* We DON'T replace any text without selecting it, so we can deselect any other text,
* thus allowing ourselves to select [from_pos, to_pos] and use selection replacement.
@@ -1473,7 +1473,7 @@ void structGuiText :: f_replace (long from_pos, long to_pos, const wchar_t *text
for (long i = from_pos; i < to_pos; i ++) if (oldText [i] > 0xFFFF) numberOfSelectedHighUnicodeValues ++;
from_pos += numberOfLeadingHighUnicodeValues;
to_pos += numberOfLeadingHighUnicodeValues + numberOfSelectedHighUnicodeValues;
- const UniChar *macText_utf16 = Melder_peekWcsToUtf16 (macText);
+ const char16_t *macText_utf16 = (const char16_t *) Melder_peekWcsToUtf16 (macText);
TXNSetData (d_macMlteObject, kTXNUnicodeTextData, macText_utf16, wcslen_utf16 (macText, 0) * 2, from_pos, to_pos);
}
Melder_free (macText);
@@ -1701,16 +1701,16 @@ void structGuiText :: f_setString (const wchar_t *text) {
*/
long j = 0;
for (long i = 0; i < length_utf32; i ++) {
- utf32_t kar = text [i];
+ char32_t kar = (char32_t) text [i]; // reinterpret sign bit
if (kar == '\n') { // LF
macText [j ++] = 13; // CR
- } else if (kar <= 0xFFFF) {
+ } else if (kar <= 0x00FFFF) {
macText [j ++] = kar;
} else {
Melder_assert (kar <= 0x10FFFF);
- kar -= 0x10000;
- macText [j ++] = 0xD800 | (kar >> 10); // first UTF-16 surrogate character
- macText [j ++] = 0xDC00 | (kar & 0x3FF); // second UTF-16 surrogate character
+ kar -= 0x010000;
+ macText [j ++] = (UniChar) (0x00D800 | (kar >> 10)); // first UTF-16 surrogate character
+ macText [j ++] = (UniChar) (0x00DC00 | (kar & 0x0003FF)); // second UTF-16 surrogate character
}
}
macText [j] = '\0';
diff --git a/sys/TextEditor.cpp b/sys/TextEditor.cpp
index f93c19a..117f5ef 100644
--- a/sys/TextEditor.cpp
+++ b/sys/TextEditor.cpp
@@ -594,7 +594,9 @@ static void menu_cb_convertToCString (EDITOR_ARGS) {
} else if (*p == '\\') {
MelderInfo_write (L"\\\\");
} else if (*p < 0 || *p > 127) {
- utf32_t kar = sizeof (wchar_t) == 2 ? (utf16_t) *p : *p;
+ char32_t kar = sizeof (wchar_t) == 2 ?
+ (char16_t) *p : // reinterpret sign before extending -> zero extension
+ (char32_t) *p;
if (kar <= 0xFFFF) { // BUG on Windows
MelderInfo_write (L"\\u", hex [kar >> 12], hex [(kar >> 8) & 0x0000000F], hex [(kar >> 4) & 0x0000000F], hex [kar & 0x0000000F]);
} else {
diff --git a/sys/abcio.cpp b/sys/abcio.cpp
index 4d87f9f..a30239f 100644
--- a/sys/abcio.cpp
+++ b/sys/abcio.cpp
@@ -41,6 +41,8 @@
#endif
#include "abcio.h"
+const uint16_t endiannessTest = 769;
+
/********** ASCII I/O **********/
#define WCHAR_MINUS_1 (sizeof (wchar_t) == 2 ? 0xFFFF : 0xFFFFFFFF)
@@ -289,7 +291,7 @@ long texgeti4 (MelderReadText text) {
unsigned int texgetu1 (MelderReadText text) {
try {
- long externalValue = getUnsigned (text);
+ unsigned long externalValue = getUnsigned (text);
if (externalValue > 255)
Melder_throw ("Value (", externalValue, ") out of range (0 .. 255).");
return (unsigned int) externalValue;
@@ -300,7 +302,7 @@ unsigned int texgetu1 (MelderReadText text) {
unsigned int texgetu2 (MelderReadText text) {
try {
- long externalValue = getUnsigned (text);
+ unsigned long externalValue = getUnsigned (text);
if (externalValue > 65535)
Melder_throw ("Value (", externalValue, ") out of range (0 .. 65535).");
return (unsigned int) externalValue;
@@ -311,7 +313,7 @@ unsigned int texgetu2 (MelderReadText text) {
unsigned long texgetu4 (MelderReadText text) {
try {
- long externalValue = getUnsigned (text);
+ unsigned long externalValue = getUnsigned (text);
return externalValue;
} catch (MelderError) {
Melder_throw ("Unsigned integer not read from text file.");
@@ -500,27 +502,27 @@ void texputw4 (MelderFile file, const wchar_t *s, const wchar_t *s1, const wchar
/* On which machines is "short" a two's complement Big-Endian (MSB-first) 2-byte word? */
#if defined (macintosh) && TARGET_RT_BIG_ENDIAN == 1
- #define binario_shortBE2 (sizeof (short) == 2)
- #define binario_shortLE2 0
+ #define binario_16bitBE 1
+ #define binario_16bitLE 0
#elif defined (_WIN32) || defined (macintosh) && TARGET_RT_LITTLE_ENDIAN == 1
- #define binario_shortBE2 0
- #define binario_shortLE2 (sizeof (short) == 2)
+ #define binario_16bitBE 0
+ #define binario_16bitLE 1
#else
- #define binario_shortBE2 0
- #define binario_shortLE2 0
+ #define binario_16bitBE 0
+ #define binario_16bitLE 0
#endif
/* On which machines is "long" a two's complement Big-Endian (MSB-first) 4-byte word? */
#if defined (macintosh) && TARGET_RT_BIG_ENDIAN == 1
- #define binario_longBE4 (sizeof (long) == 4)
- #define binario_longLE4 0
+ #define binario_32bitBE 1
+ #define binario_32bitLE 0
#elif defined (_WIN32) || defined (macintosh) && TARGET_RT_LITTLE_ENDIAN == 1
- #define binario_longBE4 0
- #define binario_longLE4 (sizeof (long) == 4)
+ #define binario_32bitBE 0
+ #define binario_32bitLE 1
#else
- #define binario_longBE4 0
- #define binario_longLE4 0
+ #define binario_32bitBE 0
+ #define binario_32bitLE 0
#endif
/* On which machines is "float" IEEE, four bytes, Most Significant Bit first? */
@@ -606,6 +608,9 @@ void texputw4 (MelderFile file, const wchar_t *s, const wchar_t *s1, const wchar
# define UnsignedToFloat(u) \
(((double)((long)((u) - 2147483647L - 1))) + 2147483648.0)
+//#define FloatToUnsigned(f) (uint32_t) (f)
+//#define UnsignedToFloat(u) (double) (u)
+
/****************************************************************
* Extended precision IEEE floating-point conversion routines.
****************************************************************/
@@ -640,7 +645,7 @@ unsigned int bingetu1 (FILE *f) {
void binputu1 (unsigned int u, FILE *f) {
try {
- if (putc (u, f) < 0) writeError ("a byte.");
+ if (putc ((int) u, f) < 0) writeError ("a byte."); //
} catch (MelderError) {
Melder_throw ("Unsigned integer not written to 1 byte in binary file.");
}
@@ -690,14 +695,13 @@ static unsigned char readBuffer;
#define macro_bingetb(nbits) \
unsigned int bingetb##nbits (FILE *f) { \
- unsigned char result; \
if (bitsInReadBuffer < nbits) { \
int externalValue = fgetc (f); \
if (externalValue < 0) readError (f, "a bit."); \
readBuffer = (unsigned char) externalValue; \
bitsInReadBuffer = 8; \
} \
- result = readBuffer << (8 - bitsInReadBuffer); \
+ unsigned char result = (unsigned char) ((uint32_t) readBuffer << (8 - bitsInReadBuffer)); \
bitsInReadBuffer -= nbits; \
return result >> (8 - nbits); \
}
@@ -711,17 +715,36 @@ macro_bingetb (7)
void bingetb (FILE *f) { (void) f; bitsInReadBuffer = 0; }
-int bingeti2 (FILE *f) {
+int16_t bingeti2 (FILE *f) {
try {
- if (binario_shortBE2 && Melder_debug != 18) {
- signed short s;
- if (fread (& s, sizeof (signed short), 1, f) != 1) readError (f, "a signed short integer.");
- return (int) s; // with sign extension if an int is 4 bytes
+ if (binario_16bitBE && Melder_debug != 18) {
+ int16_t s;
+ if (fread (& s, sizeof (int16_t), 1, f) != 1) readError (f, "a signed 16-bit integer.");
+ return s;
} else {
unsigned char bytes [2];
if (fread (bytes, sizeof (unsigned char), 2, f) != 2) readError (f, "two bytes.");
- uint16_t externalValue = (uint16_t) ((uint16_t) bytes [0] << 8) | (uint16_t) bytes [1];
- return (int) (int16_t) externalValue; // with sign extension if an int is 4 bytes
+ return (int16_t) // reinterpret sign bit
+ ((uint16_t) ((uint16_t) bytes [0] << 8) |
+ (uint16_t) bytes [1]);
+ }
+ } catch (MelderError) {
+ Melder_throw ("Signed integer not read from 2 bytes in binary file.");
+ }
+}
+
+int16_t bingeti2LE (FILE *f) {
+ try {
+ if (binario_16bitLE && Melder_debug != 18) {
+ int16_t s;
+ if (fread (& s, sizeof (int16_t), 1, f) != 1) readError (f, "a signed 16-bit integer.");
+ return s;
+ } else {
+ unsigned char bytes [2];
+ if (fread (bytes, sizeof (unsigned char), 2, f) != 2) readError (f, "two bytes.");
+ return (int16_t) // reinterpret sign bit
+ ((uint16_t) ((uint16_t) bytes [1] << 8) |
+ (uint16_t) bytes [0]);
}
} catch (MelderError) {
Melder_throw ("Signed integer not read from 2 bytes in binary file.");
@@ -730,15 +753,34 @@ int bingeti2 (FILE *f) {
uint16_t bingetu2 (FILE *f) {
try {
- if (binario_shortBE2 && Melder_debug != 18) {
- unsigned short s;
- if (fread (& s, sizeof (unsigned short), 1, f) != 1) readError (f, "an unsigned short integer.");
+ if (binario_16bitBE && Melder_debug != 18) {
+ uint16_t s;
+ if (fread (& s, sizeof (uint16_t), 1, f) != 1) readError (f, "an unsigned 16-bit integer.");
return s; // without sign extension
} else {
unsigned char bytes [2];
if (fread (bytes, sizeof (unsigned char), 2, f) != 2) readError (f, "two bytes.");
- uint16_t externalValue = (uint16_t) ((uint16_t) bytes [0] << 8) | (uint16_t) bytes [1];
- return externalValue;
+ return
+ (uint16_t) ((uint16_t) bytes [0] << 8) |
+ (uint16_t) bytes [1];
+ }
+ } catch (MelderError) {
+ Melder_throw ("Unsigned integer not read from 2 bytes in binary file.");
+ }
+}
+
+uint16_t bingetu2LE (FILE *f) {
+ try {
+ if (binario_16bitLE && Melder_debug != 18) {
+ uint16_t s;
+ if (fread (& s, sizeof (uint16_t), 1, f) != 1) readError (f, "an unsigned 16-bit integer.");
+ return s; // without sign extension
+ } else {
+ unsigned char bytes [2];
+ if (fread (bytes, sizeof (unsigned char), 2, f) != 2) readError (f, "two bytes.");
+ return
+ (uint16_t) ((uint16_t) bytes [1] << 8) |
+ (uint16_t) bytes [0];
}
} catch (MelderError) {
Melder_throw ("Unsigned integer not read from 2 bytes in binary file.");
@@ -747,14 +789,16 @@ uint16_t bingetu2 (FILE *f) {
int bingete2 (FILE *f, int min, int max, const wchar_t *type) {
try {
- short result;
- if (binario_shortBE2 && Melder_debug != 18) {
- if (fread (& result, sizeof (short), 1, f) != 1) readError (f, "a signed short integer.");
+ int16_t result;
+ if (binario_16bitBE && Melder_debug != 18) {
+ if (fread (& result, sizeof (uint16_t), 1, f) != 1) readError (f, "a signed 16-bit integer.");
} else {
unsigned char bytes [2];
if (fread (bytes, sizeof (unsigned char), 2, f) != 2) readError (f, "two bytes.");
- uint16_t externalValue = (uint16_t) ((uint16_t) bytes [0] << 8) | (uint16_t) bytes [1];
- result = (short) (int16_t) externalValue;
+ uint16_t externalValue =
+ (uint16_t) ((uint16_t) bytes [0] << 8) |
+ (uint16_t) bytes [1];
+ result = (int16_t) externalValue;
}
if (result < min || result > max)
Melder_throw (result, " is not a value of enumerated type \"", type, L"\".");
@@ -764,139 +808,115 @@ int bingete2 (FILE *f, int min, int max, const wchar_t *type) {
}
}
-long bingeti3 (FILE *f) {
+int32_t bingeti3 (FILE *f) {
try {
unsigned char bytes [3];
if (fread (bytes, sizeof (unsigned char), 3, f) != 3) readError (f, "three bytes.");
- uint32_t externalValue = (uint32_t) ((uint32_t) bytes [0] << 16) | (uint32_t) ((uint32_t) bytes [1] << 8) | (uint32_t) bytes [2];
+ uint32_t externalValue =
+ (uint32_t) ((uint32_t) bytes [0] << 16) |
+ (uint32_t) ((uint32_t) bytes [1] << 8) |
+ (uint32_t) bytes [2];
if ((bytes [0] & 128) != 0) // is the 24-bit sign bit on?
externalValue |= 0xFF000000; // extend negative sign to 32 bits
- return (long) (int32_t) externalValue; // first add sign, then perhaps extend sign
+ return (int32_t) externalValue; // reinterpret sign bit
} catch (MelderError) {
- Melder_throw ("Signed long integer not read from 3 bytes in binary file.");
+ Melder_throw ("Signed integer not read from 3 bytes in binary file.");
}
}
-long bingeti4 (FILE *f) {
+int32_t bingeti3LE (FILE *f) {
try {
- if (binario_longBE4 && Melder_debug != 18) {
- long l;
- if (fread (& l, sizeof (long), 1, f) != 1) readError (f, "a signed long integer.");
- return l;
- } else {
- unsigned char bytes [4];
- if (fread (bytes, sizeof (unsigned char), 4, f) != 4) readError (f, "four bytes.");
- uint32_t externalValue =
- (uint32_t) ((uint32_t) bytes [0] << 24) | (uint32_t) ((uint32_t) bytes [1] << 16) |
- (uint32_t) ((uint32_t) bytes [2] << 8) | (uint32_t) bytes [3];
- return (long) (int32_t) externalValue; // first add sign, then perhaps extend sign
- }
+ unsigned char bytes [3];
+ if (fread (bytes, sizeof (unsigned char), 3, f) != 3) readError (f, "three bytes.");
+ uint32_t externalValue =
+ (uint32_t) ((uint32_t) bytes [2] << 16) |
+ (uint32_t) ((uint32_t) bytes [1] << 8) |
+ (uint32_t) bytes [0];
+ if ((bytes [2] & 128) != 0) // is the 24-bit sign bit on?
+ externalValue |= 0xFF000000; // extend negative sign to 32 bits
+ return (int32_t) externalValue; // reinterpret sign bit
} catch (MelderError) {
- Melder_throw ("Signed long integer not read from 4 bytes in binary file.");
+ Melder_throw ("Signed integer not read from 3 bytes in binary file.");
}
}
-unsigned long bingetu4 (FILE *f) {
+int32_t bingeti4 (FILE *f) {
try {
- if (binario_longBE4 && Melder_debug != 18) {
- unsigned long l;
- if (fread (& l, sizeof (unsigned long), 1, f) != 1) readError (f, "an unsigned long integer.");
+ if (binario_32bitBE && Melder_debug != 18) {
+ int32_t l;
+ if (fread (& l, sizeof (int32_t), 1, f) != 1) readError (f, "a signed 32-bit integer.");
return l;
} else {
unsigned char bytes [4];
if (fread (bytes, sizeof (unsigned char), 4, f) != 4) readError (f, "four bytes.");
- uint32_t externalValue =
- (uint32_t) ((uint32_t) bytes [0] << 24) | (uint32_t) ((uint32_t) bytes [1] << 16) |
- (uint32_t) ((uint32_t) bytes [2] << 8) | (uint32_t) bytes [3];
- return (unsigned long) externalValue;
+ return (int32_t)
+ ((uint32_t) ((uint32_t) bytes [0] << 24) |
+ (uint32_t) ((uint32_t) bytes [1] << 16) |
+ (uint32_t) ((uint32_t) bytes [2] << 8) |
+ (uint32_t) bytes [3]);
}
} catch (MelderError) {
- Melder_throw ("Unsigned long integer not read from 4 bytes in binary file.");
+ Melder_throw ("Signed integer not read from 4 bytes in binary file.");
}
}
-int bingeti2LE (FILE *f) {
+int32_t bingeti4LE (FILE *f) {
try {
- if (binario_shortLE2 && Melder_debug != 18) {
- signed short s;
- if (fread (& s, sizeof (signed short), 1, f) != 1) readError (f, "a signed short integer.");
- int result = (int) s; // with sign extension if an int is 4 bytes
- Melder_assert (result >= -32768 && result <= 32767);
- return result; // with sign extension if an int is 4 bytes
- } else {
- unsigned char bytes [2];
- if (fread (bytes, sizeof (unsigned char), 2, f) != 2) readError (f, "two bytes.");
- uint16_t externalValue = (uint16_t) ((uint16_t) bytes [1] << 8) | (uint16_t) bytes [0];
- return (int) (int16_t) externalValue; // with sign extension if an int is 4 bytes
- }
- } catch (MelderError) {
- Melder_throw ("Signed integer not read from 2 bytes in binary file.");
- }
-}
-
-uint16_t bingetu2LE (FILE *f) {
- try {
- if (binario_shortLE2 && Melder_debug != 18) {
- unsigned short s;
- if (fread (& s, sizeof (unsigned short), 1, f) != 1) readError (f, "an unsigned short integer.");
- return s; // without sign extension
+ if (binario_32bitLE && Melder_debug != 18) {
+ int32_t l;
+ if (fread (& l, sizeof (int32_t), 1, f) != 1) readError (f, "a signed 32-bit integer.");
+ return l;
} else {
- unsigned char bytes [2];
- if (fread (bytes, sizeof (unsigned char), 2, f) != 2) readError (f, "two bytes.");
- uint16_t externalValue = (uint16_t) ((uint16_t) bytes [1] << 8) | (uint16_t) bytes [0];
- return externalValue;
+ unsigned char bytes [4];
+ if (fread (bytes, sizeof (unsigned char), 4, f) != 4) readError (f, "four bytes.");
+ return (int32_t) // reinterpret sign bit
+ ((uint32_t) ((uint32_t) bytes [3] << 24) |
+ (uint32_t) ((uint32_t) bytes [2] << 16) |
+ (uint32_t) ((uint32_t) bytes [1] << 8) |
+ (uint32_t) bytes [0]);
}
} catch (MelderError) {
- Melder_throw ("Unsigned integer not read from 2 bytes in binary file.");
- }
-}
-
-long bingeti3LE (FILE *f) {
- try {
- unsigned char bytes [3];
- if (fread (bytes, sizeof (unsigned char), 3, f) != 3) readError (f, "three bytes.");
- uint32_t externalValue = ((uint32_t) bytes [2] << 16) | ((uint32_t) bytes [1] << 8) | (uint32_t) bytes [0];
- if ((bytes [2] & 128) != 0) // is the 24-bit sign bit on?
- externalValue |= 0xFF000000; // extend negative sign to 32 bits
- return (long) (int32_t) externalValue; // first convert signedness, then perhaps extend sign to 64 bits!
- } catch (MelderError) {
- Melder_throw ("Signed long integer not read from 3 bytes in binary file.");
+ Melder_throw ("Signed integer not read from 4 bytes in binary file.");
}
}
-long bingeti4LE (FILE *f) {
+uint32_t bingetu4 (FILE *f) {
try {
- if (binario_longLE4 && Melder_debug != 18) {
- long l;
- if (fread (& l, sizeof (long), 1, f) != 1) readError (f, "a signed long integer.");
+ if (binario_32bitBE && Melder_debug != 18) {
+ uint32_t l;
+ if (fread (& l, sizeof (uint32_t), 1, f) != 1) readError (f, "an unsigned 32-bit integer.");
return l;
} else {
unsigned char bytes [4];
if (fread (bytes, sizeof (unsigned char), 4, f) != 4) readError (f, "four bytes.");
- uint32_t externalValue = (uint32_t) ((uint32_t) bytes [3] << 24) | (uint32_t) ((uint32_t) bytes [2] << 16) |
- (uint32_t) ((uint32_t) bytes [1] << 8) | (uint32_t) bytes [0];
- return (long) (int32_t) externalValue; // first add signedness, then extend
+ return
+ (uint32_t) ((uint32_t) bytes [0] << 24) |
+ (uint32_t) ((uint32_t) bytes [1] << 16) |
+ (uint32_t) ((uint32_t) bytes [2] << 8) |
+ (uint32_t) bytes [3];
}
} catch (MelderError) {
- Melder_throw ("Signed long integer not read from 4 bytes in binary file.");
+ Melder_throw ("Unsigned integer not read from 4 bytes in binary file.");
}
}
-unsigned long bingetu4LE (FILE *f) {
+uint32_t bingetu4LE (FILE *f) {
try {
- if (binario_longLE4 && Melder_debug != 18) {
- unsigned long l;
- if (fread (& l, sizeof (unsigned long), 1, f) != 1) readError (f, "an unsigned long integer.");
+ if (binario_32bitLE && Melder_debug != 18) {
+ uint32_t l;
+ if (fread (& l, sizeof (uint32_t), 1, f) != 1) readError (f, "an unsigned 32-bit integer.");
return l;
} else {
unsigned char bytes [4];
if (fread (bytes, sizeof (unsigned char), 4, f) != 4) readError (f, "four bytes.");
- uint32_t externalValue = (uint32_t) ((uint32_t) bytes [3] << 24) | (uint32_t) ((uint32_t) bytes [2] << 16) |
- (uint32_t) ((uint32_t) bytes [1] << 8) | (uint32_t) bytes [0];
- return (unsigned long) externalValue;
+ return
+ (uint32_t) ((uint32_t) bytes [3] << 24) |
+ (uint32_t) ((uint32_t) bytes [2] << 16) |
+ (uint32_t) ((uint32_t) bytes [1] << 8) |
+ (uint32_t) bytes [0];
}
} catch (MelderError) {
- Melder_throw ("Unsigned long integer not read from 4 bytes in binary file.");
+ Melder_throw ("Unsigned integer not read from 4 bytes in binary file.");
}
}
@@ -904,21 +924,26 @@ double bingetr4 (FILE *f) {
try {
if (binario_floatIEEE4msb && Melder_debug != 18) {
float x;
- if (fread (& x, sizeof (float), 1, f) != 1) readError (f, "a single-precision floating-point number.");
+ if (fread (& x, sizeof (float), 1, f) != 1) readError (f, "a 32-bit floating-point number.");
return x;
} else {
unsigned char bytes [4];
if (fread (bytes, sizeof (unsigned char), 4, f) != 4) readError (f, "four bytes.");
- long exponent = ((unsigned long) (bytes [0] & 0x7F) << 1) | ((unsigned long) (bytes [1] & 0x80) >> 7); // 32 or 64 bits
- unsigned long mantissa = ((unsigned long) (bytes [1] & 0x7F) << 16) | ((unsigned long) bytes [2] << 8) | (unsigned long) bytes [3]; // 32 or 64 bits
+ int32_t exponent = (int32_t)
+ ((uint32_t) ((uint32_t) ((uint32_t) bytes [0] & 0x7F) << 1) |
+ (uint32_t) ((uint32_t) ((uint32_t) bytes [1] & 0x80) >> 7));
+ uint32_t mantissa =
+ (uint32_t) ((uint32_t) ((uint32_t) bytes [1] & 0x7F) << 16) |
+ (uint32_t) ((uint32_t) bytes [2] << 8) |
+ (uint32_t) bytes [3];
double x;
if (exponent == 0)
if (mantissa == 0) x = 0.0;
- else x = ldexp (UnsignedToFloat (mantissa), exponent - 149); // denormalized
+ else x = ldexp ((double) mantissa, exponent - 149); // denormalized
else if (exponent == 0x00FF) // Infinity or Not-a-Number
x = HUGE_VAL;
else // finite
- x = ldexp (UnsignedToFloat (mantissa | 0x00800000), exponent - 150);
+ x = ldexp ((double) (mantissa | 0x00800000), exponent - 150);
return bytes [0] & 0x80 ? - x : x;
}
} catch (MelderError) {
@@ -930,21 +955,26 @@ double bingetr4LE (FILE *f) {
try {
if (binario_floatIEEE4lsb && Melder_debug != 18) {
float x;
- if (fread (& x, sizeof (float), 1, f) != 1) readError (f, "a single-precision floating-point number.");
+ if (fread (& x, sizeof (float), 1, f) != 1) readError (f, "a 32-bit floating-point number.");
return x;
} else {
unsigned char bytes [4];
if (fread (bytes, sizeof (unsigned char), 4, f) != 4) readError (f, "four bytes.");
- long exponent = ((unsigned long) (bytes [3] & 0x7F) << 1) | ((unsigned long) (bytes [2] & 0x80) >> 7); // 32 or 64 bits
- unsigned long mantissa = ((unsigned long) (bytes [2] & 0x7F) << 16) | ((unsigned long) bytes [1] << 8) | (unsigned long) bytes [0]; // 32 or 64 bits
+ int32_t exponent = (int32_t)
+ ((uint32_t) ((uint32_t) ((uint32_t) bytes [3] & 0x7F) << 1) |
+ (uint32_t) ((uint32_t) ((uint32_t) bytes [2] & 0x80) >> 7));
+ uint32_t mantissa =
+ (uint32_t) ((uint32_t) ((uint32_t) bytes [2] & 0x7F) << 16) |
+ (uint32_t) ((uint32_t) bytes [1] << 8) |
+ (uint32_t) bytes [0];
double x;
if (exponent == 0)
if (mantissa == 0) x = 0.0;
- else x = ldexp (UnsignedToFloat (mantissa), exponent - 149); // denormalized
- else if (exponent == 0x00FF) // Infinity or Not-a-Number. */
+ else x = ldexp ((double) mantissa, exponent - 149); // denormalized
+ else if (exponent == 0x00FF) // Infinity or Not-a-Number
x = HUGE_VAL;
else // finite
- x = ldexp (UnsignedToFloat (mantissa | 0x00800000), exponent - 150);
+ x = ldexp ((double) (mantissa | 0x00800000), exponent - 150);
return bytes [3] & 0x80 ? - x : x;
}
} catch (MelderError) {
@@ -956,25 +986,34 @@ double bingetr8 (FILE *f) {
try {
if (binario_doubleIEEE8msb && Melder_debug != 18) {
double x;
- if (fread (& x, sizeof (double), 1, f) != 1) readError (f, "a double-precision floating-point number.");
+ if (fread (& x, sizeof (double), 1, f) != 1) readError (f, "a 64-bit floating-point number.");
return x;
} else {
unsigned char bytes [8];
if (fread (bytes, sizeof (unsigned char), 8, f) != 8) readError (f, "eight bytes.");
Melder_assert (sizeof (long) >= 4);
- long exponent = ((unsigned long) (bytes [0] & 0x7F) << 4) | ((unsigned long) (bytes [1] & 0xF0) >> 4);
- unsigned long highMantissa = ((unsigned long) (bytes [1] & 0x0F) << 16) | ((unsigned long) bytes [2] << 8) | (unsigned long) bytes [3];
- unsigned long lowMantissa = ((unsigned long) bytes [4] << 24) | ((unsigned long) bytes [5] << 16) | ((unsigned long) bytes [6] << 8) | (unsigned long) bytes [7];
+ int32_t exponent = (int32_t)
+ ((uint32_t) ((uint32_t) ((uint32_t) bytes [0] & 0x7F) << 4) |
+ (uint32_t) ((uint32_t) ((uint32_t) bytes [1] & 0xF0) >> 4));
+ uint32_t highMantissa =
+ (uint32_t) ((uint32_t) ((uint32_t) bytes [1] & 0x0F) << 16) |
+ (uint32_t) ((uint32_t) bytes [2] << 8) |
+ (uint32_t) bytes [3];
+ uint32_t lowMantissa =
+ (uint32_t) ((uint32_t) bytes [4] << 24) |
+ (uint32_t) ((uint32_t) bytes [5] << 16) |
+ (uint32_t) ((uint32_t) bytes [6] << 8) |
+ (uint32_t) bytes [7];
double x;
if (exponent == 0)
if (highMantissa == 0 && lowMantissa == 0) x = 0.0;
- else x = ldexp (UnsignedToFloat (highMantissa), exponent - 1042) +
- ldexp (UnsignedToFloat (lowMantissa), exponent - 1074); // denormalized
+ else x = ldexp ((double) highMantissa, exponent - 1042) +
+ ldexp ((double) lowMantissa, exponent - 1074); // denormalized
else if (exponent == 0x07FF) // Infinity or Not-a-Number
x = HUGE_VAL;
else
- x = ldexp (UnsignedToFloat (highMantissa | 0x00100000), exponent - 1043) +
- ldexp (UnsignedToFloat (lowMantissa), exponent - 1075);
+ x = ldexp ((double) (highMantissa | 0x00100000), exponent - 1043) +
+ ldexp ((double) lowMantissa, exponent - 1075);
return bytes [0] & 0x80 ? - x : x;
}
} catch (MelderError) {
@@ -986,16 +1025,26 @@ double bingetr10 (FILE *f) {
try {
unsigned char bytes [10];
if (fread (bytes, sizeof (unsigned char), 10, f) != 10) readError (f, "ten bytes.");
- long exponent = ((bytes [0] & 0x7F) << 8) | bytes [1];
- unsigned long highMantissa = ((unsigned long) bytes [2] << 24) | ((unsigned long) bytes [3] << 16) | ((unsigned long) bytes [4] << 8) | (unsigned long) bytes [5];
- unsigned long lowMantissa = ((unsigned long) bytes [6] << 24) | ((unsigned long) bytes [7] << 16) | ((unsigned long) bytes [8] << 8) | (unsigned long) bytes [9];
+ int32_t exponent = (int32_t)
+ ((uint32_t) ((uint32_t) ((uint32_t) bytes [0] & 0x7F) << 8) |
+ (uint32_t) bytes [1]);
+ uint32_t highMantissa =
+ (uint32_t) ((uint32_t) bytes [2] << 24) |
+ (uint32_t) ((uint32_t) bytes [3] << 16) |
+ (uint32_t) ((uint32_t) bytes [4] << 8) |
+ (uint32_t) bytes [5];
+ uint32_t lowMantissa =
+ (uint32_t) ((uint32_t) bytes [6] << 24) |
+ (uint32_t) ((uint32_t) bytes [7] << 16) |
+ (uint32_t) ((uint32_t) bytes [8] << 8) |
+ (uint32_t) bytes [9];
double x;
if (exponent == 0 && highMantissa == 0 && lowMantissa == 0) x = 0;
- else if (exponent == 0x7FFF) x = HUGE_VAL; /* Infinity or NaN */
+ else if (exponent == 0x7FFF) x = HUGE_VAL; // Infinity or NaN
else {
exponent -= 16383;
- x = ldexp (UnsignedToFloat (highMantissa), exponent - 31);
- x += ldexp (UnsignedToFloat (lowMantissa), exponent - 63);
+ x = ldexp ((double) highMantissa, exponent - 31);
+ x += ldexp ((double) lowMantissa, exponent - 63);
}
return bytes [0] & 0x80 ? - x : x;
} catch (MelderError) {
@@ -1030,15 +1079,14 @@ void binputb (FILE *f) {
writeBuffer = 0;
}
-void binputi2 (int i, FILE *f) {
+void binputi2 (int16_t i, FILE *f) {
try {
- if (binario_shortBE2 && Melder_debug != 18) {
- short s = i;
- if (fwrite (& s, sizeof (short), 1, f) != 1) writeError ("a signed short integer.");
+ if (binario_16bitBE && Melder_debug != 18) {
+ if (fwrite (& i, sizeof (short), 1, f) != 1) writeError ("a signed 16-bit integer.");
} else {
char bytes [2];
- bytes [0] = i >> 8;
- bytes [1] = i;
+ bytes [0] = (char) (i >> 8); // truncate
+ bytes [1] = (char) (i); // truncate
if (fwrite (bytes, sizeof (char), 2, f) != 2) writeError ("two bytes.");
}
} catch (MelderError) {
@@ -1046,155 +1094,152 @@ void binputi2 (int i, FILE *f) {
}
}
-void binputu2 (unsigned int u, FILE *f) {
+void binputi2LE (int16_t i, FILE *f) {
try {
- if (binario_shortBE2 && Melder_debug != 18) {
- unsigned short s = u;
- if (fwrite (& s, sizeof (unsigned short), 1, f) != 1) writeError ("an unsigned short integer.");
+ if (binario_16bitLE && Melder_debug != 18) {
+ if (fwrite (& i, sizeof (short), 1, f) != 1) writeError ("a signed 16-bit integer.");
} else {
char bytes [2];
- bytes [0] = u >> 8;
- bytes [1] = u;
+ bytes [1] = (char) (i >> 8); // truncate
+ bytes [0] = (char) (i); // truncate
if (fwrite (bytes, sizeof (char), 2, f) != 2) writeError ("two bytes.");
}
} catch (MelderError) {
- Melder_throw ("Unsigned integer not written to 2 bytes in binary file.");
+ Melder_throw ("Signed integer not written to 2 bytes in binary file.");
}
}
-void binpute2 (int value, FILE *f) {
+void binputu2 (uint16_t u, FILE *f) {
try {
- if (binario_shortBE2 && Melder_debug != 18) {
- short s = value;
- if (fwrite (& s, sizeof (short), 1, f) != 1) writeError ("a signed short integer");
+ if (binario_16bitBE && Melder_debug != 18) {
+ if (fwrite (& u, sizeof (uint16_t), 1, f) != 1) writeError ("an unsigned 16-bit integer.");
} else {
char bytes [2];
- bytes [0] = value >> 8;
- bytes [1] = value;
+ bytes [0] = (char) (u >> 8); // truncate
+ bytes [1] = (char) (u); // truncate
if (fwrite (bytes, sizeof (char), 2, f) != 2) writeError ("two bytes.");
}
} catch (MelderError) {
- Melder_throw ("Enumerated value not written to 2 bytes in binary file.");
+ Melder_throw ("Unsigned integer not written to 2 bytes in binary file.");
}
}
-void binputi3 (long i, FILE *f) {
+void binputu2LE (uint16_t u, FILE *f) {
try {
- char bytes [3];
- bytes [0] = i >> 16;
- bytes [1] = i >> 8;
- bytes [2] = i;
- if (fwrite (bytes, sizeof (char), 3, f) != 3) writeError ("three bytes");
+ if (binario_16bitLE && Melder_debug != 18) {
+ if (fwrite (& u, sizeof (uint16_t), 1, f) != 1) writeError ("an unsigned 16-bit integer.");
+ } else {
+ char bytes [2];
+ bytes [1] = (char) (u >> 8); // truncate
+ bytes [0] = (char) (u); // truncate
+ if (fwrite (bytes, sizeof (char), 2, f) != 2) writeError ("two bytes.");
+ }
} catch (MelderError) {
- Melder_throw ("Signed integer not written to 3 bytes in binary file.");
+ Melder_throw ("Unsigned integer not written to 2 bytes in binary file.");
}
}
-void binputi4 (long i, FILE *f) {
+void binpute2 (int value, FILE *f) {
try {
- if (binario_longBE4 && Melder_debug != 18) {
- if (fwrite (& i, sizeof (long), 1, f) != 1) writeError ("a signed long integer.");
+ if (binario_16bitBE && Melder_debug != 18) {
+ short s = value;
+ if (fwrite (& s, sizeof (short), 1, f) != 1) writeError ("a signed 16-bit integer");
} else {
- char bytes [4];
- bytes [0] = i >> 24;
- bytes [1] = i >> 16;
- bytes [2] = i >> 8;
- bytes [3] = i;
- if (fwrite (bytes, sizeof (char), 4, f) != 4) writeError ("four bytes.");
+ char bytes [2];
+ bytes [0] = (char) (value >> 8); // truncate
+ bytes [1] = (char) (value); // truncate
+ if (fwrite (bytes, sizeof (char), 2, f) != 2) writeError ("two bytes.");
}
} catch (MelderError) {
- Melder_throw ("Signed integer not written to 4 bytes in binary file.");
+ Melder_throw ("Enumerated value not written to 2 bytes in binary file.");
}
}
-void binputu4 (unsigned long u, FILE *f) {
+void binputi3 (int32_t i, FILE *f) {
try {
- if (binario_longBE4 && Melder_debug != 18) {
- if (fwrite (& u, sizeof (unsigned long), 1, f) != 1) writeError ("an unsigned long integer.");
- } else {
- char bytes [4];
- bytes [0] = u >> 24;
- bytes [1] = u >> 16;
- bytes [2] = u >> 8;
- bytes [3] = u;
- if (fwrite (bytes, sizeof (char), 4, f) != 4) writeError ("four bytes.");
- }
+ char bytes [3];
+ bytes [0] = (char) (i >> 16); // truncate
+ bytes [1] = (char) (i >> 8); // truncate
+ bytes [2] = (char) (i); // truncate
+ if (fwrite (bytes, sizeof (char), 3, f) != 3) writeError ("three bytes");
} catch (MelderError) {
- Melder_throw ("Unsigned integer not written to 4 bytes in binary file.");
+ Melder_throw ("Signed integer not written to 3 bytes in binary file.");
}
}
-void binputi2LE (int i, FILE *f) {
+void binputi3LE (int32_t i, FILE *f) {
try {
- if (binario_shortLE2 && Melder_debug != 18) {
- short s = i;
- if (fwrite (& s, sizeof (short), 1, f) != 1) writeError ("a signed short integer.");
- } else {
- char bytes [2];
- bytes [1] = i >> 8;
- bytes [0] = i;
- if (fwrite (bytes, sizeof (char), 2, f) != 2) writeError ("two bytes.");
- }
+ char bytes [3];
+ bytes [2] = (char) (i >> 16); // truncate
+ bytes [1] = (char) (i >> 8); // truncate
+ bytes [0] = (char) (i); // truncate
+ if (fwrite (bytes, sizeof (char), 3, f) != 3) writeError ("three bytes");
} catch (MelderError) {
- Melder_throw ("Signed integer not written to 2 bytes in binary file.");
+ Melder_throw ("Signed integer not written to 3 bytes in binary file.");
}
}
-void binputu2LE (unsigned int u, FILE *f) {
+void binputi4 (int32_t i, FILE *f) {
try {
- if (binario_shortLE2 && Melder_debug != 18) {
- unsigned short s = u;
- if (fwrite (& s, sizeof (unsigned short), 1, f) != 1) writeError ("an unsigned short integer.");
+ if (binario_32bitBE && Melder_debug != 18) {
+ if (fwrite (& i, sizeof (int32_t), 1, f) != 1) writeError ("a signed 32-bit integer.");
} else {
- char bytes [2];
- bytes [1] = u >> 8;
- bytes [0] = u;
- if (fwrite (bytes, sizeof (char), 2, f) != 2) writeError ("two bytes.");
+ char bytes [4];
+ bytes [0] = (char) (i >> 24); // truncate
+ bytes [1] = (char) (i >> 16); // truncate
+ bytes [2] = (char) (i >> 8); // truncate
+ bytes [3] = (char) (i); // truncate
+ if (fwrite (bytes, sizeof (char), 4, f) != 4) writeError ("four bytes.");
}
} catch (MelderError) {
- Melder_throw ("Unsigned integer not written to 2 bytes in binary file.");
+ Melder_throw ("Signed integer not written to 4 bytes in binary file.");
}
}
-void binputi3LE (long i, FILE *f) {
+void binputi4LE (int32_t i, FILE *f) {
try {
- char bytes [3];
- bytes [2] = i >> 16;
- bytes [1] = i >> 8;
- bytes [0] = i;
- if (fwrite (bytes, sizeof (char), 3, f) != 3) writeError ("three bytes");
+ if (binario_32bitLE && Melder_debug != 18) {
+ if (fwrite (& i, sizeof (int32_t), 1, f) != 1) writeError ("a signed 32-bit integer.");
+ } else {
+ char bytes [4];
+ bytes [3] = (char) (i >> 24); // truncate
+ bytes [2] = (char) (i >> 16); // truncate
+ bytes [1] = (char) (i >> 8); // truncate
+ bytes [0] = (char) (i); // truncate
+ if (fwrite (bytes, sizeof (char), 4, f) != 4) writeError ("four bytes.");
+ }
} catch (MelderError) {
- Melder_throw ("Signed integer not written to 3 bytes in binary file.");
+ Melder_throw ("Signed integer not written to 4 bytes in binary file.");
}
}
-void binputi4LE (long i, FILE *f) {
+void binputu4 (uint32_t u, FILE *f) {
try {
- if (binario_longLE4 && Melder_debug != 18) {
- if (fwrite (& i, sizeof (long), 1, f) != 1) writeError ("a signed long integer.");
+ if (binario_32bitBE && Melder_debug != 18) {
+ if (fwrite (& u, sizeof (uint32_t), 1, f) != 1) writeError ("an unsigned 32-bit integer.");
} else {
char bytes [4];
- bytes [3] = i >> 24;
- bytes [2] = i >> 16;
- bytes [1] = i >> 8;
- bytes [0] = i;
+ bytes [0] = (char) (u >> 24); // truncate
+ bytes [1] = (char) (u >> 16); // truncate
+ bytes [2] = (char) (u >> 8); // truncate
+ bytes [3] = (char) (u); // truncate
if (fwrite (bytes, sizeof (char), 4, f) != 4) writeError ("four bytes.");
}
} catch (MelderError) {
- Melder_throw ("Signed integer not written to 4 bytes in binary file.");
+ Melder_throw ("Unsigned integer not written to 4 bytes in binary file.");
}
}
-void binputu4LE (unsigned long u, FILE *f) {
+void binputu4LE (uint32_t u, FILE *f) {
try {
- if (binario_longLE4 && Melder_debug != 18) {
- if (fwrite (& u, sizeof (unsigned long), 1, f) != 1) writeError ("an unsigned long integer.");
+ if (binario_32bitLE && Melder_debug != 18) {
+ if (fwrite (& u, sizeof (uint32_t), 1, f) != 1) writeError ("an unsigned 32-bit integer.");
} else {
char bytes [4];
- bytes [3] = u >> 24;
- bytes [2] = u >> 16;
- bytes [1] = u >> 8;
- bytes [0] = u;
+ bytes [3] = (char) (u >> 24); // truncate
+ bytes [2] = (char) (u >> 16); // truncate
+ bytes [1] = (char) (u >> 8); // truncate
+ bytes [0] = (char) (u); // truncate
if (fwrite (bytes, sizeof (char), 4, f) != 4) writeError ("four bytes.");
}
} catch (MelderError) {
@@ -1205,13 +1250,13 @@ void binputu4LE (unsigned long u, FILE *f) {
void binputr4 (double x, FILE *f) {
try {
if (binario_floatIEEE4msb && Melder_debug != 18) {
- float x4 = x;
- if (fwrite (& x4, sizeof (float), 1, f) != 1) writeError ("a single-precision floating-point number.");
+ float x4 = (float) x; // convert down, with loss of precision
+ if (fwrite (& x4, sizeof (float), 1, f) != 1) writeError ("a 32-bit floating-point number.");
} else {
unsigned char bytes [4];
int sign, exponent;
double fMantissa, fsMantissa;
- unsigned long mantissa;
+ uint32_t mantissa;
if (x < 0.0) { sign = 0x0100; x *= -1; }
else sign = 0;
if (x == 0.0) { exponent = 0; mantissa = 0; }
@@ -1219,7 +1264,7 @@ void binputr4 (double x, FILE *f) {
fMantissa = frexp (x, & exponent);
if ((exponent > 128) || ! (fMantissa < 1)) // Infinity or Not-a-Number
{ exponent = sign | 0x00FF; mantissa = 0; } // Infinity
- else { /* Finite. */
+ else { // finite
exponent += 126; // add bias
if (exponent <= 0) { // denormalized
fMantissa = ldexp (fMantissa, exponent - 1);
@@ -1228,10 +1273,10 @@ void binputr4 (double x, FILE *f) {
exponent |= sign;
fMantissa = ldexp (fMantissa, 24);
fsMantissa = floor (fMantissa);
- mantissa = FloatToUnsigned (fsMantissa) & 0x007FFFFF;
+ mantissa = (uint32_t) fsMantissa & 0x007FFFFF;
}
}
- bytes [0] = exponent >> 1;
+ bytes [0] = (uint8_t) (exponent >> 1); // truncate: bits 2 through 9 (bit 9 is the sign bit)
bytes [1] = (exponent << 7) | (mantissa >> 16);
bytes [2] = mantissa >> 8;
bytes [3] = mantissa;
@@ -1245,13 +1290,13 @@ void binputr4 (double x, FILE *f) {
void binputr4LE (double x, FILE *f) {
try {
if (binario_floatIEEE4lsb && Melder_debug != 18) {
- float x4 = x;
- if (fwrite (& x4, sizeof (float), 1, f) != 1) writeError ("a single-precision floating-point number.");
+ float x4 = (float) x; // convert down, with loss of precision
+ if (fwrite (& x4, sizeof (float), 1, f) != 1) writeError ("a 32-bit floating-point number.");
} else {
unsigned char bytes [4];
int sign, exponent;
double fMantissa, fsMantissa;
- unsigned long mantissa;
+ uint32_t mantissa;
if (x < 0.0) { sign = 0x0100; x *= -1; }
else sign = 0;
if (x == 0.0) { exponent = 0; mantissa = 0; }
@@ -1268,7 +1313,7 @@ void binputr4LE (double x, FILE *f) {
exponent |= sign;
fMantissa = ldexp (fMantissa, 24);
fsMantissa = floor (fMantissa);
- mantissa = FloatToUnsigned (fsMantissa) & 0x007FFFFF;
+ mantissa = (uint32_t) fsMantissa & 0x007FFFFF;
}
}
bytes [3] = exponent >> 1;
@@ -1285,12 +1330,12 @@ void binputr4LE (double x, FILE *f) {
void binputr8 (double x, FILE *f) {
try {
if (binario_doubleIEEE8msb && Melder_debug != 18) {
- if (fwrite (& x, sizeof (double), 1, f) != 1) writeError ("a double-precision floating-point number.");
+ if (fwrite (& x, sizeof (double), 1, f) != 1) writeError ("a 64-bit floating-point number.");
} else {
unsigned char bytes [8];
int sign, exponent;
double fMantissa, fsMantissa;
- unsigned long highMantissa, lowMantissa;
+ uint32_t highMantissa, lowMantissa;
if (x < 0.0) { sign = 0x0800; x *= -1; }
else sign = 0;
if (x == 0.0) { exponent = 0; highMantissa = 0; lowMantissa = 0; }
@@ -1307,10 +1352,10 @@ void binputr8 (double x, FILE *f) {
exponent |= sign;
fMantissa = ldexp (fMantissa, 21);
fsMantissa = floor (fMantissa);
- highMantissa = FloatToUnsigned (fsMantissa) & 0x000FFFFF;
+ highMantissa = (uint32_t) fsMantissa & 0x000FFFFF;
fMantissa = ldexp (fMantissa - fsMantissa, 32);
fsMantissa = floor (fMantissa);
- lowMantissa = FloatToUnsigned (fsMantissa);
+ lowMantissa = (uint32_t) fsMantissa;
}
}
bytes [0] = exponent >> 4;
@@ -1331,9 +1376,10 @@ void binputr8 (double x, FILE *f) {
void binputr10 (double x, FILE *f) {
try {
unsigned char bytes [10];
- int sign, exponent;
+ Melder_assert (sizeof (int) > 2);
+ int sign, exponent; // these should be uint16_t, but frexp() expects an int
double fMantissa, fsMantissa;
- unsigned long highMantissa, lowMantissa;
+ uint32_t highMantissa, lowMantissa;
if (x < 0.0) { sign = 0x8000; x *= -1; }
else sign = 0;
if (x == 0.0) { exponent = 0; highMantissa = 0; lowMantissa = 0; }
@@ -1341,19 +1387,19 @@ void binputr10 (double x, FILE *f) {
fMantissa = frexp (x, & exponent);
if ((exponent > 16384) || ! (fMantissa < 1)) // Infinity or Not-a-Number
{ exponent = sign | 0x7FFF; highMantissa = 0; lowMantissa = 0; } // Infinity
- else { /* Finite */
- exponent += 16382; /* Add bias. */
- if (exponent < 0) { /* Denormalized. */
+ else { // finite
+ exponent += 16382; // add bias
+ if (exponent < 0) { // denormalized
fMantissa = ldexp (fMantissa, exponent);
exponent = 0;
}
exponent |= sign;
fMantissa = ldexp (fMantissa, 32);
fsMantissa = floor (fMantissa);
- highMantissa = FloatToUnsigned (fsMantissa);
+ highMantissa = (uint32_t) fsMantissa;
fMantissa = ldexp (fMantissa - fsMantissa, 32);
fsMantissa = floor (fMantissa);
- lowMantissa = FloatToUnsigned (fsMantissa);
+ lowMantissa = (uint32_t) fsMantissa;
}
}
bytes [0] = exponent >> 8;
@@ -1444,8 +1490,8 @@ char * bingets2 (FILE *f) {
char * bingets4 (FILE *f) {
try {
- unsigned long length = bingetu4 (f);
- autostring8 result = Melder_malloc (char, length + 1);
+ uint32_t length = bingetu4 (f);
+ autostring8 result = Melder_malloc (char, (int64_t) length + 1);
if (fread (result.peek(), sizeof (char), length, f) != length)
Melder_throw (feof (f) ? "Reached end of file" : "Error in file", " while trying to read ", length, " one-byte characters.");
result [length] = 0; // trailing null byte
@@ -1464,7 +1510,7 @@ wchar_t * bingetw1 (FILE *f) {
* UTF-16
*/
length = bingetu1 (f);
- result.reset (Melder_malloc (wchar_t, length + 1));
+ result.reset (Melder_malloc (wchar_t, (int64_t) length + 1));
for (unsigned short i = 0; i < length; i ++) {
if (sizeof (wchar_t) == 2) {
result [i] = (wchar_t) bingetu2 (f); // add sign
@@ -1486,7 +1532,7 @@ wchar_t * bingetw1 (FILE *f) {
/*
* ASCII
*/
- result.reset (Melder_malloc (wchar_t, length + 1));
+ result.reset (Melder_malloc (wchar_t, (int64_t) length + 1));
for (unsigned short i = 0; i < length; i ++) {
result [i] = bingetu1 (f);
}
@@ -1507,8 +1553,8 @@ wchar_t * bingetw2 (FILE *f) {
* UTF-16
*/
length = bingetu2 (f);
- result.reset (Melder_malloc (wchar_t, length + 1));
- for (unsigned short i = 0; i < length; i ++) {
+ result.reset (Melder_malloc (wchar_t, (int64_t) length + 1));
+ for (uint16_t i = 0; i < length; i ++) {
if (sizeof (wchar_t) == 2) {
result [i] = (wchar_t) bingetu2 (f);
} else {
@@ -1544,14 +1590,14 @@ wchar_t * bingetw2 (FILE *f) {
wchar_t * bingetw4 (FILE *f) {
try {
autostring result = NULL;
- unsigned long length = bingetu4 (f);
+ uint32_t length = bingetu4 (f);
if (length == 0xFFFFFFFF) { // an escape for encoding
/*
* UTF-16
*/
length = bingetu4 (f);
- result.reset (Melder_malloc (wchar_t, length + 1));
- for (unsigned long i = 0; i < length; i ++) {
+ result.reset (Melder_malloc (wchar_t, (int64_t) length + 1));
+ for (uint32_t i = 0; i < length; i ++) {
if (sizeof (wchar_t) == 2) {
result [i] = (wchar_t) bingetu2 (f);
} else {
@@ -1572,8 +1618,8 @@ wchar_t * bingetw4 (FILE *f) {
/*
* ASCII
*/
- result.reset (Melder_malloc (wchar_t, length + 1));
- for (unsigned long i = 0; i < length; i ++) {
+ result.reset (Melder_malloc (wchar_t, (int64_t) length + 1));
+ for (uint32_t i = 0; i < length; i ++) {
result [i] = bingetu1 (f);
}
}
@@ -1589,10 +1635,10 @@ void binputs1 (const char *s, FILE *f) {
if (s == NULL) {
binputu1 (0, f);
} else {
- unsigned long length = strlen (s);
- if (length > 255) {
+ size_t length = strlen (s);
+ if (length > UINT8_MAX) {
Melder_warning ("Text of ", length, " characters truncated to 255 characters.");
- length = 255;
+ length = UINT8_MAX;
}
binputu1 (length, f);
if (fwrite (s, sizeof (char), length, f) != length)
@@ -1608,12 +1654,12 @@ void binputs2 (const char *s, FILE *f) {
if (s == NULL) {
binputu2 (0, f);
} else {
- unsigned long length = strlen (s);
- if (length > 65535) {
+ size_t length = strlen (s);
+ if (length > UINT16_MAX) {
Melder_warning ("Text of ", length, " characters truncated to 65535 characters.");
- length = 65535;
+ length = UINT16_MAX;
}
- binputu2 (length, f);
+ binputu2 ((uint16_t) length, f); // safe conversion down
if (fwrite (s, sizeof (char), length, f) != length)
Melder_throw ("Error in file while trying to write ", length, " one-byte characters.");
}
@@ -1627,7 +1673,11 @@ void binputs4 (const char *s, FILE *f) {
if (s == NULL) {
binputu4 (0, f);
} else {
- unsigned long length = strlen (s);
+ size_t length = strlen (s);
+ if (length > UINT32_MAX) {
+ Melder_warning ("Text of ", length, " characters truncated to 4,294,967,295 characters.");
+ length = UINT32_MAX;
+ }
binputu4 (length, f);
if (fwrite (s, sizeof (char), length, f) != length)
Melder_throw ("Error in file while trying to write ", length, " one-byte characters.");
@@ -1638,16 +1688,16 @@ void binputs4 (const char *s, FILE *f) {
}
static inline void binpututf16 (wchar_t character, FILE *f) {
- if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16?
- binputu2 (character, f);
- } else { // wchar_t is UTF-32.
- utf32_t kar = character;
- if (kar <= 0xFFFF) {
- binputu2 (character, f);
- } else if (kar <= 0x10FFFF) {
+ if (sizeof (wchar_t) == 2) { // wchar_t is (signed) UTF-16?
+ binputu2 ((uint16_t) character, f); // convert sign
+ } else { // wchar_t is (signed) UTF-32.
+ char32_t kar = (char32_t) character; // safe, because sign bit is always zero
+ if (kar <= 0x0000FFFF) {
+ binputu2 ((uint16_t) character, f); // truncate to lower 16 bits
+ } else if (kar <= 0x0010FFFF) {
kar -= 0x10000;
- binputu2 (0xD800 | (kar >> 10), f);
- binputu2 (0xDC00 | (kar & 0x3FF), f);
+ binputu2 ((uint16_t) (0x0000D800 | (kar >> 10)), f);
+ binputu2 ((uint16_t) (0xDC00 | (kar & 0x3FF)), f);
} else {
Melder_fatal ("Impossible Unicode value.");
}
@@ -1659,18 +1709,18 @@ void binputw1 (const wchar_t *s, FILE *f) {
if (s == NULL) {
binputu1 (0, f);
} else {
- unsigned long length = wcslen (s);
- if (length > 254) {
+ size_t length = wcslen (s);
+ if (length > UINT8_MAX - 1) {
Melder_warning ("Text of ", length, " characters truncated to 254 characters.");
- length = 254;
+ length = UINT8_MAX - 1;
}
if (Melder_isValidAscii (s)) {
/*
* ASCII
*/
binputu1 (length, f);
- for (unsigned long i = 0; i < length; i ++) {
- binputu1 (s [i], f);
+ for (size_t i = 0; i < length; i ++) {
+ binputu1 ((unsigned int) (char) s [i], f);
}
} else {
/*
@@ -1678,7 +1728,7 @@ void binputw1 (const wchar_t *s, FILE *f) {
*/
binputu1 (0xFF, f); // an escape for multibyte encoding
binputu1 (length, f);
- for (unsigned long i = 0; i < length; i ++) {
+ for (size_t i = 0; i < length; i ++) {
binpututf16 (s [i], f);
}
}
@@ -1693,26 +1743,26 @@ void binputw2 (const wchar_t *s, FILE *f) {
if (s == NULL) {
binputu2 (0, f);
} else {
- unsigned long length = wcslen (s);
- if (length > 65534) {
+ size_t length = wcslen (s);
+ if (length > UINT16_MAX - 1) {
Melder_warning ("Text of ", length, " characters truncated to 65534 characters.");
- length = 65534;
+ length = UINT16_MAX - 1;
}
if (Melder_isValidAscii (s)) {
/*
* ASCII
*/
- binputu2 (length, f);
- for (unsigned long i = 0; i < length; i ++) {
- binputu1 (s [i], f);
+ binputu2 ((uint16_t) length, f);
+ for (size_t i = 0; i < length; i ++) {
+ binputu1 ((unsigned int) (char) s [i], f);
}
} else {
/*
* UTF-16
*/
binputu2 (0xFFFF, f); // an escape for multibyte encoding
- binputu2 (length, f);
- for (unsigned long i = 0; i < length; i ++) {
+ binputu2 ((uint16_t) length, f);
+ for (size_t i = 0; i < length; i ++) {
binpututf16 (s [i], f);
}
}
@@ -1727,14 +1777,18 @@ void binputw4 (const wchar_t *s, FILE *f) {
if (s == NULL) {
binputu4 (0, f);
} else {
- unsigned long length = wcslen (s);
+ size_t length = wcslen (s);
+ if (length > UINT32_MAX - 1) {
+ Melder_warning ("Text of ", length, " characters truncated to 4,294,967,294 characters.");
+ length = UINT32_MAX - 1;
+ }
if (Melder_isValidAscii (s)) {
/*
* ASCII
*/
binputu4 (length, f);
- for (unsigned long i = 0; i < length; i ++) {
- binputu1 (s [i], f);
+ for (size_t i = 0; i < length; i ++) {
+ binputu1 ((unsigned int) (char) s [i], f);
}
} else {
/*
@@ -1742,7 +1796,7 @@ void binputw4 (const wchar_t *s, FILE *f) {
*/
binputu4 (0xFFFFFFFF, f); // an escape for multibyte encoding
binputu4 (length, f);
- for (unsigned long i = 0; i < length; i ++) {
+ for (size_t i = 0; i < length; i ++) {
binpututf16 (s [i], f);
}
}
@@ -1859,7 +1913,7 @@ macro_cacgetb (7)
void cacgetb (CACHE *f) { (void) f; bitsInReadBuffer = 0; }
int cacgeti2 (CACHE *f) {
- if (binario_shortBE2) {
+ if (binario_16bitBE) {
short s;
START (s) READ READ
return s; /* With sign extension if an int is 4 bytes. */
@@ -1871,7 +1925,7 @@ int cacgeti2 (CACHE *f) {
}
unsigned int cacgetu2 (CACHE *f) {
- if (binario_shortBE2) {
+ if (binario_16bitBE) {
unsigned short s;
START (s) READ READ
return s; /* Without sign extension. */
@@ -1884,7 +1938,7 @@ unsigned int cacgetu2 (CACHE *f) {
int cacgete2 (CACHE *f, const wchar_t *type) {
signed short s;
- if (binario_shortBE2) {
+ if (binario_16bitBE) {
START (s) READ READ
} else {
unsigned char bytes [2];
@@ -1897,7 +1951,7 @@ int cacgete2 (CACHE *f, const wchar_t *type) {
}
long cacgeti4 (CACHE *f) {
- if (binario_longBE4) {
+ if (binario_32bitBE) {
long l;
START (l) READ READ READ READ
return l;
@@ -1913,7 +1967,7 @@ long cacgeti4 (CACHE *f) {
}
unsigned long cacgetu4 (CACHE *f) {
- if (binario_longBE4) {
+ if (binario_32bitBE) {
unsigned long l;
START (l) READ READ READ READ
return l;
@@ -2054,7 +2108,7 @@ void cacputb (CACHE *f) {
}
void cacputi2 (int i, CACHE *f) {
- if (binario_shortBE2) {
+ if (binario_16bitBE) {
short s = i;
START (s) WRITE WRITE
} else {
@@ -2066,7 +2120,7 @@ void cacputi2 (int i, CACHE *f) {
}
void cacputu2 (unsigned int u, CACHE *f) {
- if (binario_shortBE2) {
+ if (binario_16bitBE) {
unsigned short s = u;
START (s) WRITE WRITE
} else {
@@ -2078,7 +2132,7 @@ void cacputu2 (unsigned int u, CACHE *f) {
}
void cacpute2 (int value, CACHE *f) {
- if (binario_shortBE2) {
+ if (binario_16bitBE) {
signed short s = value;
START (s) WRITE WRITE
} else {
@@ -2090,7 +2144,7 @@ void cacpute2 (int value, CACHE *f) {
}
void cacputi4 (long i, CACHE *f) {
- if (binario_longBE4) {
+ if (binario_32bitBE) {
START (i) WRITE WRITE WRITE WRITE
} else {
char bytes [4];
@@ -2103,7 +2157,7 @@ void cacputi4 (long i, CACHE *f) {
}
void cacputu4 (unsigned long u, CACHE *f) {
- if (binario_longBE4) {
+ if (binario_32bitBE) {
START (u) WRITE WRITE WRITE WRITE
} else {
char bytes [4];
diff --git a/sys/abcio.h b/sys/abcio.h
index c303810..c582a6d 100644
--- a/sys/abcio.h
+++ b/sys/abcio.h
@@ -28,7 +28,8 @@
int texgeti1 (MelderReadText text);
int texgeti2 (MelderReadText text);
-long texgeti4 (MelderReadText text);
+long texgeti32 (MelderReadText text);
+#define texgeti4 texgeti32
unsigned int texgetu1 (MelderReadText text);
unsigned int texgetu2 (MelderReadText text);
unsigned long texgetu4 (MelderReadText text);
@@ -54,7 +55,8 @@ void texputintro (MelderFile file, const wchar_t *s1, const wchar_t *s2, const w
void texputi1 (MelderFile file, int i, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6);
void texputi2 (MelderFile file, int i, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6);
-void texputi4 (MelderFile file, long i, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6);
+void texputi32 (MelderFile file, long i, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6);
+#define texputi4 texputi32
void texputu1 (MelderFile file, unsigned int u, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6);
void texputu2 (MelderFile file, unsigned int u, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6);
void texputu4 (MelderFile file, unsigned long u, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6);
@@ -81,24 +83,26 @@ void texputw4 (MelderFile file, const wchar_t *s, const wchar_t *s1, const wchar
int fgetc (FILE *f); int fputc (int c, FILE *f); // 0..255
*/
unsigned int bingetu1 (FILE *f); void binputu1 (unsigned int i, FILE *f); /* 0..255 */
-uint16_t bingetu2 (FILE *f); void binputu2 (unsigned int i, FILE *f); /* 0..65535 */
-unsigned long bingetu4 (FILE *f); void binputu4 (unsigned long i, FILE *f); /* 0..4294967295 */
+uint16_t bingetu2 (FILE *f); void binputu2 (uint16_t i, FILE *f); /* 0..65535 */
+uint32_t bingetu4 (FILE *f); void binputu4 (uint32_t i, FILE *f); /* 0..4294967295 */
int bingeti1 (FILE *f); void binputi1 (int i, FILE *f); /* -128..127 */
-int bingeti2 (FILE *f); void binputi2 (int i, FILE *f); /* -32768..32767 */
-long bingeti3 (FILE *f); void binputi3 (long i, FILE *f); /* -8388608..2148388607 */
-long bingeti4 (FILE *f); void binputi4 (long i, FILE *f); /* -2147483648..2147483647 */
+int16_t bingeti2 (FILE *f); void binputi2 (int16_t i, FILE *f); /* -32768..32767 */
+int32_t bingeti3 (FILE *f); void binputi3 (int32_t i, FILE *f); /* -8388608..2148388607 */
+int32_t bingeti32 (FILE *f); void binputi32 (int32_t i, FILE *f); /* -2147483648..2147483647 */
+#define bingeti4 bingeti32
+#define binputi4 binputi32
/*
Read or write signed or unsigned integers from or to 2 or 4 bytes in the stream 'f',
in big-endian byte order (most significant byte first).
This is the native integer format on Macintosh and Silicon Graphics Iris.
*/
-int bingeti2LE (FILE *f); void binputi2LE (int i, FILE *f); /* -32768..32767 */
-long bingeti3LE (FILE *f); void binputi3LE (long i, FILE *f); /* -8388608..2148388607 */
-long bingeti4LE (FILE *f); void binputi4LE (long i, FILE *f); /* -2147483648..2147483647 */
-uint16_t bingetu2LE (FILE *f); void binputu2LE (unsigned int i, FILE *f); /* 0..65535 */
-unsigned long bingetu4LE (FILE *f); void binputu4LE (unsigned long i, FILE *f); /* 0..4294967295 */
+int16_t bingeti2LE (FILE *f); void binputi2LE (int16_t i, FILE *f); /* -32768..32767 */
+int32_t bingeti3LE (FILE *f); void binputi3LE (int32_t i, FILE *f); /* -8388608..2148388607 */
+int32_t bingeti4LE (FILE *f); void binputi4LE (int32_t i, FILE *f); /* -2147483648..2147483647 */
+uint16_t bingetu2LE (FILE *f); void binputu2LE (uint16_t i, FILE *f); /* 0..65535 */
+uint32_t bingetu4LE (FILE *f); void binputu4LE (uint32_t i, FILE *f); /* 0..4294967295 */
/*
Read or write signed or unsigned integers from or to 2 or 4 bytes in the stream 'f',
in little-endian byte order (least significant byte first).
diff --git a/sys/melder.cpp b/sys/melder.cpp
index 8e9c8e1..c69f1a6 100644
--- a/sys/melder.cpp
+++ b/sys/melder.cpp
@@ -817,7 +817,7 @@ static void mac_message (NSAlertStyle macAlertType, const wchar_t *messageW) {
int messageLength = wcslen (messageW);
int j = 0;
for (int i = 0; i < messageLength && j <= 4000 - 3; i ++) {
- utf32_t kar = messageW [i];
+ char32_t kar = (char32_t) messageW [i]; // change sign
if (kar <= 0xFFFF) {
messageU [j ++] = kar;
} else if (kar <= 0x10FFFF) {
diff --git a/sys/melder.h b/sys/melder.h
index af3262f..6b38f50 100644
--- a/sys/melder.h
+++ b/sys/melder.h
@@ -2,7 +2,7 @@
#define _melder_h_
/* melder.h
*
- * Copyright (C) 1992-2012,2013,2014 Paul Boersma
+ * Copyright (C) 1992-2012,2013,2014,2015 Paul Boersma
*
* 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
@@ -37,6 +37,7 @@
#undef swprintf
#define swprintf _snwprintf
//#define swprintf __mingw_snwprintf
+ #include <sys/types.h> // for off_t
#endif
#include <stdbool.h>
/*
@@ -45,11 +46,23 @@
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include <stdint.h>
+#ifndef INT54_MAX
+ #define INT54_MAX 9007199254740991LL
+ #define INT54_MIN -9007199254740991LL
+#endif
typedef wchar_t wchar;
-typedef uint8_t utf8_t;
-typedef uint16_t utf16_t;
-typedef uint32_t utf32_t;
+typedef uint8_t char8_t;
+typedef char32_t char32;
+typedef char16_t char16;
+typedef char8_t char8;
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
bool Melder_wcsequ_firstCharacterCaseInsensitive (const wchar_t *string1, const wchar_t *string2);
@@ -66,24 +79,203 @@ bool Melder_wcsequ_firstCharacterCaseInsensitive (const wchar_t *string1, const
#ifndef NULL
#define NULL ((void *) 0)
#endif
-#ifndef INT32_MAX
- #define INT8_MAX 127
- #define INT16_MAX 32767
- #define INT32_MAX 2147483647
- #define INT64_MAX 9223372036854775807LL
-
- #define INT8_MIN -128
- #define INT16_MIN -32768
- #define INT32_MIN (-INT32_MAX-1)
- #define INT64_MIN (-INT64_MAX-1)
-
- #define UINT8_MAX 255
- #define UINT16_MAX 65535
- #define UINT32_MAX 4294967295U
- #define UINT64_MAX 18446744073709551615ULL
+
+/********** FILES **********/
+
+#if defined (_WIN32)
+ #define Melder_DIRECTORY_SEPARATOR '\\'
+#else
+ #define Melder_DIRECTORY_SEPARATOR '/'
+#endif
+
+struct FLAC__StreamDecoder;
+struct FLAC__StreamEncoder;
+
+#define kMelder_MAXPATH 1023 /* excluding the null byte */
+
+struct structMelderFile {
+ FILE *filePointer;
+ wchar_t path [kMelder_MAXPATH+1];
+ bool openForReading, openForWriting, verbose, requiresCRLF;
+ unsigned long outputEncoding;
+ int indent;
+ struct FLAC__StreamEncoder *flacEncoder;
+};
+typedef struct structMelderFile *MelderFile;
+
+struct structMelderDir {
+ wchar_t path [kMelder_MAXPATH+1];
+};
+typedef struct structMelderDir *MelderDir;
+
+#if defined (macintosh) && useCarbon
+ void Melder_machToFile (void *void_fsref, MelderFile file);
+#endif
+
+const wchar_t * MelderFile_name (MelderFile file);
+wchar_t * MelderDir_name (MelderDir dir);
+void Melder_pathToDir (const wchar_t *path, MelderDir dir);
+void Melder_pathToFile (const wchar_t *path, MelderFile file);
+void Melder_relativePathToFile (const wchar_t *path, MelderFile file);
+wchar_t * Melder_dirToPath (MelderDir dir);
+ /* Returns a pointer internal to 'dir', like "/u/paul/praats" or "D:\Paul\Praats" */
+wchar_t * Melder_fileToPath (MelderFile file);
+void MelderFile_copy (MelderFile file, MelderFile copy);
+void MelderDir_copy (MelderDir dir, MelderDir copy);
+bool MelderFile_equal (MelderFile file1, MelderFile file2);
+bool MelderDir_equal (MelderDir dir1, MelderDir dir2);
+void MelderFile_setToNull (MelderFile file);
+bool MelderFile_isNull (MelderFile file);
+void MelderDir_setToNull (MelderDir dir);
+bool MelderDir_isNull (MelderDir dir);
+void MelderDir_getFile (MelderDir parent, const wchar_t *fileName, MelderFile file);
+void MelderDir_relativePathToFile (MelderDir dir, const wchar_t *path, MelderFile file);
+void MelderFile_getParentDir (MelderFile file, MelderDir parent);
+void MelderDir_getParentDir (MelderDir file, MelderDir parent);
+bool MelderDir_isDesktop (MelderDir dir);
+void MelderDir_getSubdir (MelderDir parent, const wchar_t *subdirName, MelderDir subdir);
+void Melder_rememberShellDirectory (void);
+wchar_t * Melder_getShellDirectory (void);
+void Melder_getHomeDir (MelderDir homeDir);
+void Melder_getPrefDir (MelderDir prefDir);
+void Melder_getTempDir (MelderDir tempDir);
+
+bool MelderFile_exists (MelderFile file);
+bool MelderFile_readable (MelderFile file);
+long MelderFile_length (MelderFile file);
+void MelderFile_delete (MelderFile file);
+
+/* The following two should be combined with each other and with Windows extension setting: */
+FILE * Melder_fopen (MelderFile file, const char *type);
+void Melder_fclose (MelderFile file, FILE *stream);
+void Melder_files_cleanUp (void);
+
+/* So these will be the future replacements for the above, as soon as we rid of text files: */
+MelderFile MelderFile_open (MelderFile file);
+MelderFile MelderFile_append (MelderFile file);
+MelderFile MelderFile_create (MelderFile file);
+void * MelderFile_read (MelderFile file, long nbytes);
+char * MelderFile_readLine (MelderFile file);
+void MelderFile_writeCharacter (MelderFile file, wchar_t kar);
+void MelderFile_write (MelderFile file, const wchar_t *s1);
+void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2);
+void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3);
+void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4);
+void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5);
+void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6);
+void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6, const wchar_t *s7);
+void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6, const wchar_t *s7, const wchar_t *s8);
+void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6, const wchar_t *s7, const wchar_t *s8, const wchar_t *s9);
+void MelderFile_rewind (MelderFile file);
+void MelderFile_seek (MelderFile file, long position, int direction);
+long MelderFile_tell (MelderFile file);
+void MelderFile_close (MelderFile file);
+void MelderFile_close_nothrow (MelderFile file);
+
+/* Read and write whole text files. */
+wchar_t * MelderFile_readText (MelderFile file);
+void MelderFile_writeText (MelderFile file, const wchar_t *text, enum kMelder_textOutputEncoding outputEncoding);
+void MelderFile_appendText (MelderFile file, const wchar_t *text);
+
+void Melder_createDirectory (MelderDir parent, const wchar_t *subdirName, int mode);
+
+void Melder_getDefaultDir (MelderDir dir);
+void Melder_setDefaultDir (MelderDir dir);
+void MelderFile_setDefaultDir (MelderFile file);
+
+/* Use the following functions to pass unchanged text or file names to Melder_* functions. */
+/* Backslashes are replaced by "\bs". */
+/* The trick is that they return one of 11 cyclically used static strings, */
+/* so you can use up to 11 strings in a single Melder_* call. */
+wchar_t * Melder_peekExpandBackslashes (const wchar_t *message);
+const wchar_t * MelderFile_messageName (MelderFile file); // Calls Melder_peekExpandBackslashes ().
+
+/*
+ * Debugging.
+ */
+int Melder_fatal (const char *format, ...);
+ /* Give error message, abort program. */
+ /* Should only be caused by programming errors. */
+
+int Melder_assert_ (const char *condition, const char *fileName, int lineNumber);
+ /* Call Melder_fatal with a message based on the following template: */
+ /* "Assertion failed in file <fileName> on line <lineNumber>: <condition>" */
+
+void Melder_setTracing (bool tracing);
+extern bool Melder_isTracing;
+void Melder_tracingToFile (MelderFile file);
+void Melder_trace_FMT (const char *fileName, int lineNumber, const char *functionName, const char *format, ...);
+#ifdef NDEBUG
+ #define Melder_assert(x) ((void) 0)
+ #define trace(x) ((void) 0)
+#else
+ #define Melder_assert(x) ((x) ? (void) (0) : (void) Melder_assert_ (#x, __FILE__, __LINE__))
+ #define trace(...) ((! Melder_isTracing) ? (void) 0 : Melder_trace_FMT (__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__))
#endif
/*
+ * char16 and char32 handling.
+ */
+static inline int64_t str16len (const char16_t *string) {
+ if (sizeof (wchar_t) == 2) {
+ return (int64_t) wcslen ((const wchar_t *) string);
+ } else {
+ int64_t result = 0;
+ while (* string ++ != u'\0') result ++;
+ return result;
+ }
+}
+static inline void str16cpy (char16_t *target, const char16_t *source) {
+ if (sizeof (wchar_t) == 2) {
+ wcscpy ((wchar_t *) target, (const wchar_t *) source);
+ } else {
+ while (* source != u'\0') * target ++ = * source ++;
+ * target = u'\0';
+ }
+}
+static inline int str16cmp (const char16_t *string1, const char16_t *string2) {
+ if (sizeof (wchar_t) == 2) {
+ return wcscmp ((const wchar_t *) string1, (const wchar_t *) string2);
+ } else {
+ while (*string1 == *string2 ++) {
+ if (*string1 ++ == u'\0') {
+ return 0;
+ }
+ }
+ return (int) (int16_t) (string1 [0] - string2 [-1]); // unsigned subtraction, then sign conversion, then up conversion
+ }
+}
+static inline int64_t str32len (const char32_t *string) {
+ if (sizeof (wchar_t) == 4) {
+ return (int64_t) wcslen ((const wchar_t *) string);
+ } else {
+ int64_t result = 0;
+ while (* string ++ != U'\0') result ++;
+ return result;
+ }
+}
+static inline void str32cpy (char32_t *target, const char32_t *source) {
+ if (sizeof (wchar_t) == 4) {
+ wcscpy ((wchar_t *) target, (const wchar_t *) source);
+ } else {
+ while (* source != U'\0') * target ++ = * source ++;
+ * target = U'\0';
+ }
+}
+static inline int str32cmp (const char32_t *string1, const char32_t *string2) {
+ if (sizeof (wchar_t) == 4) {
+ return wcscmp ((const wchar_t *) string1, (const wchar_t *) string2);
+ } else {
+ while (*string1 == *string2 ++) {
+ if (*string1 ++ == U'\0') {
+ return 0;
+ }
+ }
+ return (int) (int32_t) (string1 [0] - string2 [-1]); // unsigned subtraction, then sign conversion, then perhaps up conversion
+ }
+}
+
+/*
* Operating system version control.
*/
#define ALLOW_GDK_DRAWING 1
@@ -138,7 +330,7 @@ void Melder_message_init (void); // to be called around program start-up
void * _Melder_malloc (int64_t size);
#define Melder_malloc(type,numberOfElements) (type *) _Melder_malloc ((numberOfElements) * (int64_t) sizeof (type))
void * _Melder_malloc_f (int64_t size);
-#define Melder_malloc_f(type,numberOfElements) (type *) _Melder_malloc_f ((numberOfElements) * sizeof (type))
+#define Melder_malloc_f(type,numberOfElements) (type *) _Melder_malloc_f ((numberOfElements) * (int64_t) sizeof (type))
void * Melder_realloc (void *pointer, int64_t size);
void * Melder_realloc_f (void *pointer, int64_t size);
void * _Melder_calloc (int64_t numberOfElements, int64_t elementSize);
@@ -182,22 +374,29 @@ const uint32_t kMelder_textOutputEncoding_FLAC = 0x464C4143;
bool Melder_isValidAscii (const wchar_t *string);
bool Melder_strIsValidUtf8 (const char *string);
bool Melder_isEncodable (const wchar_t *string, int outputEncoding);
-extern wchar_t Melder_decodeMacRoman [256];
-extern wchar_t Melder_decodeWindowsLatin1 [256];
+extern char32_t Melder_decodeMacRoman [256];
+extern char32_t Melder_decodeWindowsLatin1 [256];
-long Melder_killReturns_inlineW (wchar_t *text);
+long Melder_killReturns_inlineW (wchar_t *text);
+long Melder_killReturns_inline32 (char32_t *text);
-unsigned long wcslen_utf8 (const wchar_t *wcs, bool expandNewlines);
-unsigned long wcslen_utf16 (const wchar_t *wcs, bool expandNewlines);
-unsigned long wcslen_utf32 (const wchar_t *wcs, bool expandNewlines);
+size_t wcslen_utf8 (const wchar_t *wcs, bool expandNewlines);
+size_t wcslen_utf16 (const wchar_t *wcs, bool expandNewlines);
+size_t wcslen_char32 (const wchar_t *wcs, bool expandNewlines);
-void Melder_8bitToWcs_inline (const char *string, wchar_t *wcs, int inputEncoding);
+void Melder_8bitToWcs_inline (const char *source, wchar_t *target, int inputEncoding);
+void Melder_8bitToChar32_inline (const char *source, char32_t *target, int inputEncoding);
// errors: Text is not valid UTF-8.
wchar_t * Melder_8bitToWcs (const char *string, int inputEncoding);
+char32 * Melder_8bitToChar32 (const char *string, int inputEncoding);
// errors: Out of memory; Text is not valid UTF-8.
wchar_t * Melder_utf8ToWcs (const char *string);
+char32 * Melder_utf8ToChar32 (const char *string);
// errors: Out of memory; Text is not valid UTF-8.
+char32 * Melder_utf8ToChar32_f (const char *string); // for use in string constants only
+ // crashes: Out of memory; Text is not valid UTF-8.
+
void Melder_wcsToUtf8_inline (const wchar_t *wcs, char *utf8);
char * Melder_wcsToUtf8 (const wchar_t *string);
// errors: Out of memory.
@@ -205,7 +404,7 @@ void Melder_wcsTo8bitFileRepresentation_inline (const wchar_t *wcs, char *utf8);
void Melder_8bitFileRepresentationToWcs_inline (const char *utf8, wchar_t *wcs);
extern "C" wchar_t * Melder_peekUtf8ToWcs (const char *string);
extern "C" char * Melder_peekWcsToUtf8 (const wchar_t *string);
-extern "C" const utf16_t * Melder_peekWcsToUtf16 (const wchar_t *string);
+extern "C" const uint16_t * Melder_peekWcsToUtf16 (const wchar_t *string); // char16_t is C++-only
const void * Melder_peekWcsToCfstring (const wchar_t *string);
void Melder_fwriteWcsAsUtf8 (const wchar_t *ptr, size_t n, FILE *f);
@@ -251,137 +450,34 @@ double Melder_allocationSize (void);
double Melder_reallocationsInSituCount (void);
double Melder_movingReallocationsCount (void);
-/********** FILES **********/
-
-#if defined (_WIN32)
- #define Melder_DIRECTORY_SEPARATOR '\\'
-#else
- #define Melder_DIRECTORY_SEPARATOR '/'
-#endif
-
-struct FLAC__StreamDecoder;
-struct FLAC__StreamEncoder;
-
-#define kMelder_MAXPATH 1023 /* excluding the null byte */
-
-struct structMelderFile {
- FILE *filePointer;
- wchar_t path [kMelder_MAXPATH+1];
- bool openForReading, openForWriting, verbose, requiresCRLF;
- unsigned long outputEncoding;
- int indent;
- struct FLAC__StreamEncoder *flacEncoder;
-};
-typedef struct structMelderFile *MelderFile;
-
-struct structMelderDir {
- wchar_t path [kMelder_MAXPATH+1];
-};
-typedef struct structMelderDir *MelderDir;
-
-#if defined (macintosh) && useCarbon
- void Melder_machToFile (void *void_fsref, MelderFile file);
-#endif
-
-const wchar_t * MelderFile_name (MelderFile file);
-wchar_t * MelderDir_name (MelderDir dir);
-void Melder_pathToDir (const wchar_t *path, MelderDir dir);
-void Melder_pathToFile (const wchar_t *path, MelderFile file);
-void Melder_relativePathToFile (const wchar_t *path, MelderFile file);
-wchar_t * Melder_dirToPath (MelderDir dir);
- /* Returns a pointer internal to 'dir', like "/u/paul/praats" or "D:\Paul\Praats" */
-wchar_t * Melder_fileToPath (MelderFile file);
-void MelderFile_copy (MelderFile file, MelderFile copy);
-void MelderDir_copy (MelderDir dir, MelderDir copy);
-bool MelderFile_equal (MelderFile file1, MelderFile file2);
-bool MelderDir_equal (MelderDir dir1, MelderDir dir2);
-void MelderFile_setToNull (MelderFile file);
-bool MelderFile_isNull (MelderFile file);
-void MelderDir_setToNull (MelderDir dir);
-bool MelderDir_isNull (MelderDir dir);
-void MelderDir_getFile (MelderDir parent, const wchar_t *fileName, MelderFile file);
-void MelderDir_relativePathToFile (MelderDir dir, const wchar_t *path, MelderFile file);
-void MelderFile_getParentDir (MelderFile file, MelderDir parent);
-void MelderDir_getParentDir (MelderDir file, MelderDir parent);
-bool MelderDir_isDesktop (MelderDir dir);
-void MelderDir_getSubdir (MelderDir parent, const wchar_t *subdirName, MelderDir subdir);
-void Melder_rememberShellDirectory (void);
-wchar_t * Melder_getShellDirectory (void);
-void Melder_getHomeDir (MelderDir homeDir);
-void Melder_getPrefDir (MelderDir prefDir);
-void Melder_getTempDir (MelderDir tempDir);
-
-bool MelderFile_exists (MelderFile file);
-bool MelderFile_readable (MelderFile file);
-long MelderFile_length (MelderFile file);
-void MelderFile_delete (MelderFile file);
-
-/* The following two should be combined with each other and with Windows extension setting: */
-FILE * Melder_fopen (MelderFile file, const char *type);
-void Melder_fclose (MelderFile file, FILE *stream);
-void Melder_files_cleanUp (void);
-
-/* So these will be the future replacements for the above, as soon as we rid of text files: */
-MelderFile MelderFile_open (MelderFile file);
-MelderFile MelderFile_append (MelderFile file);
-MelderFile MelderFile_create (MelderFile file);
-void * MelderFile_read (MelderFile file, long nbytes);
-char * MelderFile_readLine (MelderFile file);
-void MelderFile_writeCharacter (MelderFile file, wchar_t kar);
-void MelderFile_write (MelderFile file, const wchar_t *s1);
-void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2);
-void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3);
-void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4);
-void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5);
-void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6);
-void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6, const wchar_t *s7);
-void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6, const wchar_t *s7, const wchar_t *s8);
-void MelderFile_write (MelderFile file, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3, const wchar_t *s4, const wchar_t *s5, const wchar_t *s6, const wchar_t *s7, const wchar_t *s8, const wchar_t *s9);
-void MelderFile_rewind (MelderFile file);
-void MelderFile_seek (MelderFile file, long position, int direction);
-long MelderFile_tell (MelderFile file);
-void MelderFile_close (MelderFile file);
-void MelderFile_close_nothrow (MelderFile file);
-
-/* Read and write whole text files. */
-wchar_t * MelderFile_readText (MelderFile file);
-void MelderFile_writeText (MelderFile file, const wchar_t *text, enum kMelder_textOutputEncoding outputEncoding);
-void MelderFile_appendText (MelderFile file, const wchar_t *text);
-
-void Melder_createDirectory (MelderDir parent, const wchar_t *subdirName, int mode);
-
-void Melder_getDefaultDir (MelderDir dir);
-void Melder_setDefaultDir (MelderDir dir);
-void MelderFile_setDefaultDir (MelderFile file);
-
-/* Use the following functions to pass unchanged text or file names to Melder_* functions. */
-/* Backslashes are replaced by "\bs". */
-/* The trick is that they return one of 11 cyclically used static strings, */
-/* so you can use up to 11 strings in a single Melder_* call. */
-wchar_t * Melder_peekExpandBackslashes (const wchar_t *message);
-const wchar_t * MelderFile_messageName (MelderFile file); // Calls Melder_peekExpandBackslashes ().
-
/********** STRINGS **********/
/* These are routines for never having to check string boundaries again. */
typedef struct {
- unsigned long length;
- unsigned long bufferSize;
- wchar_t *string; // a growing buffer, never shrunk (can only be freed by MelderString_free)
+ int64 length;
+ int64 bufferSize;
+ wchar *string; // a growing buffer, never shrunk (can only be freed by MelderString_free)
} MelderString;
typedef struct {
- unsigned long length;
- unsigned long bufferSize;
- utf16_t *string; // a growing buffer, never shrunk (can only be freed by MelderString16_free)
+ int64 length;
+ int64 bufferSize;
+ char16 *string; // a growing buffer, never shrunk (can only be freed by MelderString16_free)
} MelderString16;
+typedef struct {
+ int64 length;
+ int64 bufferSize;
+ char32 *string; // a growing buffer, never shrunk (can only be freed by MelderString32_free)
+} MelderString32;
void MelderString_free (MelderString *me); // frees the "string" attribute only (and sets other attributes to zero)
void MelderString16_free (MelderString16 *me); // frees the "string" attribute only (and sets other attributes to zero)
+void MelderString32_free (MelderString32 *me); // frees the "string" attribute only (and sets other attributes to zero)
void MelderString_empty (MelderString *me); // sets to empty string (buffer not freed)
void MelderString16_empty (MelderString16 *me); // sets to empty string (buffer not freed)
+void MelderString32_empty (MelderString32 *me); // sets to empty string (buffer not freed)
void MelderString_copy (MelderString *me, const wchar_t *source);
-void MelderString_ncopy (MelderString *me, const wchar_t *source, unsigned long n);
+void MelderString_ncopy (MelderString *me, const wchar_t *source, int64 n);
void MelderString_append (MelderString *me, const wchar_t *s1);
void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2);
void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2, const wchar_t *s3);
@@ -398,6 +494,7 @@ void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2
const wchar_t *s5, const wchar_t *s6, const wchar_t *s7, const wchar_t *s8, const wchar_t *s9);
void MelderString_appendCharacter (MelderString *me, wchar_t character);
void MelderString16_appendCharacter (MelderString16 *me, wchar_t character);
+void MelderString32_appendCharacter (MelderString32 *me, char32_t character);
void MelderString_get (MelderString *me, wchar_t *destination); // performs no boundary checking
double MelderString_allocationCount (void);
double MelderString_deallocationCount (void);
@@ -552,9 +649,10 @@ struct MelderArg {
MelderArg (const wchar_t * arg) : type (1), argW (arg) { }
MelderArg (const char * arg) : type (2), arg8 (arg) { }
MelderArg (const double arg) : type (1), argW (Melder_double (arg)) { }
- MelderArg (const long long arg) : type (1), argW (Melder_integer (arg)) { }
+ MelderArg (const long long arg) : type (1), argW (Melder_integer (arg)) { }
+ MelderArg (const unsigned long long arg) : type (1), argW (Melder_integer ((int64_t) arg)) { }
MelderArg (const long arg) : type (1), argW (Melder_integer (arg)) { }
- MelderArg (const unsigned long arg) : type (1), argW (Melder_integer (arg)) { }
+ MelderArg (const unsigned long arg) : type (1), argW (Melder_integer ((int64_t) arg)) { } // ignore ULL above 2^63
MelderArg (const int arg) : type (1), argW (Melder_integer (arg)) { }
MelderArg (const unsigned int arg) : type (1), argW (Melder_integer (arg)) { }
MelderArg (const short arg) : type (1), argW (Melder_integer (arg)) { }
@@ -639,25 +737,6 @@ void Melder_clearError (void);
wchar_t * Melder_getError (void);
/* Returns the error string. Mainly used with wcsstr. */
-int Melder_fatal (const char *format, ...);
- /* Give error message, abort program. */
- /* Should only be caused by programming errors. */
-
-#ifdef NDEBUG
- #define Melder_assert(x) ((void) 0)
- #define trace(x) ((void) 0)
-#else
- #define Melder_assert(x) ((x) ? (void) (0) : (void) Melder_assert_ (#x, __FILE__, __LINE__))
- #define trace(...) Melder_trace_ (__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
-#endif
-int Melder_assert_ (const char *condition, const char *fileName, int lineNumber);
- /* Call Melder_fatal with a message based on the following template: */
- /* "Assertion failed in file <fileName> on line <lineNumber>: <condition>" */
-void Melder_setTracing (bool tracing);
-bool Melder_getTracing ();
-void Melder_tracingToFile (MelderFile file);
-void Melder_trace_ (const char *fileName, int lineNumber, const char *functionName, const char *format, ...);
-
/********** WARNING: ive warning to stderr (batch) or to a "Warning" dialog **********/
void Melder_warning (const MelderArg& arg1);
@@ -995,7 +1074,7 @@ void MelderFile_writeAudioFileTrailer (MelderFile file, int audioFileType, long
void MelderFile_writeAudioFile (MelderFile file, int audioFileType, const short *buffer, long sampleRate, long numberOfSamples, int numberOfChannels, int numberOfBitsPerSamplePoint);
int MelderFile_checkSoundFile (MelderFile file, int *numberOfChannels, int *encoding,
- double *sampleRate, long *startOfData, long *numberOfSamples);
+ double *sampleRate, long *startOfData, int32 *numberOfSamples);
/* Returns information about a just opened audio file.
* The return value is the audio file type, or 0 if it is not a sound file or in case of error.
* The data start at 'startOfData' bytes from the start of the file.
@@ -1221,12 +1300,14 @@ public:
}
private:
_autostring& operator= (const _autostring&); // disable copy assignment
- //autostring (autostring &); // disable copy constructor (trying it this way also disables good things like autostring s1 = wcsdup("hello");)
+ //_autostring (_autostring &); // disable copy constructor (trying it this way also disables good things like autostring s1 = wcsdup("hello");)
template <class Y> _autostring (_autostring<Y> &); // disable copy constructor
};
typedef _autostring <wchar_t> autostring;
typedef _autostring <char> autostring8;
+typedef _autostring <char16_t> autostring16;
+typedef _autostring <char32_t> autostring32;
class autoMelderAudioSaveMaximumAsynchronicity {
enum kMelder_asynchronicityLevel d_saveAsynchronicity;
diff --git a/sys/melder_alloc.cpp b/sys/melder_alloc.cpp
index 76b9599..9954943 100644
--- a/sys/melder_alloc.cpp
+++ b/sys/melder_alloc.cpp
@@ -65,9 +65,9 @@ void Melder_alloc_init (void) {
void * _Melder_malloc (int64_t size) {
if (size <= 0)
Melder_throw ("Can never allocate ", Melder_bigInteger (size), " bytes.");
- if (sizeof (size_t) < 8 && size > /*2147483647*/ INT32_MAX)
+ if (sizeof (size_t) < 8 && (double) size > SIZE_MAX)
Melder_throw ("Can never allocate ", Melder_bigInteger (size), " bytes. Use a 64-bit edition of Praat instead?");
- void *result = malloc (size);
+ void *result = malloc ((size_t) size);
if (result == NULL)
Melder_throw ("Out of memory: there is not enough room for another ", Melder_bigInteger (size), " bytes.");
if (Melder_debug == 34) { Melder_casual ("Melder_malloc\t%p\t%ls\t1", result, Melder_bigInteger (size)); }
@@ -79,10 +79,12 @@ void * _Melder_malloc (int64_t size) {
void * _Melder_malloc_f (int64_t size) {
if (size <= 0)
Melder_fatal ("(Melder_malloc_f:) Can never allocate %ls bytes.", Melder_bigInteger (size));
- void *result = malloc (size);
+ if (sizeof (size_t) < 8 && (double) size > SIZE_MAX)
+ Melder_fatal ("(Melder_malloc_f:) Can never allocate %ls bytes.", Melder_bigInteger (size));
+ void *result = malloc ((size_t) size);
if (result == NULL) {
if (theRainyDayFund != NULL) { free (theRainyDayFund); theRainyDayFund = NULL; }
- result = malloc (size);
+ result = malloc ((size_t) size);
if (result != NULL) {
Melder_flushError ("Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
} else {
@@ -105,7 +107,9 @@ void _Melder_free (void **ptr) {
void * Melder_realloc (void *ptr, int64_t size) {
if (size <= 0)
Melder_throw ("Can never allocate ", Melder_bigInteger (size), " bytes.");
- void *result = realloc (ptr, size); // will not show in the statistics...
+ if (sizeof (size_t) < 8 && (double) size > SIZE_MAX)
+ Melder_throw ("Can never allocate ", Melder_bigInteger (size), " bytes. Use a 64-bit edition of Praat instead?");
+ void *result = realloc (ptr, (size_t) size); // will not show in the statistics...
if (result == NULL)
Melder_throw ("Out of memory. Could not extend room to ", Melder_bigInteger (size), " bytes.");
if (ptr == NULL) { // is it like malloc?
@@ -127,10 +131,12 @@ void * Melder_realloc_f (void *ptr, int64_t size) {
void *result;
if (size <= 0)
Melder_fatal ("(Melder_realloc_f:) Can never allocate %ls bytes.", Melder_bigInteger (size));
- result = realloc (ptr, size); /* Will not show in the statistics... */
+ if (sizeof (size_t) < 8 && (double) size > SIZE_MAX)
+ Melder_fatal ("(Melder_realloc_f:) Can never allocate %ls bytes.", Melder_bigInteger (size));
+ result = realloc (ptr, (size_t) size); // will not show in the statistics...
if (result == NULL) {
if (theRainyDayFund != NULL) { free (theRainyDayFund); theRainyDayFund = NULL; }
- result = realloc (ptr, size);
+ result = realloc (ptr, (size_t) size);
if (result != NULL) {
Melder_flushError ("Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
} else {
@@ -157,14 +163,14 @@ void * _Melder_calloc (int64_t nelem, int64_t elsize) {
Melder_throw ("Can never allocate ", Melder_bigInteger (nelem), " elements.");
if (elsize <= 0)
Melder_throw ("Can never allocate elements whose size is ", Melder_bigInteger (elsize), " bytes.");
- if (sizeof (size_t) < 8 && nelem * elsize > 2147483647)
+ if (sizeof (size_t) < 8 && (double) nelem * (double) elsize > SIZE_MAX)
Melder_throw ("Can never allocate ", Melder_bigInteger (nelem * elsize), " bytes. Use a 64-bit edition of Praat instead?");
- result = calloc (nelem, elsize);
+ result = calloc ((size_t) nelem, (size_t) elsize);
if (result == NULL)
Melder_throw ("Out of memory: there is not enough room for ", Melder_bigInteger (nelem), " more elements whose sizes are ", elsize, " bytes each.");
if (Melder_debug == 34) { Melder_casual ("Melder_calloc\t%p\t%ls\t%ls", result, Melder_bigInteger (nelem), Melder_bigInteger (elsize)); }
totalNumberOfAllocations += 1;
- totalAllocationSize += nelem * elsize;
+ totalAllocationSize += (double) nelem * (double) elsize;
return result;
}
@@ -174,10 +180,12 @@ void * _Melder_calloc_f (int64_t nelem, int64_t elsize) {
Melder_fatal ("(Melder_calloc_f:) Can never allocate %ls elements.", Melder_bigInteger (nelem));
if (elsize <= 0)
Melder_fatal ("(Melder_calloc_f:) Can never allocate elements whose size is %ls bytes.", Melder_bigInteger (elsize));
- result = calloc (nelem, elsize);
+ if (sizeof (size_t) < 8 && (double) nelem * (double) elsize > SIZE_MAX)
+ Melder_fatal ("(Melder_calloc_f:) Can never allocate %ls bytes.", Melder_double ((double) nelem * (double) elsize));
+ result = calloc ((size_t) nelem, (size_t) elsize);
if (result == NULL) {
if (theRainyDayFund != NULL) { free (theRainyDayFund); theRainyDayFund = NULL; }
- result = calloc (nelem, elsize);
+ result = calloc ((size_t) nelem, (size_t) elsize);
if (result != NULL) {
Melder_flushError ("Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
} else {
@@ -185,30 +193,34 @@ void * _Melder_calloc_f (int64_t nelem, int64_t elsize) {
}
}
totalNumberOfAllocations += 1;
- totalAllocationSize += nelem * elsize;
+ totalAllocationSize += (double) nelem * (double) elsize;
return result;
}
char * Melder_strdup (const char *string) {
if (! string) return NULL;
- int64_t size = strlen (string) + 1;
- char *result = (char *) malloc (size * sizeof (char));
+ int64_t size = (int64_t) strlen (string) + 1;
+ if (sizeof (size_t) < 8 && (double) size > SIZE_MAX)
+ Melder_throw ("Can never allocate ", Melder_bigInteger (size), " bytes. Use a 64-bit edition of Praat instead?");
+ char *result = (char *) malloc ((size_t) size * sizeof (char));
if (result == NULL)
Melder_throw ("Out of memory: there is not enough room to duplicate a text of ", Melder_bigInteger (size - 1), " characters.");
strcpy (result, string);
if (Melder_debug == 34) { Melder_casual ("Melder_strdup\t%p\t%ls\t1", result, Melder_bigInteger (size)); }
totalNumberOfAllocations += 1;
- totalAllocationSize += size;
+ totalAllocationSize += (double) size;
return result;
}
char * Melder_strdup_f (const char *string) {
if (! string) return NULL;
- int64_t size = strlen (string) + 1;
- char *result = (char *) malloc (size * sizeof (char));
+ int64_t size = (int64_t) strlen (string) + 1;
+ if (sizeof (size_t) < 8 && (double) size > SIZE_MAX)
+ Melder_fatal ("(Melder_strdup_f:) Can never allocate %ls bytes.", Melder_bigInteger (size));
+ char *result = (char *) malloc ((size_t) size * sizeof (char));
if (result == NULL) {
if (theRainyDayFund != NULL) { free (theRainyDayFund); theRainyDayFund = NULL; }
- result = (char *) malloc (size * sizeof (char));
+ result = (char *) malloc ((size_t) size * sizeof (char));
if (result != NULL) {
Melder_flushError ("Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
} else {
@@ -217,30 +229,55 @@ char * Melder_strdup_f (const char *string) {
}
strcpy (result, string);
totalNumberOfAllocations += 1;
- totalAllocationSize += size;
+ totalAllocationSize += (double) size;
return result;
}
wchar_t * Melder_wcsdup (const wchar_t *string) {
if (! string) return NULL;
- int64_t size = wcslen (string) + 1;
- wchar_t *result = (wchar_t *) malloc (size * sizeof (wchar_t));
+ int64_t size = (int64_t) wcslen (string) + 1;
+ double allocationSize = (double) size * (double) sizeof (wchar_t);
+ if (allocationSize > INT54_MAX)
+ Melder_throw ("Can never allocate ", Melder_bigInteger (size), " bytes. It is above the 9-petabyte limit.");
+ if (sizeof (size_t) < 8 && allocationSize > SIZE_MAX)
+ Melder_throw ("Can never allocate ", Melder_bigInteger (size), " bytes. Use a 64-bit edition of Praat instead?");
+ wchar_t *result = (wchar_t *) malloc ((size_t) allocationSize); // guarded conversion
if (result == NULL)
Melder_throw ("Out of memory: there is not enough room to duplicate a text of ", Melder_bigInteger (size - 1), " characters.");
wcscpy (result, string);
if (Melder_debug == 34) { Melder_casual ("Melder_wcsdup\t%p\t%ls\t4", result, Melder_bigInteger (size)); }
totalNumberOfAllocations += 1;
- totalAllocationSize += size * sizeof (wchar_t);
+ totalAllocationSize += allocationSize;
+ return result;
+}
+
+char32_t * Melder_str32dup (const char32_t *string) {
+ if (! string) return NULL;
+ int64_t size = (int64_t) str32len (string) + 1;
+ double allocationSize = (double) size * (double) sizeof (char32_t);
+ if (allocationSize > INT54_MAX)
+ Melder_throw ("Can never allocate ", Melder_bigInteger (size), " bytes. It is above the 9-petabyte limit.");
+ if (sizeof (size_t) < 8 && allocationSize > SIZE_MAX)
+ Melder_throw ("Can never allocate ", Melder_bigInteger (size), " bytes. Use a 64-bit edition of Praat instead?");
+ char32_t *result = (char32_t *) malloc ((size_t) allocationSize); // guarded conversion
+ if (result == NULL)
+ Melder_throw ("Out of memory: there is not enough room to duplicate a text of ", Melder_bigInteger (size - 1), " characters.");
+ str32cpy (result, string);
+ if (Melder_debug == 34) { Melder_casual ("Melder_str32dup\t%p\t%ls\t4", result, Melder_bigInteger (size)); }
+ totalNumberOfAllocations += 1;
+ totalAllocationSize += allocationSize;
return result;
}
wchar_t * Melder_wcsdup_f (const wchar_t *string) {
if (! string) return NULL;
- int64_t size = wcslen (string) + 1;
- wchar_t *result = (wchar_t *) malloc (size * sizeof (wchar_t));
+ int64_t size = (int64_t) wcslen (string) + 1;
+ if (sizeof (size_t) < 8 && (double) size * (double) sizeof (wchar_t) > SIZE_MAX)
+ Melder_fatal ("(Melder_wcsdup_f:) Can never allocate %ls characters.", Melder_bigInteger (size));
+ wchar_t *result = (wchar_t *) malloc ((size_t) size * sizeof (wchar_t));
if (result == NULL) {
if (theRainyDayFund != NULL) { free (theRainyDayFund); theRainyDayFund = NULL; }
- result = (wchar_t *) malloc (size * sizeof (wchar_t));
+ result = (wchar_t *) malloc ((size_t) size * sizeof (wchar_t));
if (result != NULL) {
Melder_flushError ("Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
} else {
@@ -249,7 +286,7 @@ wchar_t * Melder_wcsdup_f (const wchar_t *string) {
}
wcscpy (result, string);
totalNumberOfAllocations += 1;
- totalAllocationSize += size * sizeof (wchar_t);
+ totalAllocationSize += (double) size * sizeof (wchar_t);
return result;
}
@@ -279,6 +316,12 @@ int Melder_strcmp (const char *string1, const char *string2) {
return strcmp (string1, string2);
}
+int Melder_str32cmp (const char32 *string1, const char32 *string2) {
+ if (string1 == NULL) string1 = U"";
+ if (string2 == NULL) string2 = U"";
+ return str32cmp (string1, string2);
+}
+
int Melder_strncmp (const char *string1, const char *string2, int64_t n) {
if (string1 == NULL) string1 = "";
if (string2 == NULL) string2 = "";
diff --git a/sys/melder_audiofiles.cpp b/sys/melder_audiofiles.cpp
index 1ed117d..34d49d1 100644
--- a/sys/melder_audiofiles.cpp
+++ b/sys/melder_audiofiles.cpp
@@ -1,6 +1,6 @@
/* melder_audiofiles.cpp
*
- * Copyright (C) 1992-2011,2013 Paul Boersma & David Weenink, 2007 Erez Volk (for FLAC)
+ * Copyright (C) 1992-2011,2013,2015 Paul Boersma & David Weenink, 2007 Erez Volk (for FLAC)
*
* 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
@@ -80,8 +80,8 @@ void MelderFile_writeAudioFileHeader (MelderFile file, int audioFileType, long s
/* Format Version Chunk: 8 + 4 bytes. */
if (fwrite ("FVER", 1, 4, f) != 4) Melder_throw ("Error in file while trying to write the FVER statement.");
- binputi4 (4, f); // the size of what follows
- binputi4 (0xA2805140, f); // time of version
+ binputu4 (4, f); // the size of what follows
+ binputu4 (0xA2805140, f); // time of version
/* Common Chunk: 8 + 18 bytes. */
if (fwrite ("COMM", 1, 4, f) != 4) Melder_throw ("Error in file while trying to write the COMM statement.");
@@ -111,8 +111,8 @@ void MelderFile_writeAudioFileHeader (MelderFile file, int audioFileType, long s
/* Format Version Chunk: 8 + 4 bytes. */
if (fwrite ("FVER", 1, 4, f) != 4) Melder_throw ("Error in file while trying to write the FVER statement.");
- binputi4 (4, f); // the size of what follows
- binputi4 (0xA2805140, f); // time of version
+ binputu4 (4, f); // the size of what follows
+ binputu4 (0xA2805140, f); // time of version
/* Common Chunk: 8 + 24 bytes. */
if (fwrite ("COMM", 1, 4, f) != 4) Melder_throw ("Error in file while trying to write the COMM statement.");
@@ -140,11 +140,18 @@ void MelderFile_writeAudioFileHeader (MelderFile file, int audioFileType, long s
numberOfChannels > 2 ||
numberOfBitsPerSamplePoint != numberOfBytesPerSamplePoint * 8;
const int formatSize = needExtensibleFormat ? 40 : 16;
- long dataSize = numberOfSamples * numberOfBytesPerSamplePoint * numberOfChannels;
+ double dataSize_f = (double) numberOfSamples * (double) numberOfBytesPerSamplePoint * (double) numberOfChannels;
+ if (dataSize_f > INT54_MAX)
+ Melder_throw ("Cannot save data over the 9-petabyte limit.");
+ int64_t dataSize = (int64_t) dataSize_f;
/* RIFF Chunk: contains all other chunks. */
if (fwrite ("RIFF", 1, 4, f) != 4) Melder_throw ("Error in file while trying to write the RIFF statement.");
- binputi4LE (4 + (12 + formatSize) + (4 + dataSize), f);
+ int64_t sizeOfRiffChunk_i64 = 4 + (12 + formatSize) + (4 + dataSize);
+ if (sizeOfRiffChunk_i64 > UINT32_MAX)
+ Melder_throw ("Cannot save a WAV file with more than ", UINT32_MAX, " bytes.");
+ uint32_t sizeOfRiffChunk_u32 = (uint32_t) sizeOfRiffChunk_i64;
+ binputu4LE (sizeOfRiffChunk_u32, f);
if (fwrite ("WAVE", 1, 4, f) != 4) Melder_throw ("Error in file while trying to write the WAV file type.");
/* Format Chunk: if 16-bits audio, then 8 + 16 bytes; else 8 + 40 bytes. */
@@ -365,7 +372,7 @@ static short alaw2linear[] =
};
static void Melder_checkAiffFile (FILE *f, int *numberOfChannels, int *encoding,
- double *sampleRate, long *startOfData, long *numberOfSamples)
+ double *sampleRate, long *startOfData, int32 *numberOfSamples)
{
char data [8], chunkID [4];
bool commonChunkPresent = false, dataChunkPresent = false, isAifc = true;
@@ -452,7 +459,7 @@ static void Melder_checkAiffFile (FILE *f, int *numberOfChannels, int *encoding,
}
static void Melder_checkWavFile (FILE *f, int *numberOfChannels, int *encoding,
- double *sampleRate, long *startOfData, long *numberOfSamples)
+ double *sampleRate, long *startOfData, int32 *numberOfSamples)
{
char data [14], chunkID [4];
bool formatChunkPresent = false, dataChunkPresent = false;
@@ -564,7 +571,7 @@ static void Melder_checkWavFile (FILE *f, int *numberOfChannels, int *encoding,
dataChunkSize = chunkSize;
*startOfData = ftell (f);
if (chunkSize & 1) chunkSize ++;
- if (chunkSize < 0) { // incorrect data chunk (sometimes -44); assume that the data run till the end of the file
+ if (chunkSize > UINT32_MAX - 100) { // incorrect data chunk (sometimes -44); assume that the data run till the end of the file
fseeko (f, 0LL, SEEK_END);
off_t endOfData = ftello (f);
dataChunkSize = chunkSize = endOfData - *startOfData;
@@ -586,12 +593,12 @@ static void Melder_checkWavFile (FILE *f, int *numberOfChannels, int *encoding,
if (! formatChunkPresent) Melder_throw (L"Found no Format Chunk.");
if (! dataChunkPresent) Melder_throw (L"Found no Data Chunk.");
- Melder_assert (numberOfBitsPerSamplePoint != -1 && dataChunkSize != -1);
+ Melder_assert (numberOfBitsPerSamplePoint != -1 && dataChunkSize != 0xffffffff);
*numberOfSamples = dataChunkSize / *numberOfChannels / ((numberOfBitsPerSamplePoint + 7) / 8);
}
static void Melder_checkNextSunFile (FILE *f, int *numberOfChannels, int *encoding,
- double *sampleRate, long *startOfData, long *numberOfSamples)
+ double *sampleRate, long *startOfData, int32 *numberOfSamples)
{
char tag [4];
fread (tag, 1, 4, f);
@@ -637,7 +644,7 @@ static int nistGetValue (const char *header, const char *object, double *rval, c
return 1;
}
static void Melder_checkNistFile (FILE *f, int *numberOfChannels, int *encoding,
- double *sampleRate, long *startOfData, long *numberOfSamples)
+ double *sampleRate, long *startOfData, int32 *numberOfSamples)
{
char header [1024], sval [100];
double rval;
@@ -677,7 +684,7 @@ static void Melder_checkNistFile (FILE *f, int *numberOfChannels, int *encoding,
}
static void Melder_checkFlacFile (MelderFile file, int *numberOfChannels, int *encoding,
- double *sampleRate, long *startOfData, long *numberOfSamples)
+ double *sampleRate, long *startOfData, int32 *numberOfSamples)
{
FLAC__StreamMetadata metadata;
FLAC__StreamMetadata_StreamInfo *info;
@@ -688,13 +695,13 @@ static void Melder_checkFlacFile (MelderFile file, int *numberOfChannels, int *e
*encoding = Melder_FLAC_COMPRESSION_16;
*sampleRate = (double) info -> sample_rate;
*startOfData = 0; // meaningless: libFLAC does the I/O
- *numberOfSamples = info -> total_samples; // FIXME: may lose bits above LONG_MAX
+ *numberOfSamples = info -> total_samples; // BUG: loses bits above INT32_MAX
if ((FLAC__uint64) *numberOfSamples != info -> total_samples)
Melder_throw ("FLAC file too long.");
}
static void Melder_checkMp3File (FILE *f, int *numberOfChannels, int *encoding,
- double *sampleRate, long *startOfData, long *numberOfSamples)
+ double *sampleRate, long *startOfData, int32 *numberOfSamples)
{
MP3_FILE mp3f = mp3f_new ();
mp3f_set_file (mp3f, f);
@@ -706,14 +713,14 @@ static void Melder_checkMp3File (FILE *f, int *numberOfChannels, int *encoding,
*numberOfChannels = mp3f_channels (mp3f);
*sampleRate = mp3f_frequency (mp3f);
*numberOfSamples = mp3f_samples (mp3f);
- if ((MP3F_OFFSET)*numberOfSamples != mp3f_samples (mp3f))
+ if ((MP3F_OFFSET)*numberOfSamples != mp3f_samples (mp3f)) // BUG: loses bits above INT32_MAX
Melder_throw ("MP3 file too long.");
*startOfData = 0; // meaningless
mp3f_delete (mp3f);
}
int MelderFile_checkSoundFile (MelderFile file, int *numberOfChannels, int *encoding,
- double *sampleRate, long *startOfData, long *numberOfSamples)
+ double *sampleRate, long *startOfData, int32 *numberOfSamples)
{
char data [16];
FILE *f = file -> filePointer;
@@ -905,179 +912,277 @@ void Melder_readAudioToFloat (FILE *f, int numberOfChannels, int encoding, doubl
Melder_warning ("File too small (", numberOfChannels, "-channel 8-bit).\nMissing samples set to zero.");
}
break;
- case Melder_LINEAR_16_BIG_ENDIAN: {
- try {
- const int numberOfBytesPerSamplePerChannel = 2;
- if (numberOfChannels > (int) sizeof (double) / numberOfBytesPerSamplePerChannel) {
- for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
- for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- buffer [ichan] [isamp] = bingeti2 (f) * (1.0 / 32768);
+ case Melder_LINEAR_16_BIG_ENDIAN:
+ case Melder_LINEAR_16_LITTLE_ENDIAN:
+ case Melder_LINEAR_24_BIG_ENDIAN:
+ case Melder_LINEAR_24_LITTLE_ENDIAN:
+ case Melder_LINEAR_32_BIG_ENDIAN:
+ case Melder_LINEAR_32_LITTLE_ENDIAN:
+ {
+ int numberOfBytesPerSamplePerChannel =
+ encoding == Melder_LINEAR_16_BIG_ENDIAN || encoding == Melder_LINEAR_16_LITTLE_ENDIAN ? 2 :
+ encoding == Melder_LINEAR_24_BIG_ENDIAN || encoding == Melder_LINEAR_24_LITTLE_ENDIAN ? 3 : 4;
+ double numberOfBytes_f = (double) numberOfChannels * (double) numberOfSamples * (double) numberOfBytesPerSamplePerChannel;
+ if (isinf (numberOfBytes_f) || numberOfBytes_f > (double) (1LL << 53)) {
+ Melder_throw ("Cannot read ", numberOfBytes_f, " bytes, "
+ "because that crosses the 9-petabyte limit.");
+ }
+ if (numberOfBytes_f > (double) SIZE_MAX) {
+ Melder_throw ("Cannot read ", numberOfBytes_f, " bytes. "
+ "Perhaps try a 64-bit edition of Praat?");
+ }
+ Melder_assert (numberOfBytes_f >= 0.0);
+ size_t numberOfBytes = (size_t) numberOfBytes_f; // cast is safe because overflow and signedness have been checked
+ uint8_t *bytes = (uint8_t *) & buffer [numberOfChannels] [numberOfSamples] + sizeof (double) - numberOfBytes;
+ /*
+ * Read 16-bit data into the last quarter of the buffer,
+ * or 24-bit data into the last three-eighths of the buffer,
+ * or 32-bit data into the last half of the buffer.
+ */
+ size_t numberOfBytesRead = fread (bytes, 1, numberOfBytes, f);
+ if (numberOfChannels == 1) {
+ switch (encoding) {
+ case Melder_LINEAR_16_BIG_ENDIAN: {
+ for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++;
+ int value = (int) (int16_t) (((uint16_t) byte1 << 8) | (uint16_t) byte2); // extend sign
+ buffer [1] [isamp] = value * (1.0 / 32768);
}
- }
- } else { // optimize
- long numberOfBytes = numberOfChannels * numberOfSamples * numberOfBytesPerSamplePerChannel;
- unsigned char *bytes = (unsigned char *) & buffer [numberOfChannels] [numberOfSamples] + sizeof (double) - numberOfBytes;
- Melder_assert (numberOfBytes > 0);
- if (fread (bytes, 1, numberOfBytes, f) < (size_t) numberOfBytes) throw MelderError (); // read 16-bit data into last quarter of buffer
- if (numberOfChannels == 1) {
+ } break;
+ case Melder_LINEAR_16_LITTLE_ENDIAN: {
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
unsigned char byte1 = * bytes ++, byte2 = * bytes ++;
- long value = (int16_t) (((uint16_t) byte1 << 8) | (uint16_t) byte2);
+ int value = (int) (int16_t) (((uint16_t) byte2 << 8) | (uint16_t) byte1); // extend sign
buffer [1] [isamp] = value * (1.0 / 32768);
}
- } else {
+ } break;
+ case Melder_LINEAR_24_BIG_ENDIAN: {
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
- for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- unsigned char byte1 = * bytes ++, byte2 = * bytes ++;
- long value = (int16_t) (((uint16_t) byte1 << 8) | (uint16_t) byte2);
- buffer [ichan] [isamp] = value * (1.0 / 32768);
- }
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++;
+ int32_t value = (int32_t)
+ ((uint32_t) ((uint32_t) byte1 << 24) |
+ (uint32_t) ((uint32_t) byte2 << 16) |
+ ((uint32_t) byte3 << 8));
+ buffer [1] [isamp] = value * (1.0 / 32768 / 65536);
}
- }
- }
- } catch (MelderError) {
- Melder_clearError ();
- Melder_warning (L"File too small (", numberOfChannels, "-channel 16-bit).\nMissing samples set to zero.");
- }
- } break;
- case Melder_LINEAR_16_LITTLE_ENDIAN: {
- try {
- const int numberOfBytesPerSamplePerChannel = 2;
- if (numberOfChannels > (int) sizeof (double) / numberOfBytesPerSamplePerChannel) {
- for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
- for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- buffer [ichan] [isamp] = bingeti2LE (f) * (1.0 / 32768);
+ } break;
+ case Melder_LINEAR_24_LITTLE_ENDIAN: {
+ for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++;
+ int32_t value = (int32_t)
+ ((uint32_t) ((uint32_t) byte3 << 24) |
+ (uint32_t) ((uint32_t) byte2 << 16) |
+ ((uint32_t) byte1 << 8));
+ buffer [1] [isamp] = value * (1.0 / 32768 / 65536);
}
- }
- } else { // optimize
- double numberOfBytes_f = (double) numberOfChannels * (double) numberOfSamples * (double) numberOfBytesPerSamplePerChannel;
- if (isinf (numberOfBytes_f) || numberOfBytes_f > (double) (1LL << 53)) {
- Melder_throw ("Cannot read ", numberOfBytes_f, " bytes, because that crosses the 9-petabyte limit.");
- }
- if (numberOfBytes_f > (double) SIZE_MAX) {
- Melder_throw ("Cannot read ", numberOfBytes_f, " bytes. Perhaps try a 64-bit edition of Praat?");
- }
- Melder_assert (numberOfBytes_f >= 0.0);
- size_t numberOfBytes = (size_t) numberOfBytes_f; // cast is safe because overflow and signedness have been checked
- unsigned char *bytes = (unsigned char *) & buffer [numberOfChannels] [numberOfSamples] + sizeof (double) - numberOfBytes;
- if (fread (bytes, 1, numberOfBytes, f) < (size_t) numberOfBytes) throw MelderError (); // read 16-bit data into last quarter of buffer
- if (numberOfChannels == 1) {
+ } break;
+ case Melder_LINEAR_32_BIG_ENDIAN: {
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
- unsigned char byte1 = * bytes ++, byte2 = * bytes ++;
- long value = (int16_t) (((uint16_t) byte2 << 8) | (uint16_t) byte1);
- buffer [1] [isamp] = value * (1.0 / 32768);
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++, byte4 = * bytes ++;
+ int32_t value = (int32_t)
+ ((uint32_t) ((uint32_t) byte1 << 24) |
+ (uint32_t) ((uint32_t) byte2 << 16) |
+ (uint32_t) ((uint32_t) byte3 << 8) |
+ (uint32_t) byte4);
+ buffer [1] [isamp] = value * (1.0 / 32768 / 65536);
}
- } else {
+ } break;
+ case Melder_LINEAR_32_LITTLE_ENDIAN: {
+ for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++, byte4 = * bytes ++;
+ int32_t value = (int32_t)
+ ((uint32_t) ((uint32_t) byte4 << 24) |
+ (uint32_t) ((uint32_t) byte3 << 16) |
+ (uint32_t) ((uint32_t) byte2 << 8) |
+ (uint32_t) byte1);
+ buffer [1] [isamp] = value * (1.0 / 32768 / 65536);
+ }
+ } break;
+ }
+ } else if (numberOfChannels <= (int) sizeof (double) / numberOfBytesPerSamplePerChannel) {
+ switch (encoding) {
+ case Melder_LINEAR_16_BIG_ENDIAN: {
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
unsigned char byte1 = * bytes ++, byte2 = * bytes ++;
- long value = (int16_t) (((uint16_t) byte2 << 8) | (uint16_t) byte1);
+ int value = (int) (int16_t) (((uint16_t) byte1 << 8) | (uint16_t) byte2);
buffer [ichan] [isamp] = value * (1.0 / 32768);
}
}
- }
- }
- } catch (MelderError) {
- Melder_clearError ();
- Melder_warning ("File too small (", numberOfChannels, "-channel 16-bit).\nMissing samples set to zero.");
- }
- } break;
- case Melder_LINEAR_24_BIG_ENDIAN: {
- try {
- const int numberOfBytesPerSamplePerChannel = 3;
- if (numberOfChannels > (int) sizeof (double) / numberOfBytesPerSamplePerChannel) {
- for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
- for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- buffer [ichan] [isamp] = bingeti3 (f) * (1.0 / 8388608);
+ } break;
+ case Melder_LINEAR_16_LITTLE_ENDIAN: {
+ for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
+ for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
+ uint8_t byte1 = * bytes ++, byte2 = * bytes ++;
+ int value = (int) (int16_t) (((uint16_t) byte2 << 8) | (uint16_t) byte1);
+ buffer [ichan] [isamp] = value * (1.0 / 32768);
+ }
}
- }
- } else { // optimize
- long numberOfBytes = numberOfChannels * numberOfSamples * numberOfBytesPerSamplePerChannel;
- unsigned char *bytes = (unsigned char *) & buffer [numberOfChannels] [numberOfSamples] + sizeof (double) - numberOfBytes;
- if (fread (bytes, 1, numberOfBytes, f) < numberOfBytes) throw MelderError (); // read 24-bit data into last three-eighths of buffer
- if (numberOfChannels == 1) {
+ } break;
+ case Melder_LINEAR_24_BIG_ENDIAN: {
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
- unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++;
- uint32_t unsignedValue = ((uint32_t) byte1 << 16) | ((uint32_t) byte2 << 8) | (uint32_t) byte3;
- if ((byte1 & 128) != 0) unsignedValue |= 0xFF000000;
- buffer [1] [isamp] = (int32_t) unsignedValue * (1.0 / 8388608);
+ for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++;
+ uint32_t unsignedValue =
+ (uint32_t) ((uint32_t) byte1 << 16) |
+ (uint32_t) ((uint32_t) byte2 << 8) |
+ (uint32_t) byte3;
+ if ((byte1 & 128) != 0) unsignedValue |= 0xFF000000; // extend sign
+ buffer [ichan] [isamp] = (int32_t) unsignedValue * (1.0 / 8388608);
+ }
}
- } else {
+ } break;
+ case Melder_LINEAR_24_LITTLE_ENDIAN: {
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++;
- uint32_t unsignedValue = ((uint32_t) byte1 << 16) | ((uint32_t) byte2 << 8) | (uint32_t) byte3;
- if ((byte1 & 128) != 0) unsignedValue |= 0xFF000000;
+ uint32_t unsignedValue = ((uint32_t) byte3 << 16) | ((uint32_t) byte2 << 8) | (uint32_t) byte1;
+ if ((byte3 & 128) != 0) unsignedValue |= 0xFF000000;
buffer [ichan] [isamp] = (int32_t) unsignedValue * (1.0 / 8388608);
}
}
- }
+ } break;
+ case Melder_LINEAR_32_BIG_ENDIAN: {
+ for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
+ for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++, byte4 = * bytes ++;
+ int32_t value = (int32_t)
+ ((uint32_t) ((uint32_t) byte1 << 24) |
+ (uint32_t) ((uint32_t) byte2 << 16) |
+ (uint32_t) ((uint32_t) byte3 << 8) |
+ (uint32_t) byte4);
+ buffer [ichan] [isamp] = value * (1.0 / 32768 / 65536);
+ }
+ }
+ } break;
+ case Melder_LINEAR_32_LITTLE_ENDIAN: {
+ for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
+ for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++, byte4 = * bytes ++;
+ int32_t value = (int32_t)
+ ((uint32_t) ((uint32_t) byte4 << 24) |
+ (uint32_t) ((uint32_t) byte3 << 16) |
+ (uint32_t) ((uint32_t) byte2 << 8) |
+ (uint32_t) byte1);
+ buffer [ichan] [isamp] = value * (1.0 / 32768 / 65536);
+ }
+ }
+ } break;
}
- } catch (MelderError) {
- Melder_clearError ();
- Melder_warning ("File too small (", numberOfChannels, "-channel 24-bit).\nMissing samples set to zero.");
- }
- } break;
- case Melder_LINEAR_24_LITTLE_ENDIAN: {
- try {
- const int numberOfBytesPerSamplePerChannel = 3;
- if (numberOfChannels > (int) sizeof (double) / numberOfBytesPerSamplePerChannel) {
- for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
- for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- buffer [ichan] [isamp] = bingeti3LE (f) * (1.0 / 8388608);
+ } else {
+ Melder_assert (sizeof (double) == 8);
+ int32_t *ints = (int32_t *) & buffer [1] [1];
+ switch (encoding) {
+ case Melder_LINEAR_16_BIG_ENDIAN: {
+ for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
+ for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++;
+ int32_t value = (int32_t)
+ (((uint32_t) byte1 << 24) |
+ ((uint32_t) byte2 << 16));
+ * ints ++ = value;
+ * ints ++ = 0; // the marker
+ }
}
- }
- } else { // optimize
- long numberOfBytes = numberOfChannels * numberOfSamples * numberOfBytesPerSamplePerChannel;
- unsigned char *bytes = (unsigned char *) & buffer [numberOfChannels] [numberOfSamples] + sizeof (double) - numberOfBytes;
- if (fread (bytes, 1, numberOfBytes, f) < numberOfBytes) throw MelderError (); // read 24-bit data into last three-eighths of buffer
- if (numberOfChannels == 1) {
+ } break;
+ case Melder_LINEAR_16_LITTLE_ENDIAN: {
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
- unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++;
- uint32_t unsignedValue = ((uint32_t) byte3 << 16) | ((uint32_t) byte2 << 8) | (uint32_t) byte1;
- if ((byte3 & 128) != 0) unsignedValue |= 0xFF000000;
- buffer [1] [isamp] = (int32_t) unsignedValue * (1.0 / 8388608);
+ for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++;
+ int32_t value = (int32_t)
+ (((uint32_t) byte2 << 24) |
+ ((uint32_t) byte1 << 16));
+ * ints ++ = value;
+ * ints ++ = 0; // the marker
+ }
}
- } else {
+ } break;
+ case Melder_LINEAR_24_BIG_ENDIAN: {
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++;
- uint32_t unsignedValue = ((uint32_t) byte3 << 16) | ((uint32_t) byte2 << 8) | (uint32_t) byte1;
- if ((byte3 & 128) != 0) unsignedValue |= 0xFF000000;
- buffer [ichan] [isamp] = (int32_t) unsignedValue * (1.0 / 8388608);
+ int32_t value = (int32_t)
+ (((uint32_t) byte1 << 24) |
+ ((uint32_t) byte2 << 16) |
+ ((uint32_t) byte3 << 8));
+ * ints ++ = value;
+ * ints ++ = 0; // the marker
+ }
+ }
+ } break;
+ case Melder_LINEAR_24_LITTLE_ENDIAN: {
+ for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
+ for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++;
+ int32_t value = (int32_t)
+ (((uint32_t) byte3 << 24) |
+ ((uint32_t) byte2 << 16) |
+ ((uint32_t) byte1 << 8));
+ * ints ++ = value;
+ * ints ++ = 0; // the marker
+ }
+ }
+ } break;
+ case Melder_LINEAR_32_BIG_ENDIAN: {
+ for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
+ for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++, byte4 = * bytes ++;
+ int32_t value = (int32_t)
+ (((uint32_t) byte1 << 24) |
+ ((uint32_t) byte2 << 16) |
+ ((uint32_t) byte3 << 8) |
+ (uint32_t) byte4);
+ * ints ++ = value;
+ * ints ++ = 0; // the marker
+ }
+ }
+ } break;
+ case Melder_LINEAR_32_LITTLE_ENDIAN: {
+ for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
+ for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
+ unsigned char byte1 = * bytes ++, byte2 = * bytes ++, byte3 = * bytes ++, byte4 = * bytes ++;
+ int32_t value = (int32_t)
+ (((uint32_t) byte4 << 24) |
+ ((uint32_t) byte3 << 16) |
+ ((uint32_t) byte2 << 8) |
+ (uint32_t) byte1);
+ * ints ++ = value;
+ * ints ++ = 0; // the marker
}
}
}
}
- } catch (MelderError) {
- Melder_clearError ();
- Melder_warning ("File too small (", numberOfChannels, "-channel 24-bit).\nMissing samples set to zero.");
- }
- } break;
- case Melder_LINEAR_32_BIG_ENDIAN:
- try {
- for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
- for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- buffer [ichan] [isamp] = bingeti4 (f) * (1.0 / 32768 / 65536);
+ double *doubles = & buffer [1] [1];
+ long n = numberOfSamples * numberOfChannels;
+ for (long i = 0; i < n; i ++) {
+ int32_t *valuePosition = (int32_t *) & doubles [i];
+ int32_t *markerPosition = valuePosition + 1;
+ if (! *markerPosition) {
+ int32_t value = *valuePosition;
+ long ichan = i / numberOfSamples, isamp = i % numberOfSamples;
+ for (long other = isamp * numberOfChannels + ichan; other != i; ) {
+ int32_t *otherValuePosition = (int32_t *) & doubles [other];
+ *valuePosition = *otherValuePosition;
+ *markerPosition = 1;
+ valuePosition = otherValuePosition;
+ markerPosition = valuePosition + 1;
+ ichan = other / numberOfSamples, isamp = other % numberOfSamples;
+ other = isamp * numberOfChannels + ichan;
+ }
+ *valuePosition = value;
+ *markerPosition = 1;
}
}
- } catch (MelderError) {
- Melder_clearError ();
- Melder_warning ("File too small (", numberOfChannels, "-channel 32-bit).\nMissing samples set to zero.");
- }
- break;
- case Melder_LINEAR_32_LITTLE_ENDIAN:
- try {
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- buffer [ichan] [isamp] = bingeti4LE (f) * (1.0 / 32768 / 65536);
+ buffer [ichan] [isamp] = * (int32_t *) & buffer [ichan] [isamp] * (1.0 / 32768 / 65536);
}
}
- } catch (MelderError) {
- Melder_clearError ();
- Melder_warning ("File too small (", numberOfChannels, "-channel 32-bit).\nMissing samples set to zero.");
}
- break;
+ if (numberOfBytesRead < numberOfBytes)
+ Melder_warning ("File too small (", numberOfChannels, "-channel ", numberOfBytesPerSamplePerChannel * 8, "-bit).\n"
+ "Missing samples were set to zero.");
+ } break;
case Melder_IEEE_FLOAT_32_BIG_ENDIAN:
try {
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
@@ -1302,60 +1407,60 @@ void MelderFile_writeFloatToAudio (MelderFile file, int numberOfChannels, int en
case Melder_LINEAR_8_SIGNED:
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- long value = round (buffer [ichan] [isamp] * 128);
- if (value < -128) { value = -128; nclipped ++; }
- if (value > 127) { value = 127; nclipped ++; }
- binputi1 (value, f);
+ double value = round (buffer [ichan] [isamp] * 128.0);
+ if (value < -128.0) { value = -128.0; nclipped ++; }
+ if (value > 127.0) { value = 127.0; nclipped ++; }
+ binputi1 ((int) value, f);
}
}
break;
case Melder_LINEAR_8_UNSIGNED:
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- long value = floor ((buffer [ichan] [isamp] + 1.0) * 128);
- if (value < 0) { value = 0; nclipped ++; }
- if (value > 255) { value = 255; nclipped ++; }
- binputu1 (value, f);
+ double value = floor ((buffer [ichan] [isamp] + 1.0) * 128.0);
+ if (value < 0.0) { value = 0.0; nclipped ++; }
+ if (value > 255.0) { value = 255.0; nclipped ++; }
+ binputu1 ((int) value, f);
}
}
break;
case Melder_LINEAR_16_BIG_ENDIAN:
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- long value = round (buffer [ichan] [isamp] * 32768);
- if (value < -32768) { value = -32768; nclipped ++; }
- if (value > 32767) { value = 32767; nclipped ++; }
- binputi2 (value, f);
+ double value = round (buffer [ichan] [isamp] * 32768.0);
+ if (value < -32768.0) { value = -32768.0; nclipped ++; }
+ if (value > 32767.0) { value = 32767.0; nclipped ++; }
+ binputi2 ((int16) value, f);
}
}
break;
case Melder_LINEAR_16_LITTLE_ENDIAN:
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- long value = round (buffer [ichan] [isamp] * 32768);
- if (value < -32768) { value = -32768; nclipped ++; }
- if (value > 32767) { value = 32767; nclipped ++; }
- binputi2LE (value, f);
+ double value = round (buffer [ichan] [isamp] * 32768.0);
+ if (value < -32768.0) { value = -32768.0; nclipped ++; }
+ if (value > 32767.0) { value = 32767.0; nclipped ++; }
+ binputi2LE ((int16) value, f);
}
}
break;
case Melder_LINEAR_24_BIG_ENDIAN:
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- long value = round (buffer [ichan] [isamp] * 8388608);
- if (value < -8388608) { value = -8388608; nclipped ++; }
- if (value > 8388607) { value = 8388607; nclipped ++; }
- binputi3 (value, f);
+ double value = round (buffer [ichan] [isamp] * 8388608.0);
+ if (value < -8388608.0) { value = -8388608.0; nclipped ++; }
+ if (value > 8388607.0) { value = 8388607.0; nclipped ++; }
+ binputi3 ((int32) value, f);
}
}
break;
case Melder_LINEAR_24_LITTLE_ENDIAN:
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- long value = round (buffer [ichan] [isamp] * 8388608);
- if (value < -8388608) { value = -8388608; nclipped ++; }
- if (value > 8388607) { value = 8388607; nclipped ++; }
- binputi3LE (value, f);
+ double value = round (buffer [ichan] [isamp] * 8388608.0);
+ if (value < -8388608.0) { value = -8388608.0; nclipped ++; }
+ if (value > 8388607.0) { value = 8388607.0; nclipped ++; }
+ binputi3LE ((int32) value, f);
}
}
break;
@@ -1365,7 +1470,7 @@ void MelderFile_writeFloatToAudio (MelderFile file, int numberOfChannels, int en
double value = round (buffer [ichan] [isamp] * 2147483648.0);
if (value < -2147483648.0) { value = -2147483648.0; nclipped ++; }
if (value > 2147483647.0) { value = 2147483647.0; nclipped ++; }
- binputi4 (value, f);
+ binputi4 ((int32) value, f); // safe cast: rounding and range already handled
}
}
break;
@@ -1375,7 +1480,7 @@ void MelderFile_writeFloatToAudio (MelderFile file, int numberOfChannels, int en
double value = round (buffer [ichan] [isamp] * 2147483648.0);
if (value < -2147483648.0) { value = -2147483648.0; nclipped ++; }
if (value > 2147483647.0) { value = 2147483647.0; nclipped ++; }
- binputi4LE (value, f);
+ binputi4LE ((int32) value, f);
}
}
break;
@@ -1403,9 +1508,9 @@ void MelderFile_writeFloatToAudio (MelderFile file, int numberOfChannels, int en
for (long isamp = 1; isamp <= numberOfSamples; isamp ++) {
FLAC__int32 samples [FLAC__MAX_CHANNELS];
for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
- long value = round (buffer [ichan] [isamp] * 32768);
- if (value < -32768) { value = -32768; nclipped ++; }
- if (value > 32767) { value = 32767; nclipped ++; }
+ double value = round (buffer [ichan] [isamp] * 32768.0);
+ if (value < -32768.0) { value = -32768.0; nclipped ++; }
+ if (value > 32767.0) { value = 32767.0; nclipped ++; }
samples [ichan - 1] = (FLAC__int32) value;
}
if (! FLAC__stream_encoder_process_interleaved (file -> flacEncoder, samples, 1))
diff --git a/sys/melder_debug.cpp b/sys/melder_debug.cpp
index ac78833..42bd9ea 100644
--- a/sys/melder_debug.cpp
+++ b/sys/melder_debug.cpp
@@ -1,6 +1,6 @@
/* melder_debug.cpp
*
- * Copyright (C) 2000-2012,2014 Paul Boersma
+ * Copyright (C) 2000-2012,2014,2015 Paul Boersma
*
* 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
@@ -81,18 +81,18 @@ the behaviour of that program changes in the following way:
*/
-static bool theTracing = false;
+bool Melder_isTracing = false;
static structMelderFile theTracingFile = { 0 };
#ifdef linux
static void theGtkLogHandler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data) {
- Melder_trace_ (NULL, 0, "GTK", "%s", message);
+ Melder_trace_FMT (NULL, 0, "GTK", "%s", message);
}
static void theGlibLogHandler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data) {
- Melder_trace_ (NULL, 0, "GLib", "%s", message);
+ Melder_trace_FMT (NULL, 0, "GLib", "%s", message);
}
static void theGlibGobjectLogHandler (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer unused_data) {
- Melder_trace_ (NULL, 0, "GLib-GObject", "%s", message);
+ Melder_trace_FMT (NULL, 0, "GLib-GObject", "%s", message);
}
#endif
@@ -102,7 +102,7 @@ void Melder_setTracing (bool tracing) {
#define str(s) #s
if (! tracing)
trace ("switch tracing off in Praat version %s at %s", xstr (PRAAT_VERSION_STR), ctime (& today));
- theTracing = tracing;
+ Melder_isTracing = tracing;
#ifdef linux
static guint handler_id1, handler_id2, handler_id3;
if (tracing) {
@@ -120,17 +120,13 @@ void Melder_setTracing (bool tracing) {
trace ("switch tracing on in Praat version %s at %s", xstr (PRAAT_VERSION_STR), ctime (& today));
}
-bool Melder_getTracing () {
- return theTracing;
-}
-
void Melder_tracingToFile (MelderFile file) {
MelderFile_copy (file, & theTracingFile);
MelderFile_delete (& theTracingFile);
}
-void Melder_trace_ (const char *fileName, int lineNumber, const char *functionName, const char *format, ...) {
- if (! theTracing || MelderFile_isNull (& theTracingFile)) return;
+void Melder_trace_FMT (const char *fileName, int lineNumber, const char *functionName, const char *format, ...) {
+ if (! Melder_isTracing || MelderFile_isNull (& theTracingFile)) return;
try {
FILE *f = Melder_fopen (& theTracingFile, "a");
if (fileName) {
diff --git a/sys/melder_files.cpp b/sys/melder_files.cpp
index 28ded40..05c4c04 100644
--- a/sys/melder_files.cpp
+++ b/sys/melder_files.cpp
@@ -101,15 +101,15 @@ void Melder_wcsTo8bitFileRepresentation_inline (const wchar_t *wcs, char *utf8)
So we first convert to UTF-16, then turn into CFString, then decompose, then convert to UTF-8.
*/
UniChar unipath [kMelder_MAXPATH+1];
- long n = wcslen (wcs), n_utf16 = 0;
- for (long i = 0; i < n; i ++) {
- utf32_t kar = wcs [i];
- if (kar <= 0xFFFF) {
- unipath [n_utf16 ++] = kar; // including null byte
+ size_t n = wcslen (wcs), n_utf16 = 0;
+ for (size_t i = 0; i < n; i ++) {
+ char32_t kar = (char32_t) wcs [i]; // change sign (bit 32 is never used)
+ if (kar <= 0x00FFFF) {
+ unipath [n_utf16 ++] = (UniChar) kar; // including null byte; guarded truncation
} else if (kar <= 0x10FFFF) {
- kar -= 0x10000;
- unipath [n_utf16 ++] = 0xD800 | (kar >> 10);
- unipath [n_utf16 ++] = 0xDC00 | (kar & 0x3FF);
+ kar -= 0x010000;
+ unipath [n_utf16 ++] = (UniChar) (0x00D800 | (kar >> 10)); // correct truncation, because UTF-32 has fewer than 27 bits (in fact it has 21 bits)
+ unipath [n_utf16 ++] = (UniChar) (0x00DC00 | (kar & 0x0003FF));
} else {
unipath [n_utf16 ++] = UNICODE_REPLACEMENT_CHARACTER;
}
@@ -137,16 +137,16 @@ void Melder_8bitFileRepresentationToWcs_inline (const char *path, wchar_t *wpath
long n_utf16 = CFStringGetLength (cfpath2);
long n_wcs = 0;
for (long i = 0; i < n_utf16; i ++) {
- utf32_t kar = CFStringGetCharacterAtIndex (cfpath2, i);
- if (kar >= 0xD800 && kar <= 0xDBFF) {
- utf32_t kar2 = CFStringGetCharacterAtIndex (cfpath2, ++ i);
- if (kar2 >= 0xDC00 && kar2 <= 0xDFFF) {
- kar = (((kar & 0x3FF) << 10) | (kar2 & 0x3FF)) + 0x10000;
+ char32_t kar1 = CFStringGetCharacterAtIndex (cfpath2, i);
+ if (kar1 >= 0x00D800 && kar1 <= 0x00DBFF) {
+ char32_t kar2 = (char32_t) CFStringGetCharacterAtIndex (cfpath2, ++ i); // convert up
+ if (kar2 >= 0x00DC00 && kar2 <= 0x00DFFF) {
+ kar1 = (((kar1 & 0x3FF) << 10) | (kar2 & 0x3FF)) + 0x10000;
} else {
- kar = UNICODE_REPLACEMENT_CHARACTER;
+ kar1 = UNICODE_REPLACEMENT_CHARACTER;
}
}
- wpath [n_wcs ++] = kar;
+ wpath [n_wcs ++] = (wchar_t) kar1;
}
wpath [n_wcs] = '\0';
CFRelease (cfpath2);
@@ -535,7 +535,7 @@ static size_t read_URL_data_from_file (void *buffer, size_t size, size_t nmemb,
#endif
FILE * Melder_fopen (MelderFile file, const char *type) {
- if (! Melder_getTracing())
+ if (! Melder_isTracing)
Melder_assert (wcsequ (Melder_double (1.5), L"1.5")); // check locale settings; because of the required file portability Praat cannot stand "1,5"
/*
* On the Unix-like systems (including MacOS), the path has to be converted to 8-bit characters in UTF-8 encoding.
diff --git a/sys/melder_ftoa.cpp b/sys/melder_ftoa.cpp
index 411de42..7161b95 100644
--- a/sys/melder_ftoa.cpp
+++ b/sys/melder_ftoa.cpp
@@ -31,7 +31,7 @@
* pb 2008/01/06 Mac: use strtod instead of wcstod for speed
* pb 2010/10/16 Melder_naturalLogarithm
* pb 2011/04/05 C++
- * pb 2014/01/09 use fabs in the calculating minimum precision
+ * pb 2014/01/09 use fabs in calculating minimum precision
*/
#include "melder.h"
@@ -41,8 +41,8 @@
#define NUMBER_OF_BUFFERS 32
/* = maximum number of arguments to a function call */
-#define MAXIMUM_NUMERIC_STRING_LENGTH 386
- /* = sign + 308 + point + 60 + e + sign + 3 + null byte + (\.c10^^ - 1) + 4 extra */
+#define MAXIMUM_NUMERIC_STRING_LENGTH 400
+ /* = sign + 324 + point + 60 + e + sign + 3 + null byte + ("·10^^" - "e") + 4 extra */
static wchar_t buffers [NUMBER_OF_BUFFERS] [MAXIMUM_NUMERIC_STRING_LENGTH + 1];
static int ibuffer = 0;
@@ -52,7 +52,29 @@ const wchar_t * Melder_integer (int64_t value) {
if (sizeof (long) == 8) {
swprintf (buffers [ibuffer], MAXIMUM_NUMERIC_STRING_LENGTH, L"%ld", value);
} else if (sizeof (long long) == 8) {
- swprintf (buffers [ibuffer], MAXIMUM_NUMERIC_STRING_LENGTH, L"%lld", value);
+ /*
+ * There are buggy platforms (namely 32-bit Mingw on Windows XP) that support long long and %lld but that convert
+ * the argument to a 32-bit long.
+ * There are also buggy platforms (namely 32-bit gcc on Linux) that support long long and %I64d but that convert
+ * the argument to a 32-bit long.
+ */
+ static const wchar_t *formatString = NULL;
+ if (! formatString) {
+ wchar_t tryBuffer [MAXIMUM_NUMERIC_STRING_LENGTH + 1];
+ swprintf (tryBuffer, MAXIMUM_NUMERIC_STRING_LENGTH, L"%lld", 1000000000000LL);
+ if (wcsequ (tryBuffer, L"1000000000000")) {
+ formatString = L"%lld";
+ } else {
+ swprintf (tryBuffer, MAXIMUM_NUMERIC_STRING_LENGTH, L"%I64d", 1000000000000LL);
+ if (wcsequ (tryBuffer, L"1000000000000")) {
+ formatString = L"%I64d";
+ } else {
+ wprintf (tryBuffer);
+ Melder_fatal ("Found no way to print 64-bit integers.");
+ }
+ }
+ }
+ swprintf (buffers [ibuffer], MAXIMUM_NUMERIC_STRING_LENGTH, formatString, value);
} else {
Melder_fatal ("Neither long nor long long is 8 bytes on this machine.");
}
@@ -214,12 +236,12 @@ const wchar_t * Melder_float (const wchar_t *number) {
if (number [0] == '1' && number [1] == 'e') {
wcscpy (buffers [ibuffer], L"10^^"); b = buffers [ibuffer] + 4;
} else {
- wcscat (buffers [ibuffer], L"\\.c10^^"); b += 7;
+ wcscat (buffers [ibuffer], L"·10^^"); b += 7;
}
Melder_assert (*n == 'e');
- if (*++n == '+') n ++; /* Ignore leading plus sign in exponent. */
- if (*n == '-') *(b++) = *(n++); /* Copy sign of negative exponent. */
- while (*n == '0') n ++; /* Ignore leading zeroes in exponent. */
+ if (*++n == '+') n ++; // ignore leading plus sign in exponent
+ if (*n == '-') *(b++) = *(n++); // copy sign of negative exponent
+ while (*n == '0') n ++; // ignore leading zeroes in exponent
while (*n >= '0' && *n <= '9') *(b++) = *(n++);
*(b++) = '^';
while (*n != '\0') *(b++) = *(n++); *b = '\0';
diff --git a/sys/melder_readtext.cpp b/sys/melder_readtext.cpp
index aa88101..a1852d5 100644
--- a/sys/melder_readtext.cpp
+++ b/sys/melder_readtext.cpp
@@ -37,28 +37,32 @@ wchar_t MelderReadText_getChar (MelderReadText me) {
} else {
if (* my readPointer8 == '\0') return 0;
if (my input8Encoding == kMelder_textInputEncoding_UTF8) {
- utf32_t kar = * (unsigned char *) my readPointer8 ++;
- if (kar <= 0x7F) {
- return kar;
- } else if (kar <= 0xDF) {
- utf32_t kar2 = * (unsigned char *) my readPointer8 ++;
- return ((kar & 0x1F) << 6) | (kar2 & 0x3F);
- } else if (kar <= 0xEF) {
- utf32_t kar2 = * (unsigned char *) my readPointer8 ++;
- utf32_t kar3 = * (unsigned char *) my readPointer8 ++;
- return ((kar & 0x0F) << 12) | ((kar2 & 0x3F) << 6) | (kar3 & 0x3F);
- } else if (kar <= 0xF4) {
- utf32_t kar2 = * (unsigned char *) my readPointer8 ++;
- utf32_t kar3 = * (unsigned char *) my readPointer8 ++;
- utf32_t kar4 = * (unsigned char *) my readPointer8 ++;
- return ((kar & 0x07) << 18) | ((kar2 & 0x3F) << 12) | ((kar3 & 0x3F) << 6) | (kar4 & 0x3F); // BUG: should be UTF-16 on Windows
+ char32_t kar1 = * (char8_t *) my readPointer8 ++;
+ if (kar1 <= 0x7F) {
+ return kar1;
+ } else if (kar1 <= 0xDF) {
+ char32_t kar2 = * (char8_t *) my readPointer8 ++;
+ return ((kar1 & 0x1F) << 6) | (kar2 & 0x3F);
+ } else if (kar1 <= 0xEF) {
+ char32_t kar2 = * (char8_t *) my readPointer8 ++;
+ char32_t kar3 = * (char8_t *) my readPointer8 ++;
+ return ((kar1 & 0x0F) << 12) | ((kar2 & 0x3F) << 6) | (kar3 & 0x3F);
+ } else if (kar1 <= 0xF4) {
+ char32_t kar2 = * (char8_t *) my readPointer8 ++;
+ char32_t kar3 = * (char8_t *) my readPointer8 ++;
+ char32_t kar4 = * (char8_t *) my readPointer8 ++;
+ return ((kar1 & 0x07) << 18) | ((kar2 & 0x3F) << 12) | ((kar3 & 0x3F) << 6) | (kar4 & 0x3F); // BUG: should be UTF-16 on Windows
+ } else {
+ return UNICODE_REPLACEMENT_CHARACTER;
}
} else if (my input8Encoding == kMelder_textInputEncoding_MACROMAN) {
return Melder_decodeMacRoman [* (unsigned char *) my readPointer8 ++];
} else if (my input8Encoding == kMelder_textInputEncoding_WINDOWS_LATIN1) {
return Melder_decodeWindowsLatin1 [* (unsigned char *) my readPointer8 ++];
+ } else {
+ /* Unknown encoding. */
+ return * (char8_t *) my readPointer8 ++;
}
- return * (unsigned char *) my readPointer8 ++;
}
}
@@ -180,8 +184,8 @@ static wchar_t * _MelderFile_readText (MelderFile file, char **string8) {
rewind (f); // length and type already set correctly.
autostring8 text8bit = Melder_malloc (char, length + 1);
Melder_assert (text8bit.peek() != NULL);
- int64_t numberOfBytesRead = fread_multi (text8bit.peek(), length, f);
- if (numberOfBytesRead < length)
+ size_t numberOfBytesRead = fread_multi (text8bit.peek(), (size_t) length, f);
+ if ((int64_t) numberOfBytesRead < length)
Melder_throw ("The file contains ", (double) length, " bytes, but we could read only ",
(double) numberOfBytesRead, " of them.");
text8bit [length] = '\0';
@@ -217,49 +221,51 @@ static wchar_t * _MelderFile_readText (MelderFile file, char **string8) {
text.reset (Melder_malloc (wchar_t, length + 1));
if (type == 1) {
for (int64_t i = 0; i < length; i ++) {
- utf16_t kar = bingetu2 (f);
+ char16_t kar1 = bingetu2 (f);
if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16 (or its signed counterpart)?
- text [i] = (wchar_t) kar;
+ text [i] = (wchar_t) kar1;
} else { // wchar_t is UTF-32 (or its signed counterpart)
- if (kar < 0xD800) {
- text [i] = (wchar_t) kar; // convert up without sign extension
- } else if (kar < 0xDC00) {
+ if (kar1 < 0xD800) {
+ text [i] = (wchar_t) kar1; // convert up without sign extension
+ } else if (kar1 < 0xDC00) {
length --;
- utf16_t kar2 = bingetu2 (f);
+ char16_t kar2 = bingetu2 (f);
if (kar2 >= 0xDC00 && kar2 <= 0xDFFF) {
- text [i] = (wchar_t) (0x00010000 + (uint32_t) (((uint32_t) kar & 0x000003FF) << 10) + (uint32_t) ((uint32_t) kar2 & 0x000003FF));
+ text [i] = (wchar_t) (0x00010000 +
+ (uint32_t) (((uint32_t) kar1 & 0x000003FF) << 10) +
+ (uint32_t) ((uint32_t) kar2 & 0x000003FF));
} else {
text [i] = UNICODE_REPLACEMENT_CHARACTER;
}
- } else if (kar < 0xE000) {
+ } else if (kar1 < 0xE000) {
text [i] = UNICODE_REPLACEMENT_CHARACTER;
- } else if (kar <= 0xFFFF) {
- text [i] = (wchar_t) kar; // convert up without sign extension
} else {
- Melder_fatal ("MelderFile_readText: unsigned short greater than 0xFFFF: should not occur.");
+ text [i] = (wchar_t) kar1; // convert up without sign extension
}
}
}
} else {
for (int64_t i = 0; i < length; i ++) {
- utf16_t kar = bingetu2LE (f);
+ char16_t kar1 = bingetu2LE (f);
if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16 (or its signed counterpart)?
- text [i] = (wchar_t) kar;
+ text [i] = (wchar_t) kar1;
} else { // wchar_t is UTF-32 (or its signed counterpart)
- if (kar < 0xD800) {
- text [i] = (wchar_t) kar; // convert up without sign extension
- } else if (kar < 0xDC00) {
+ if (kar1 < 0xD800) {
+ text [i] = (wchar_t) kar1; // convert up without sign extension
+ } else if (kar1 < 0xDC00) {
length --;
- utf16_t kar1 = bingetu2LE (f);
- if (kar1 >= 0xDC00 && kar1 <= 0xDFFF) {
- text [i] = (wchar_t) (0x00010000 + (uint32_t) (((uint32_t) kar & 0x000003FF) << 10) + (uint32_t) ((uint32_t) kar1 & 0x000003FF));
+ char16_t kar2 = bingetu2LE (f);
+ if (kar2 >= 0xDC00 && kar2 <= 0xDFFF) {
+ text [i] = (wchar_t) (0x00010000 +
+ (uint32_t) (((uint32_t) kar1 & 0x000003FF) << 10) +
+ (uint32_t) ((uint32_t) kar2 & 0x000003FF));
} else {
text [i] = UNICODE_REPLACEMENT_CHARACTER;
}
- } else if (kar < 0xE000) {
+ } else if (kar1 < 0xE000) {
text [i] = UNICODE_REPLACEMENT_CHARACTER;
- } else if (kar <= 0xFFFF) {
- text [i] = (wchar_t) kar; // convert up without sign extension
+ } else if (kar1 <= 0xFFFF) {
+ text [i] = (wchar_t) kar1; // convert up without sign extension
} else {
Melder_fatal ("MelderFile_readText: unsigned short greater than 0xFFFF: should not occur.");
}
diff --git a/sys/melder_strings.cpp b/sys/melder_strings.cpp
index 2e56d22..5b38a98 100644
--- a/sys/melder_strings.cpp
+++ b/sys/melder_strings.cpp
@@ -1,6 +1,6 @@
/* melder_strings.cpp
*
- * Copyright (C) 2006-2011 Paul Boersma
+ * Copyright (C) 2006-2011,2015 Paul Boersma
*
* 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
@@ -20,16 +20,16 @@
#include "melder.h"
#include "UnicodeData.h"
#define my me ->
-#define FREE_THRESHOLD_BYTES 10000
+#define FREE_THRESHOLD_BYTES 10000LL
static double totalNumberOfAllocations = 0, totalNumberOfDeallocations = 0, totalAllocationSize = 0, totalDeallocationSize = 0;
void MelderString_free (MelderString *me) {
if (my string == NULL) return;
Melder_free (my string);
- if (Melder_debug == 34) fprintf (stderr, "from MelderString_free\t%p\t%ld\t%ld\n", my string, my bufferSize, sizeof (wchar_t));
+ if (Melder_debug == 34) fprintf (stderr, "from MelderString_free\t%p\t%lld\t%d\n", my string, (long long) my bufferSize, (int) sizeof (wchar_t));
totalNumberOfDeallocations += 1;
- totalDeallocationSize += my bufferSize * sizeof (wchar_t);
+ totalDeallocationSize += my bufferSize * (int64_t) sizeof (wchar_t);
my bufferSize = 0;
my length = 0;
}
@@ -37,9 +37,9 @@ void MelderString_free (MelderString *me) {
void MelderString16_free (MelderString16 *me) {
if (my string == NULL) return;
Melder_free (my string);
- if (Melder_debug == 34) fprintf (stderr, "from MelderString16_free\t%p\t%ld\t%ld\n", my string, my bufferSize, 2L);
+ if (Melder_debug == 34) fprintf (stderr, "from MelderString16_free\t%p\t%lld\t%d\n", my string, (long long) my bufferSize, 2);
totalNumberOfDeallocations += 1;
- totalDeallocationSize += my bufferSize * sizeof (utf16_t);
+ totalDeallocationSize += my bufferSize * (int64_t) sizeof (char16_t);
my bufferSize = 0;
my length = 0;
}
@@ -48,16 +48,16 @@ void MelderString16_free (MelderString16 *me) {
if (sizeNeeded > my bufferSize) { \
Melder_assert (my bufferSize >= 0); \
Melder_assert (sizeNeeded >= 0); \
- sizeNeeded = 1.618034 * sizeNeeded + 100; \
+ sizeNeeded = (int64) (1.618034 * sizeNeeded) + 100; \
Melder_assert (sizeNeeded > 0); \
if (my string) { \
totalNumberOfDeallocations += 1; \
- totalDeallocationSize += my bufferSize * sizeof (type); \
+ totalDeallocationSize += my bufferSize * (int64) sizeof (type); \
} \
- long bytesNeeded = sizeNeeded * sizeof (type); \
+ int64 bytesNeeded = sizeNeeded * (int64) sizeof (type); \
Melder_assert (bytesNeeded > 0); \
try { \
- if (Melder_debug == 34) fprintf (stderr, "from MelderString:expandIfNecessary\t%p\t%ld\t%ld\n", my string, sizeNeeded, sizeof (type)); \
+ if (Melder_debug == 34) fprintf (stderr, "from MelderString:expandIfNecessary\t%p\t%lld\t%d\n", my string, (long long) sizeNeeded, (int) sizeof (type)); \
my string = (type *) Melder_realloc (my string, bytesNeeded); \
} catch (MelderError) { \
my bufferSize = 0; \
@@ -70,54 +70,54 @@ void MelderString16_free (MelderString16 *me) {
}
void MelderString_empty (MelderString *me) {
- if (my bufferSize * sizeof (wchar_t) >= FREE_THRESHOLD_BYTES) {
+ if (my bufferSize * (int64) sizeof (wchar) >= FREE_THRESHOLD_BYTES) {
MelderString_free (me);
}
- unsigned long sizeNeeded = 1;
- expandIfNecessary (wchar_t)
+ int64 sizeNeeded = 1;
+ expandIfNecessary (wchar)
my string [0] = '\0';
my length = 0;
}
void MelderString16_empty (MelderString16 *me) {
- if (my bufferSize * sizeof (wchar_t) >= FREE_THRESHOLD_BYTES) {
+ if (my bufferSize * (int64) sizeof (wchar) >= FREE_THRESHOLD_BYTES) {
MelderString16_free (me);
}
- unsigned long sizeNeeded = 1;
- expandIfNecessary (utf16_t)
+ int64_t sizeNeeded = 1;
+ expandIfNecessary (char16)
my string [0] = '\0';
my length = 0;
}
void MelderString_copy (MelderString *me, const wchar_t *source) {
- if (my bufferSize * sizeof (wchar_t) >= FREE_THRESHOLD_BYTES)
+ if (my bufferSize * (int64) sizeof (wchar) >= FREE_THRESHOLD_BYTES)
MelderString_free (me);
if (source == NULL) source = L"";
- unsigned long length = wcslen (source);
- unsigned long sizeNeeded = length + 1;
- expandIfNecessary (wchar_t)
+ int64 length = (int64) wcslen (source);
+ int64 sizeNeeded = length + 1;
+ expandIfNecessary (wchar)
wcscpy (my string, source);
my length = length;
}
-void MelderString_ncopy (MelderString *me, const wchar_t *source, unsigned long n) {
- if (my bufferSize * sizeof (wchar_t) >= FREE_THRESHOLD_BYTES)
+void MelderString_ncopy (MelderString *me, const wchar_t *source, int64 n) {
+ if (my bufferSize * (int64) sizeof (wchar_t) >= FREE_THRESHOLD_BYTES)
MelderString_free (me);
if (source == NULL) source = L"";
- unsigned long length = wcslen (source);
+ int64 length = (int64) wcslen (source);
if (length > n) length = n;
- unsigned long sizeNeeded = length + 1;
- expandIfNecessary (wchar_t)
- wcsncpy (my string, source, length);
+ int64 sizeNeeded = length + 1;
+ expandIfNecessary (wchar)
+ wcsncpy (my string, source, (size_t) length);
my string [length] = '\0';
my length = length;
}
void MelderString_append (MelderString *me, const wchar_t *s1) {
if (s1 == NULL) s1 = L"";
- unsigned long length1 = wcslen (s1);
- unsigned long sizeNeeded = my length + length1 + 1;
- expandIfNecessary (wchar_t)
+ int64 length1 = (int64) wcslen (s1);
+ int64 sizeNeeded = my length + length1 + 1;
+ expandIfNecessary (wchar)
wcscpy (my string + my length, s1);
my length += length1;
}
@@ -125,10 +125,10 @@ void MelderString_append (MelderString *me, const wchar_t *s1) {
void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2) {
if (s1 == NULL) s1 = L"";
if (s2 == NULL) s2 = L"";
- unsigned long length1 = wcslen (s1);
- unsigned long length2 = wcslen (s2);
- unsigned long sizeNeeded = my length + length1 + length2 + 1;
- expandIfNecessary (wchar_t)
+ int64 length1 = (int64) wcslen (s1);
+ int64 length2 = (int64) wcslen (s2);
+ int64 sizeNeeded = my length + length1 + length2 + 1;
+ expandIfNecessary (wchar)
wcscpy (my string + my length, s1);
my length += length1;
wcscpy (my string + my length, s2);
@@ -139,11 +139,11 @@ void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2
if (s1 == NULL) s1 = L"";
if (s2 == NULL) s2 = L"";
if (s3 == NULL) s3 = L"";
- unsigned long length1 = wcslen (s1);
- unsigned long length2 = wcslen (s2);
- unsigned long length3 = wcslen (s3);
- unsigned long sizeNeeded = my length + length1 + length2 + length3 + 1;
- expandIfNecessary (wchar_t)
+ int64 length1 = (int64) wcslen (s1);
+ int64 length2 = (int64) wcslen (s2);
+ int64 length3 = (int64) wcslen (s3);
+ int64 sizeNeeded = my length + length1 + length2 + length3 + 1;
+ expandIfNecessary (wchar)
wcscpy (my string + my length, s1);
my length += length1;
wcscpy (my string + my length, s2);
@@ -157,12 +157,12 @@ void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2
if (s2 == NULL) s2 = L"";
if (s3 == NULL) s3 = L"";
if (s4 == NULL) s4 = L"";
- unsigned long length1 = wcslen (s1);
- unsigned long length2 = wcslen (s2);
- unsigned long length3 = wcslen (s3);
- unsigned long length4 = wcslen (s4);
- unsigned long sizeNeeded = my length + length1 + length2 + length3 + length4 + 1;
- expandIfNecessary (wchar_t)
+ int64 length1 = (int64) wcslen (s1);
+ int64 length2 = (int64) wcslen (s2);
+ int64 length3 = (int64) wcslen (s3);
+ int64 length4 = (int64) wcslen (s4);
+ int64 sizeNeeded = my length + length1 + length2 + length3 + length4 + 1;
+ expandIfNecessary (wchar)
wcscpy (my string + my length, s1);
my length += length1;
wcscpy (my string + my length, s2);
@@ -181,13 +181,13 @@ void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2
if (s3 == NULL) s3 = L"";
if (s4 == NULL) s4 = L"";
if (s5 == NULL) s5 = L"";
- unsigned long length1 = wcslen (s1);
- unsigned long length2 = wcslen (s2);
- unsigned long length3 = wcslen (s3);
- unsigned long length4 = wcslen (s4);
- unsigned long length5 = wcslen (s5);
- unsigned long sizeNeeded = my length + length1 + length2 + length3 + length4 + length5 + 1;
- expandIfNecessary (wchar_t)
+ int64 length1 = (int64) wcslen (s1);
+ int64 length2 = (int64) wcslen (s2);
+ int64 length3 = (int64) wcslen (s3);
+ int64 length4 = (int64) wcslen (s4);
+ int64 length5 = (int64) wcslen (s5);
+ int64 sizeNeeded = my length + length1 + length2 + length3 + length4 + length5 + 1;
+ expandIfNecessary (wchar)
wcscpy (my string + my length, s1);
my length += length1;
wcscpy (my string + my length, s2);
@@ -209,14 +209,14 @@ void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2
if (s4 == NULL) s4 = L"";
if (s5 == NULL) s5 = L"";
if (s6 == NULL) s6 = L"";
- unsigned long length1 = wcslen (s1);
- unsigned long length2 = wcslen (s2);
- unsigned long length3 = wcslen (s3);
- unsigned long length4 = wcslen (s4);
- unsigned long length5 = wcslen (s5);
- unsigned long length6 = wcslen (s6);
- unsigned long sizeNeeded = my length + length1 + length2 + length3 + length4 + length5 + length6 + 1;
- expandIfNecessary (wchar_t)
+ int64 length1 = (int64) wcslen (s1);
+ int64 length2 = (int64) wcslen (s2);
+ int64 length3 = (int64) wcslen (s3);
+ int64 length4 = (int64) wcslen (s4);
+ int64 length5 = (int64) wcslen (s5);
+ int64 length6 = (int64) wcslen (s6);
+ int64 sizeNeeded = my length + length1 + length2 + length3 + length4 + length5 + length6 + 1;
+ expandIfNecessary (wchar)
wcscpy (my string + my length, s1);
my length += length1;
wcscpy (my string + my length, s2);
@@ -241,15 +241,15 @@ void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2
if (s5 == NULL) s5 = L"";
if (s6 == NULL) s6 = L"";
if (s7 == NULL) s7 = L"";
- unsigned long length1 = wcslen (s1);
- unsigned long length2 = wcslen (s2);
- unsigned long length3 = wcslen (s3);
- unsigned long length4 = wcslen (s4);
- unsigned long length5 = wcslen (s5);
- unsigned long length6 = wcslen (s6);
- unsigned long length7 = wcslen (s7);
- unsigned long sizeNeeded = my length + length1 + length2 + length3 + length4 + length5 + length6 + length7 + 1;
- expandIfNecessary (wchar_t)
+ int64 length1 = (int64) wcslen (s1);
+ int64 length2 = (int64) wcslen (s2);
+ int64 length3 = (int64) wcslen (s3);
+ int64 length4 = (int64) wcslen (s4);
+ int64 length5 = (int64) wcslen (s5);
+ int64 length6 = (int64) wcslen (s6);
+ int64 length7 = (int64) wcslen (s7);
+ int64 sizeNeeded = my length + length1 + length2 + length3 + length4 + length5 + length6 + length7 + 1;
+ expandIfNecessary (wchar)
wcscpy (my string + my length, s1);
my length += length1;
wcscpy (my string + my length, s2);
@@ -277,16 +277,16 @@ void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2
if (s6 == NULL) s6 = L"";
if (s7 == NULL) s7 = L"";
if (s8 == NULL) s8 = L"";
- unsigned long length1 = wcslen (s1);
- unsigned long length2 = wcslen (s2);
- unsigned long length3 = wcslen (s3);
- unsigned long length4 = wcslen (s4);
- unsigned long length5 = wcslen (s5);
- unsigned long length6 = wcslen (s6);
- unsigned long length7 = wcslen (s7);
- unsigned long length8 = wcslen (s8);
- unsigned long sizeNeeded = my length + length1 + length2 + length3 + length4 + length5 + length6 + length7 + length8 + 1;
- expandIfNecessary (wchar_t)
+ int64 length1 = (int64) wcslen (s1);
+ int64 length2 = (int64) wcslen (s2);
+ int64 length3 = (int64) wcslen (s3);
+ int64 length4 = (int64) wcslen (s4);
+ int64 length5 = (int64) wcslen (s5);
+ int64 length6 = (int64) wcslen (s6);
+ int64 length7 = (int64) wcslen (s7);
+ int64 length8 = (int64) wcslen (s8);
+ int64 sizeNeeded = my length + length1 + length2 + length3 + length4 + length5 + length6 + length7 + length8 + 1;
+ expandIfNecessary (wchar)
wcscpy (my string + my length, s1);
my length += length1;
wcscpy (my string + my length, s2);
@@ -317,17 +317,17 @@ void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2
if (s7 == NULL) s7 = L"";
if (s8 == NULL) s8 = L"";
if (s9 == NULL) s9 = L"";
- unsigned long length1 = wcslen (s1);
- unsigned long length2 = wcslen (s2);
- unsigned long length3 = wcslen (s3);
- unsigned long length4 = wcslen (s4);
- unsigned long length5 = wcslen (s5);
- unsigned long length6 = wcslen (s6);
- unsigned long length7 = wcslen (s7);
- unsigned long length8 = wcslen (s8);
- unsigned long length9 = wcslen (s9);
- unsigned long sizeNeeded = my length + length1 + length2 + length3 + length4 + length5 + length6 + length7 + length8 + length9 + 1;
- expandIfNecessary (wchar_t)
+ int64 length1 = (int64) wcslen (s1);
+ int64 length2 = (int64) wcslen (s2);
+ int64 length3 = (int64) wcslen (s3);
+ int64 length4 = (int64) wcslen (s4);
+ int64 length5 = (int64) wcslen (s5);
+ int64 length6 = (int64) wcslen (s6);
+ int64 length7 = (int64) wcslen (s7);
+ int64 length8 = (int64) wcslen (s8);
+ int64 length9 = (int64) wcslen (s9);
+ int64 sizeNeeded = my length + length1 + length2 + length3 + length4 + length5 + length6 + length7 + length8 + length9 + 1;
+ expandIfNecessary (wchar)
wcscpy (my string + my length, s1);
my length += length1;
wcscpy (my string + my length, s2);
@@ -349,29 +349,29 @@ void MelderString_append (MelderString *me, const wchar_t *s1, const wchar_t *s2
}
void MelderString_appendCharacter (MelderString *me, wchar_t character) {
- unsigned long sizeNeeded = my length + 2; // make room for character and null byte
- expandIfNecessary (wchar_t)
+ int64 sizeNeeded = my length + 2; // make room for character and null byte
+ expandIfNecessary (wchar)
my string [my length] = character;
my length ++;
my string [my length] = L'\0';
}
void MelderString16_appendCharacter (MelderString16 *me, wchar_t character) {
- unsigned long sizeNeeded = my length + 3; // make room for character, potential surrogate character, and null byte
- expandIfNecessary (utf16_t)
+ int64 sizeNeeded = my length + 3; // make room for character, potential surrogate character, and null byte
+ expandIfNecessary (char16)
if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16?
- my string [my length] = character;
+ my string [my length] = (char16) character; // guarded cast
my length ++;
} else { // wchar_t is UTF-32.
- utf32_t kar = character;
- if (kar <= 0xFFFF) {
- my string [my length] = character;
+ char32 kar = (char32) character;
+ if (kar <= 0x00FFFF) {
+ my string [my length] = (char16) character; // guarded cast
my length ++;
} else if (kar <= 0x10FFFF) {
- kar -= 0x10000;
- my string [my length] = 0xD800 | (kar >> 10);
+ kar -= 0x010000;
+ my string [my length] = (char16) (0x00D800 | (kar >> 10));
my length ++;
- my string [my length] = 0xDC00 | (kar & 0x3FF);
+ my string [my length] = (char16) (0x00DC00 | (kar & 0x0003FF));
my length ++;
} else {
my string [my length] = UNICODE_REPLACEMENT_CHARACTER;
@@ -381,6 +381,14 @@ void MelderString16_appendCharacter (MelderString16 *me, wchar_t character) {
my string [my length] = '\0';
}
+void MelderString32_appendCharacter (MelderString32 *me, char32 character) {
+ int64 sizeNeeded = my length + 2; // make room for character and null byte
+ expandIfNecessary (char32)
+ my string [my length] = character;
+ my length ++;
+ my string [my length] = U'\0';
+}
+
void MelderString_get (MelderString *me, wchar_t *destination) {
if (my string) {
wcscpy (destination, my string);
diff --git a/sys/melder_textencoding.cpp b/sys/melder_textencoding.cpp
index fd9b014..85c4a8a 100644
--- a/sys/melder_textencoding.cpp
+++ b/sys/melder_textencoding.cpp
@@ -66,24 +66,29 @@ void Melder_textEncoding_prefs (void) {
bool Melder_isValidAscii (const wchar_t *text) {
for (; *text != '\0'; text ++) {
if (sizeof (wchar_t) == 2) {
- unsigned short kar = *text;
- if (kar > 127) return false;
+ if ((char16_t) *text > 127) return false; // make unsigned
} else {
- if (*text > 127) return false;
+ if ((char32_t) *text > 127) return false; // make unsigned
}
}
return true;
}
+bool Melder_isValidAscii (const char32_t *text) {
+ for (; *text != '\0'; text ++) {
+ if (*text > 127) return false;
+ }
+ return true;
+}
+
bool Melder_isEncodable (const wchar_t *text, int outputEncoding) {
switch (outputEncoding) {
case kMelder_textOutputEncoding_ASCII: {
for (; *text != '\0'; text ++) {
if (sizeof (wchar_t) == 2) {
- unsigned short kar = *text;
- if (kar > 127) return false;
+ if ((char16_t) *text > 127) return false; // make unsigned
} else {
- if (*text > 127) return false;
+ if ((char32_t) *text > 127) return false; // make unsigned
}
}
return true;
@@ -91,10 +96,9 @@ bool Melder_isEncodable (const wchar_t *text, int outputEncoding) {
case kMelder_textOutputEncoding_ISO_LATIN1: {
for (; *text != '\0'; text ++) {
if (sizeof (wchar_t) == 2) {
- unsigned short kar = *text;
- if (kar > 255) return false;
+ if ((char16_t) *text > 255) return false; // make unsigned
} else {
- if (*text > 255) return false;
+ if ((char32_t) *text > 255) return false; // make unsigned
}
}
return true;
@@ -110,8 +114,8 @@ bool Melder_isEncodable (const wchar_t *text, int outputEncoding) {
}
bool Melder_strIsValidUtf8 (const char *string) {
- for (const unsigned char *p = (const unsigned char *) & string [0]; *p != '\0'; p ++) {
- unsigned long kar = *p;
+ for (const char8_t *p = (const char8_t *) & string [0]; *p != '\0'; p ++) {
+ char32_t kar = (char32_t) *p;
if (kar <= 0x7F) {
;
} else if (kar <= 0xC1) {
@@ -136,31 +140,32 @@ long Melder_killReturns_inline (char *text) {
const char *from;
char *to;
for (from = text, to = text; *from != '\0'; from ++, to ++) {
- if (*from == 13) { /* Carriage return? */
- if (from [1] == '\n') { /* Followed by linefeed? Must be a Windows text. */
- from ++; /* Ignore carriage return. */
- *to = '\n'; /* Copy linefeed. */
- } else { /* Bare carriage return? Must be a Macintosh text. */
- *to = '\n'; /* Change to linefeed. */
+ if (*from == 13) { // carriage return?
+ if (from [1] == '\n') { // followed by linefeed? Must be a Windows text
+ from ++; // ignore carriage return
+ *to = '\n'; // copy linefeed
+ } else { // bare carriage return? Must be a Macintosh text
+ *to = '\n'; // change to linefeed
}
} else {
*to = *from;
}
}
- *to = '\0'; /* Closing null byte. */
+ *to = '\0'; // closing null byte
return to - text;
}
-long Melder_killReturns_inlineW (wchar_t *text) {
- const wchar_t *from;
- wchar_t *to;
+template <class CHAR>
+long Melder_killReturns_inlineCHAR (CHAR *text) {
+ const CHAR *from;
+ CHAR *to;
for (from = text, to = text; *from != '\0'; from ++, to ++) {
- if (*from == 13) { /* Carriage return? */
- if (from [1] == '\n' || from [1] == 0x0085 /* NextLine */) { /* Followed by linefeed? Must be a Windows text. */
- from ++; /* Ignore carriage return. */
- *to = '\n'; /* Copy linefeed. */
- } else { /* Bare carriage return? Must be a Macintosh text. */
- *to = '\n'; /* Change to linefeed (10). */
+ if (*from == 13) { // carriage return?
+ if (from [1] == '\n' || from [1] == 0x0085 /* NextLine */) { // followed by linefeed? Must be a Windows text
+ from ++; // ignore carriage return
+ *to = '\n'; // copy linefeed
+ } else { // bare carriage return? Must be a Macintosh text
+ *to = '\n'; // change to linefeed (10)
}
} else if (*from == 0x0085 /* NextLine */ || *from == 0x000C /* FormFeed */ ||
*from == UNICODE_LINE_SEPARATOR || *from == UNICODE_PARAGRAPH_SEPARATOR)
@@ -170,11 +175,17 @@ long Melder_killReturns_inlineW (wchar_t *text) {
*to = *from;
}
}
- *to = '\0'; /* Closing null char. */
+ *to = '\0'; // closing null character
return to - text;
}
+long Melder_killReturns_inlineW (wchar_t *text) {
+ return Melder_killReturns_inlineCHAR <wchar_t> (text);
+}
+long Melder_killReturns_inline32 (char32_t *text) {
+ return Melder_killReturns_inlineCHAR <char32_t> (text);
+}
-wchar_t Melder_decodeMacRoman [256] = {
+char32_t Melder_decodeMacRoman [256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
@@ -242,7 +253,7 @@ wchar_t Melder_decodeMacRoman [256] = {
UNICODE_MACRON, UNICODE_BREVE, UNICODE_DOT_ABOVE, UNICODE_RING_ABOVE, UNICODE_CEDILLA,
UNICODE_DOUBLE_ACUTE_ACCENT, UNICODE_OGONEK, UNICODE_CARON };
-wchar_t Melder_decodeWindowsLatin1 [256] = {
+char32_t Melder_decodeWindowsLatin1 [256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
@@ -266,8 +277,9 @@ wchar_t Melder_decodeWindowsLatin1 [256] = {
220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 };
-void Melder_8bitToWcs_inline (const char *string, wchar_t *wcs, int inputEncoding) {
- wchar_t *q = & wcs [0];
+template <class CHAR>
+void Melder_8bitToCHAR_inline (const char *string, CHAR *wcs, int inputEncoding) {
+ CHAR *q = & wcs [0];
if (inputEncoding == 0) {
inputEncoding = preferences. inputEncoding;
/*
@@ -304,19 +316,19 @@ void Melder_8bitToWcs_inline (const char *string, wchar_t *wcs, int inputEncodin
const unsigned char *p = (const unsigned char *) & string [0];
if (inputEncoding == kMelder_textInputEncoding_UTF8) {
while (*p != '\0') {
- utf32_t kar = * p ++;
- if (kar <= 0x7F) {
- * q ++ = kar;
- } else if (kar <= 0xDF) {
- unsigned long kar2 = * p ++;
- * q ++ = ((kar & 0x1F) << 6) | (kar2 & 0x3F);
- } else if (kar <= 0xEF) {
- unsigned long kar2 = * p ++, kar3 = * p ++;
- * q ++ = ((kar & 0x0F) << 12) | ((kar2 & 0x3F) << 6) | (kar3 & 0x3F);
- } else if (kar <= 0xF4) {
- unsigned long kar2 = * p ++, kar3 = * p ++, kar4 = * p ++;
- kar = ((kar & 0x07) << 18) | ((kar2 & 0x3F) << 12) | ((kar3 & 0x3F) << 6) | (kar4 & 0x3F);
- if (sizeof (wchar_t) == 2) {
+ char32_t kar1 = * p ++;
+ if (kar1 <= 0x7F) {
+ * q ++ = (CHAR) kar1;
+ } else if (kar1 <= 0xDF) {
+ char32_t kar2 = * p ++;
+ * q ++ = (CHAR) (((kar1 & 0x1F) << 6) | (kar2 & 0x3F));
+ } else if (kar1 <= 0xEF) {
+ char32_t kar2 = * p ++, kar3 = * p ++;
+ * q ++ = (CHAR) (((kar1 & 0x0F) << 12) | ((kar2 & 0x3F) << 6) | (kar3 & 0x3F));
+ } else if (kar1 <= 0xF4) {
+ char32_t kar2 = * p ++, kar3 = * p ++, kar4 = * p ++;
+ char32_t kar = ((kar1 & 0x07) << 18) | ((kar2 & 0x3F) << 12) | ((kar3 & 0x3F) << 6) | (kar4 & 0x3F);
+ if (sizeof (CHAR) == 2) {
/*
* Convert to UTF-16 surrogate pair.
*/
@@ -324,7 +336,7 @@ void Melder_8bitToWcs_inline (const char *string, wchar_t *wcs, int inputEncodin
* q ++ = 0xD800 | (kar >> 10);
* q ++ = 0xDC00 | (kar & 0x3FF);
} else {
- * q ++ = kar;
+ * q ++ = (CHAR) kar;
}
}
}
@@ -334,32 +346,74 @@ void Melder_8bitToWcs_inline (const char *string, wchar_t *wcs, int inputEncodin
}
} else if (inputEncoding == kMelder_textInputEncoding_WINDOWS_LATIN1) {
while (*p != '\0') {
- * q ++ = Melder_decodeWindowsLatin1 [* p ++];
+ * q ++ = (CHAR) Melder_decodeWindowsLatin1 [* p ++];
}
} else if (inputEncoding == kMelder_textInputEncoding_MACROMAN) {
while (*p != '\0') {
- * q ++ = Melder_decodeMacRoman [* p ++];
+ * q ++ = (CHAR) Melder_decodeMacRoman [* p ++];
}
} else if (inputEncoding != kMelder_textInputEncoding_UTF8) {
Melder_fatal ("Unknown text input encoding %d.", inputEncoding);
}
* q = '\0';
- (void) Melder_killReturns_inlineW (wcs);
+ (void) Melder_killReturns_inlineCHAR <CHAR> (wcs);
+}
+void Melder_8bitToWcs_inline (const char *string, wchar_t *wcs, int inputEncoding) {
+ Melder_8bitToCHAR_inline <wchar_t> (string, wcs, inputEncoding);
+}
+void Melder_8bitToUtf32_inline (const char *string, char32_t *wcs, int inputEncoding) {
+ Melder_8bitToCHAR_inline <char32_t> (string, wcs, inputEncoding);
}
wchar_t * Melder_8bitToWcs (const char *string, int inputEncoding) {
if (string == NULL) return NULL;
- autostring result = Melder_malloc (wchar_t, strlen (string) + 1);
+ autostring result = Melder_malloc (wchar_t, (int64_t) strlen (string) + 1);
Melder_8bitToWcs_inline (string, result.peek(), inputEncoding);
return result.transfer();
}
+char32_t * Melder_8bitToUtf32 (const char *string, int inputEncoding) {
+ if (string == NULL) return NULL;
+ autostring32 result = Melder_malloc (char32_t, (int64_t) strlen (string) + 1);
+ Melder_8bitToUtf32_inline (string, result.peek(), inputEncoding);
+ return result.transfer();
+}
wchar_t * Melder_utf8ToWcs (const char *string) {
if (string == NULL) return NULL;
- autostring result = Melder_malloc (wchar_t, strlen (string) + 1);
+ autostring result = Melder_malloc (wchar_t, (int64_t) strlen (string) + 1);
Melder_8bitToWcs_inline (string, result.peek(), kMelder_textInputEncoding_UTF8);
return result.transfer();
}
+char32_t * Melder_utf8ToUtf32 (const char *string) {
+ if (string == NULL) return NULL;
+ autostring32 result = Melder_malloc (char32_t, (int64_t) strlen (string) + 1);
+ Melder_8bitToUtf32_inline (string, result.peek(), kMelder_textInputEncoding_UTF8);
+ return result.transfer();
+}
+
+char32_t * Melder_utf8ToUtf32_f (const char *string) {
+ char32_t *result = Melder_malloc_f (char32_t, (int64_t) strlen (string) + 1);
+ Melder_assert (Melder_strIsValidUtf8 (string));
+ const char8_t *p = (const char8_t *) & string [0];
+ char32_t *q = & result [0];
+ while (*p != '\0') {
+ char32_t kar1 = (char32_t) * p ++; // convert up
+ if (kar1 <= 0x7F) {
+ * q ++ = kar1;
+ } else if (kar1 <= 0xDF) {
+ char32_t kar2 = (char32_t) * p ++; // convert up
+ * q ++ = ((kar1 & 0x1F) << 6) | (kar2 & 0x3F);
+ } else if (kar1 <= 0xEF) {
+ char32_t kar2 = (char32_t) * p ++, kar3 = (char32_t) * p ++; // convert up
+ * q ++ = ((kar1 & 0x0F) << 12) | ((kar2 & 0x3F) << 6) | (kar3 & 0x3F);
+ } else if (kar1 <= 0xF4) {
+ char32_t kar2 = (char32_t) * p ++, kar3 = (char32_t) * p ++, kar4 = (char32_t) * p ++; // convert up
+ * q ++ = ((kar1 & 0x07) << 18) | ((kar2 & 0x3F) << 12) | ((kar3 & 0x3F) << 6) | (kar4 & 0x3F);
+ }
+ }
+ * q = '\0'; // closing null character
+ return result;
+}
wchar_t * Melder_peekUtf8ToWcs (const char *textA) {
if (textA == NULL) return NULL;
@@ -369,38 +423,48 @@ wchar_t * Melder_peekUtf8ToWcs (const char *textA) {
MelderString_empty (& buffers [ibuffer]);
unsigned long n = strlen (textA), i, j;
for (i = 0, j = 0; i <= n; i ++) {
- unsigned char kar = textA [i];
- if (kar <= 0x7F) {
- MelderString_appendCharacter (& buffers [ibuffer], kar);
- } else if (kar <= 0xC1) {
+ char8_t kar1 = (char8_t) textA [i]; // convert sign
+ if (kar1 <= 0x7F) {
+ MelderString_appendCharacter (& buffers [ibuffer],
+ (char32_t) kar1);
+ } else if (kar1 <= 0xC1) {
MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
- } else if (kar <= 0xDF) {
- unsigned char kar2 = textA [++ i];
- if (kar2 == '\0' || ! (kar2 & 0x80) || (kar2 & 0x40)) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
- MelderString_appendCharacter (& buffers [ibuffer], ((kar & 0x1F) << 6) | (kar2 & 0x3F));
- } else if (kar <= 0xEF) {
- unsigned char kar2 = textA [++ i];
- if (kar2 == '\0' || ! (kar2 & 0x80) || (kar2 & 0x40)) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
- unsigned char kar3 = textA [++ i];
- if (kar3 == '\0' || ! (kar3 & 0x80) || (kar3 & 0x40)) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
- MelderString_appendCharacter (& buffers [ibuffer], ((kar & 0x0F) << 12) | ((kar2 & 0x3F) << 6) | (kar3 & 0x3F));
- } else if (kar <= 0xF4) {
- unsigned char kar2 = textA [++ i];
- if (kar2 == '\0' || ! (kar2 & 0x80) || (kar2 & 0x40)) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
- unsigned char kar3 = textA [++ i];
- if (kar3 == '\0' || ! (kar3 & 0x80) || (kar3 & 0x40)) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
- unsigned char kar4 = textA [++ i];
- if (kar4 == '\0' || ! (kar4 & 0x80) || (kar4 & 0x40)) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
- unsigned long character = ((kar & 0x07) << 18) | ((kar2 & 0x3F) << 12) | ((kar3 & 0x3F) << 6) | (kar4 & 0x3F);
+ } else if (kar1 <= 0xDF) {
+ char8_t kar2 = (char8_t) textA [++ i];
+ if ((kar2 & 0xC0) != 0x80) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
+ MelderString_appendCharacter (& buffers [ibuffer],
+ (char32_t) ((char32_t) ((char32_t) kar1 & 0x1F) << 6) |
+ (char32_t) ((char32_t) kar2 & 0x3F));
+ } else if (kar1 <= 0xEF) {
+ char8_t kar2 = (char8_t) textA [++ i];
+ if ((kar2 & 0xC0) != 0x80) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
+ char8_t kar3 = (char8_t) textA [++ i];
+ if ((kar3 & 0xC0) != 0x80) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
+ MelderString_appendCharacter (& buffers [ibuffer],
+ (char32_t) ((char32_t) ((char32_t) kar1 & 0x0F) << 12) |
+ (char32_t) ((char32_t) ((char32_t) kar2 & 0x3F) << 6) |
+ (char32_t) ((char32_t) kar3 & 0x3F));
+ } else if (kar1 <= 0xF4) {
+ char8_t kar2 = (char8_t) textA [++ i];
+ if ((kar2 & 0xC0) != 0x80) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
+ char8_t kar3 = (char8_t) textA [++ i];
+ if ((kar3 & 0xC0) != 0x80) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
+ char8_t kar4 = (char8_t) textA [++ i];
+ if ((kar4 & 0xC0) != 0x80) MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
+ char32_t character =
+ (char32_t) ((char32_t) ((char32_t) kar1 & 0x07) << 18) |
+ (char32_t) ((char32_t) ((char32_t) kar2 & 0x3F) << 12) |
+ (char32_t) ((char32_t) ((char32_t) kar3 & 0x3F) << 6) |
+ (char32_t) ((char32_t) kar4 & 0x3F);
if (sizeof (wchar_t) == 2) {
/*
* Convert to UTF-16 surrogate pair.
*/
- character -= 0x10000;
- MelderString_appendCharacter (& buffers [ibuffer], 0xD800 | (character >> 10));
- MelderString_appendCharacter (& buffers [ibuffer], 0xDC00 | (character & 0x3FF));
+ character -= 0x010000;
+ MelderString_appendCharacter (& buffers [ibuffer], 0x00D800 | (character >> 10));
+ MelderString_appendCharacter (& buffers [ibuffer], 0x00DC00 | (character & 0x0003FF));
} else {
- MelderString_appendCharacter (& buffers [ibuffer], character);
+ MelderString_appendCharacter (& buffers [ibuffer], (wchar_t) character); // convert sign
}
} else {
MelderString_appendCharacter (& buffers [ibuffer], UNICODE_REPLACEMENT_CHARACTER);
@@ -409,43 +473,43 @@ wchar_t * Melder_peekUtf8ToWcs (const char *textA) {
return buffers [ibuffer]. string;
}
-unsigned long wcslen_utf8 (const wchar_t *wcs, bool expandNewlines) {
- long length = 0;
+size_t wcslen_utf8 (const wchar_t *wcs, bool expandNewlines) {
+ size_t length = 0;
for (const wchar_t *p = & wcs [0]; *p != '\0'; p ++) {
if (sizeof (wchar_t) == 2) {
- utf16_t kar = *p;
- if (kar <= 0x007F) {
+ char16_t kar1 = (char16_t) *p; // convert sign
+ if (kar1 <= 0x007F) {
#ifdef _WIN32
- if (expandNewlines && kar == '\n') length ++;
+ if (expandNewlines && kar1 == '\n') length ++;
#else
(void) expandNewlines;
#endif
length ++;
- } else if (kar <= 0x07FF) {
+ } else if (kar1 <= 0x07FF) {
length += 2;
- } else if (kar >= 0xD800 && kar <= 0xDBFF) {
- unsigned short kar2 = * ++ p;
+ } else if (kar1 >= 0xD800 && kar1 <= 0xDBFF) {
+ char16_t kar2 = (char16_t) * ++ p;
Melder_assert (kar2 >= 0xDC00 && kar2 <= 0xDFFF);
length += 4;
} else {
- Melder_assert (kar <= 0xD7FF || kar >= 0xE000);
+ Melder_assert (kar1 <= 0xD7FF || kar1 >= 0xE000);
length += 3;
}
} else {
- utf32_t kar = *p;
- if (kar <= 0x00007F) {
+ char32_t kar = (char32_t) *p; // convert sign
+ if (kar <= 0x0000007F) {
#ifdef _WIN32
if (expandNewlines && kar == '\n') length ++;
#else
(void) expandNewlines;
#endif
length ++;
- } else if (kar <= 0x0007FF) {
+ } else if (kar <= 0x000007FF) {
length += 2;
- } else if (kar <= 0x00FFFF) {
+ } else if (kar <= 0x0000FFFF) {
length += 3;
} else {
- Melder_assert (kar <= 0x10FFFF);
+ Melder_assert (kar <= 0x0010FFFF);
length += 4;
}
}
@@ -453,27 +517,27 @@ unsigned long wcslen_utf8 (const wchar_t *wcs, bool expandNewlines) {
return length;
}
-unsigned long wcslen_utf16 (const wchar_t *wcs, bool expandNewlines) {
- long length = 0;
+size_t wcslen_utf16 (const wchar_t *wcs, bool expandNewlines) {
+ size_t length = 0;
for (const wchar_t *p = & wcs [0]; *p != '\0'; p ++) {
if (sizeof (wchar_t) == 2) {
#ifdef _WIN32
- unsigned short kar = *p;
+ char16_t kar = (char16_t) *p; // convert sign
if (expandNewlines && kar == '\n') length ++;
#else
(void) expandNewlines;
#endif
length ++;
} else {
- unsigned long kar = *p;
- if (kar <= 0x00007F) {
+ char32_t kar = (char32_t) *p; // convert sign
+ if (kar <= 0x0000007F) {
#ifdef _WIN32
if (expandNewlines && kar == '\n') length ++;
#else
(void) expandNewlines;
#endif
length ++;
- } else if (kar >= 0x10000) {
+ } else if (kar >= 0x00010000) {
length += 2;
} else {
length += 1;
@@ -484,45 +548,73 @@ unsigned long wcslen_utf16 (const wchar_t *wcs, bool expandNewlines) {
}
void Melder_wcsToUtf8_inline (const wchar_t *wcs, char *utf8) {
- long n = wcslen (wcs), i, j;
+ size_t n = wcslen (wcs), i, j;
for (i = 0, j = 0; i < n; i ++) {
- unsigned long kar = sizeof (wchar_t) == 2 ? (unsigned short) wcs [i] : wcs [i]; // crucial cast: prevents sign extension
- if (kar <= 0x00007F) {
+ char32_t kar = sizeof (wchar_t) == 2 ?
+ (char16_t) wcs [i] : // crucial cast: prevents sign extension
+ (char32_t) wcs [i];
+ if (kar <= 0x0000007F) {
#ifdef _WIN32
if (kar == '\n') utf8 [j ++] = 13;
#endif
- utf8 [j ++] = kar;
- } else if (kar <= 0x0007FF) {
- utf8 [j ++] = 0xC0 | (kar >> 6);
- utf8 [j ++] = 0x80 | (kar & 0x00003F);
- } else if (kar <= 0x00FFFF) {
+ utf8 [j ++] = (char) (char8_t) kar; // guarded truncation
+ } else if (kar <= 0x000007FF) {
+ utf8 [j ++] = (char) (char8_t) (0xC0 | (kar >> 6));
+ utf8 [j ++] = (char) (char8_t) (0x80 | (kar & 0x00003F));
+ } else if (kar <= 0x0000FFFF) {
if (sizeof (wchar_t) == 2) {
if ((kar & 0xF800) == 0xD800) {
if (kar > 0xDBFF)
- Melder_fatal ("Incorrect Unicode value (first surrogate member %lX).", kar);
- unsigned long kar2 = (unsigned short) wcs [++ i]; // crucial cast: prevents sign extension
+ Melder_fatal ("Incorrect Unicode value (first surrogate member %X).", kar);
+ char32_t kar2 = (char16_t) wcs [++ i]; // crucial cast: prevents sign extension
if (kar2 < 0xDC00 || kar2 > 0xDFFF)
- Melder_fatal ("Incorrect Unicode value (second surrogate member %lX).", kar2);
+ Melder_fatal ("Incorrect Unicode value (second surrogate member %X).", kar2);
kar = (((kar & 0x3FF) << 10) | (kar2 & 0x3FF)) + 0x10000; // decode UTF-16
- utf8 [j ++] = 0xF0 | (kar >> 18);
- utf8 [j ++] = 0x80 | ((kar >> 12) & 0x00003F);
- utf8 [j ++] = 0x80 | ((kar >> 6) & 0x00003F);
- utf8 [j ++] = 0x80 | (kar & 0x00003F);
+ utf8 [j ++] = (char) (char8_t) (0xF0 | (kar >> 18));
+ utf8 [j ++] = (char) (char8_t) (0x80 | ((kar >> 12) & 0x00003F));
+ utf8 [j ++] = (char) (char8_t) (0x80 | ((kar >> 6) & 0x00003F));
+ utf8 [j ++] = (char) (char8_t) (0x80 | (kar & 0x00003F));
} else {
- utf8 [j ++] = 0xE0 | (kar >> 12);
- utf8 [j ++] = 0x80 | ((kar >> 6) & 0x00003F);
- utf8 [j ++] = 0x80 | (kar & 0x00003F);
+ utf8 [j ++] = (char) (char8_t) (0xE0 | (kar >> 12));
+ utf8 [j ++] = (char) (char8_t) (0x80 | ((kar >> 6) & 0x00003F));
+ utf8 [j ++] = (char) (char8_t) (0x80 | (kar & 0x00003F));
}
} else {
- utf8 [j ++] = 0xE0 | (kar >> 12);
- utf8 [j ++] = 0x80 | ((kar >> 6) & 0x00003F);
- utf8 [j ++] = 0x80 | (kar & 0x00003F);
+ utf8 [j ++] = (char) (char8_t) (0xE0 | (kar >> 12));
+ utf8 [j ++] = (char) (char8_t) (0x80 | ((kar >> 6) & 0x00003F));
+ utf8 [j ++] = (char) (char8_t) (0x80 | (kar & 0x00003F));
}
} else {
- utf8 [j ++] = 0xF0 | (kar >> 18);
- utf8 [j ++] = 0x80 | ((kar >> 12) & 0x00003F);
- utf8 [j ++] = 0x80 | ((kar >> 6) & 0x00003F);
- utf8 [j ++] = 0x80 | (kar & 0x00003F);
+ utf8 [j ++] = (char) (char8_t) (0xF0 | (kar >> 18));
+ utf8 [j ++] = (char) (char8_t) (0x80 | ((kar >> 12) & 0x00003F));
+ utf8 [j ++] = (char) (char8_t) (0x80 | ((kar >> 6) & 0x00003F));
+ utf8 [j ++] = (char) (char8_t) (0x80 | (kar & 0x00003F));
+ }
+ }
+ utf8 [j] = '\0';
+}
+
+void Melder_str32ToUtf8_inline (const char32 *string, char *utf8) {
+ int64 n = str32len (string), i, j;
+ for (i = 0, j = 0; i < n; i ++) {
+ char32 kar = string [i];
+ if (kar <= 0x00007F) { // 7 bits
+ #ifdef _WIN32
+ if (kar == '\n') utf8 [j ++] = 13;
+ #endif
+ utf8 [j ++] = (char) (char8_t) kar; // guarded truncation
+ } else if (kar <= 0x0007FF) { // 11 bits
+ utf8 [j ++] = (char) (char8_t) (0xC0 | (kar >> 6)); // the upper 5 bits yield a number between 0xC4 and 0xDF
+ utf8 [j ++] = (char) (char8_t) (0x80 | (kar & 0x00003F)); // the lower 6 bits yield a number between 0x80 and 0xBF
+ } else if (kar <= 0x00FFFF) { // 16 bits
+ utf8 [j ++] = (char) (char8_t) (0xE0 | (kar >> 12)); // the upper 4 bits yield a number between 0xE0 and 0xEF
+ utf8 [j ++] = (char) (char8_t) (0x80 | ((kar >> 6) & 0x00003F));
+ utf8 [j ++] = (char) (char8_t) (0x80 | (kar & 0x00003F));
+ } else { // 21 bits
+ utf8 [j ++] = (char) (char8_t) (0xF0 | (kar >> 18)); // the upper 3 bits yield a number between 0xF0 and 0xF4 (0x10FFFF >> 18 == 4)
+ utf8 [j ++] = (char) (char8_t) (0x80 | ((kar >> 12) & 0x00003F)); // the next 6 bits
+ utf8 [j ++] = (char) (char8_t) (0x80 | ((kar >> 6) & 0x00003F)); // the third 6 bits
+ utf8 [j ++] = (char) (char8_t) (0x80 | (kar & 0x00003F)); // the lower 6 bits
}
}
utf8 [j] = '\0';
@@ -530,7 +622,7 @@ void Melder_wcsToUtf8_inline (const wchar_t *wcs, char *utf8) {
char * Melder_wcsToUtf8 (const wchar_t *string) {
if (string == NULL) return NULL;
- autostring8 result = Melder_malloc (char, wcslen_utf8 (string, true) + 1);
+ autostring8 result = Melder_malloc (char, (int64_t) wcslen_utf8 (string, true) + 1);
Melder_wcsToUtf8_inline (string, result.peek());
return result.transfer();
}
@@ -538,24 +630,24 @@ char * Melder_wcsToUtf8 (const wchar_t *string) {
char * Melder_peekWcsToUtf8 (const wchar_t *text) {
if (text == NULL) return NULL;
static char *buffer [11] = { NULL };
- static long bufferSize [11] = { 0 };
+ static size_t bufferSize [11] = { 0 };
static int ibuffer = 0;
if (++ ibuffer == 11) ibuffer = 0;
- long sizeNeeded = wcslen (text) * 4 + 1;
+ size_t sizeNeeded = wcslen (text) * 4 + 1;
if ((bufferSize [ibuffer] - sizeNeeded) * sizeof (char) >= 10000) {
Melder_free (buffer [ibuffer]);
bufferSize [ibuffer] = 0;
}
if (sizeNeeded > bufferSize [ibuffer]) {
- sizeNeeded = sizeNeeded * 1.61803 + 100;
- buffer [ibuffer] = (char *) Melder_realloc_f (buffer [ibuffer], sizeNeeded * sizeof (char));
+ sizeNeeded = (size_t) (sizeNeeded * 1.61803) + 100;
+ buffer [ibuffer] = (char *) Melder_realloc_f (buffer [ibuffer], (int64) sizeNeeded * (int64) sizeof (char));
bufferSize [ibuffer] = sizeNeeded;
}
Melder_wcsToUtf8_inline (text, buffer [ibuffer]);
return buffer [ibuffer];
}
-const utf16_t * Melder_peekWcsToUtf16 (const wchar_t *text) {
+const uint16_t * Melder_peekWcsToUtf16 (const wchar_t *text) {
if (text == NULL) return NULL;
static MelderString16 buffers [11] = { { 0 } };
static int ibuffer = 0;
@@ -568,7 +660,7 @@ const utf16_t * Melder_peekWcsToUtf16 (const wchar_t *text) {
#endif
MelderString16_appendCharacter (& buffers [ibuffer], text [i]);
}
- return buffers [ibuffer]. string;
+ return (uint16_t *) buffers [ibuffer]. string; // return type is such that this routine can be called by C
}
#if defined (macintosh)
diff --git a/sys/melder_writetext.cpp b/sys/melder_writetext.cpp
index ff7a933..795d95f 100644
--- a/sys/melder_writetext.cpp
+++ b/sys/melder_writetext.cpp
@@ -1,6 +1,6 @@
/* melder_writetext.cpp
*
- * Copyright (C) 2007-2011 Paul Boersma
+ * Copyright (C) 2007-2011,2015 Paul Boersma
*
* 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
@@ -44,24 +44,24 @@
#include "macport_off.h"
#endif
-static void Melder_fwriteUnicodeAsUtf8 (unsigned long unicode, FILE *f) {
- if (unicode <= 0x00007F) {
+static void Melder_fwriteUnicodeAsUtf8 (char32_t unicode, FILE *f) {
+ if (unicode <= 0x0000007F) {
#ifdef _WIN32
if (unicode == '\n') fputc (13, f);
#endif
- fputc (unicode, f);
- } else if (unicode <= 0x0007FF) {
+ fputc ((int) unicode, f); // because fputc wants an int instead of an uint8_t (guarded conversion)
+ } else if (unicode <= 0x000007FF) {
fputc (0xC0 | (unicode >> 6), f);
- fputc (0x80 | (unicode & 0x00003F), f);
- } else if (unicode <= 0x00FFFF) {
+ fputc (0x80 | (unicode & 0x0000003F), f);
+ } else if (unicode <= 0x0000FFFF) {
fputc (0xE0 | (unicode >> 12), f);
- fputc (0x80 | ((unicode >> 6) & 0x00003F), f);
- fputc (0x80 | (unicode & 0x00003F), f);
+ fputc (0x80 | ((unicode >> 6) & 0x0000003F), f);
+ fputc (0x80 | (unicode & 0x0000003F), f);
} else {
fputc (0xF0 | (unicode >> 18), f);
- fputc (0x80 | ((unicode >> 12) & 0x00003F), f);
- fputc (0x80 | ((unicode >> 6) & 0x00003F), f);
- fputc (0x80 | (unicode & 0x00003F), f);
+ fputc (0x80 | ((unicode >> 12) & 0x0000003F), f);
+ fputc (0x80 | ((unicode >> 6) & 0x0000003F), f);
+ fputc (0x80 | (unicode & 0x0000003F), f);
}
}
@@ -79,38 +79,38 @@ void Melder_fwriteWcsAsUtf8 (const wchar_t *ptr, size_t n, FILE *f) {
* We are likely to be on Macintosh or Linux.
* We assume that the string's encoding is UTF-32.
*/
- Melder_fwriteUnicodeAsUtf8 (ptr [i], f);
+ Melder_fwriteUnicodeAsUtf8 ((char32_t) ptr [i], f); // safe conversion, because sign bit is zero
} else if (sizeof (wchar_t) == 2) {
/*
* We are likely to be on Windows.
* We assume that the string's encoding is UTF-16;
* if it turns out to be otherwise, we write question marks.
*/
- unsigned long kar1 = (unsigned short) ptr [i]; // potential intermediate conversion from signed short to unsigned short
- if (kar1 < 0xD800) {
+ char32_t kar1 = (char32_t) (char16_t) ptr [i]; // don't extend sign
+ if (kar1 < 0x00D800) {
Melder_fwriteUnicodeAsUtf8 (kar1, f); // a character from the Basic Multilingual Plane
- } else if (kar1 < 0xDC00) {
+ } else if (kar1 < 0x00DC00) {
/*
* We detected a surrogate code point
* and will therefore translate two UTF-16 words into one Unicode supplementary character.
*/
- unsigned long kar2 = ptr [++ i];
+ char32_t kar2 = (char32_t) (char16_t) ptr [++ i]; // don't extend sign
if (kar2 == 0) { // string exhausted?
// Melder_fatal ("Detected a bare (final) high surrogate in UTF-16.");
Melder_fwriteUnicodeAsUtf8 (UNICODE_REPLACEMENT_CHARACTER, f);
return;
}
- if (kar2 >= 0xDC00 && kar2 <= 0xDFFF) {
- Melder_fwriteUnicodeAsUtf8 (0x10000 + ((kar1 - 0xD800) << 10) + (kar2 - 0xDC00), f);
+ if (kar2 >= 0x00DC00 && kar2 <= 0x00DFFF) {
+ Melder_fwriteUnicodeAsUtf8 (0x010000 + ((kar1 - 0x00D800) << 10) + (kar2 - 0x00DC00), f);
} else {
// Melder_fatal ("Detected a bare high surrogate in UTF-16.");
Melder_fwriteUnicodeAsUtf8 (UNICODE_REPLACEMENT_CHARACTER, f);
i --; // try to interpret the next character in the normal way
}
- } else if (kar1 < 0xE000) {
+ } else if (kar1 < 0x00E000) {
// Melder_fatal ("Detected a bare low surrogate in UTF-16.");
Melder_fwriteUnicodeAsUtf8 (UNICODE_REPLACEMENT_CHARACTER, f);
- } else if (kar1 <= 0xFFFF) {
+ } else if (kar1 <= 0x00FFFF) {
Melder_fwriteUnicodeAsUtf8 (kar1, f); // a character from the Basic Multilingual Plane
} else {
Melder_fatal ("Melder_fwriteWcsAsUtf8: unsigned short greater than 0xFFFF: should not occur.");
@@ -136,7 +136,9 @@ void MelderFile_writeText (MelderFile file, const wchar_t *text, enum kMelder_te
flockfile (f);
size_t n = wcslen (text);
for (size_t i = 0; i < n; i ++) {
- unsigned long kar = sizeof (wchar_t) == 2 ? (unsigned short) text [i] : text [i];
+ char32_t kar = sizeof (wchar_t) == 2 ?
+ (char16_t) text [i] : // don't extend sign
+ (char32_t) text [i];
#ifdef _WIN32
if (kar == '\n') putc_unlocked (13, f);
#endif
@@ -145,25 +147,25 @@ void MelderFile_writeText (MelderFile file, const wchar_t *text, enum kMelder_te
funlockfile (f);
} else {
binputu2 (0xFEFF, f); // Byte Order Mark
- long n = wcslen (text);
- for (long i = 0; i < n; i ++) {
+ size_t n = wcslen (text);
+ for (size_t i = 0; i < n; i ++) {
if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16?
- unsigned short kar = text [i];
+ char16_t kar = (char16_t) text [i];
#ifdef _WIN32
if (kar == '\n') binputu2 (13, f);
#endif
binputu2 (kar, f);
} else { // wchar_t is UTF-32.
- unsigned long kar = text [i];
+ char32_t kar = (char32_t) text [i];
#ifdef _WIN32
if (kar == '\n') binputu2 (13, f);
#endif
- if (kar <= 0xFFFF) {
- binputu2 (kar, f);
+ if (kar <= 0x00FFFF) {
+ binputu2 ((char16_t) kar, f); // guarded conversion down
} else if (kar <= 0x10FFFF) {
- kar -= 0x10000;
- binputu2 (0xD800 | (kar >> 10), f);
- binputu2 (0xDC00 | (kar & 0x3ff), f);
+ kar -= 0x010000;
+ binputu2 (0xD800 | (uint16_t) (kar >> 10), f);
+ binputu2 (0xDC00 | (uint16_t) ((char16_t) kar & 0x3ff), f);
} else {
binputu2 (UNICODE_REPLACEMENT_CHARACTER, f);
}
@@ -174,9 +176,9 @@ void MelderFile_writeText (MelderFile file, const wchar_t *text, enum kMelder_te
}
void MelderFile_appendText (MelderFile file, const wchar_t *text) {
- autofile f;
+ autofile f1;
try {
- f.reset (Melder_fopen (file, "rb"));
+ f1.reset (Melder_fopen (file, "rb"));
} catch (MelderError) {
Melder_clearError (); // it's OK if the file didn't exist yet...
MelderFile_writeText (file, text, Melder_getOutputEncoding ()); // because then we just "write"
@@ -185,8 +187,8 @@ void MelderFile_appendText (MelderFile file, const wchar_t *text) {
/*
* The file already exists and is open. Determine its type.
*/
- int firstByte = fgetc (f), secondByte = fgetc (f);
- f.close (file);
+ int firstByte = fgetc (f1), secondByte = fgetc (f1);
+ f1.close (file);
int type = 0;
if (firstByte == 0xfe && secondByte == 0xff) {
type = 1; // big-endian 16-bit
@@ -196,164 +198,168 @@ void MelderFile_appendText (MelderFile file, const wchar_t *text) {
if (type == 0) {
int outputEncoding = Melder_getOutputEncoding ();
if (outputEncoding == kMelder_textOutputEncoding_UTF8) { // TODO: read as file's encoding
- autofile f = Melder_fopen (file, "ab");
- Melder_fwriteWcsAsUtf8 (text, wcslen (text), f);
- f.close (file);
+ autofile f2 = Melder_fopen (file, "ab");
+ Melder_fwriteWcsAsUtf8 (text, wcslen (text), f2);
+ f2.close (file);
} else if ((outputEncoding == kMelder_textOutputEncoding_ASCII_THEN_UTF16 && Melder_isEncodable (text, kMelder_textOutputEncoding_ASCII))
|| (outputEncoding == kMelder_textOutputEncoding_ISO_LATIN1_THEN_UTF16 && Melder_isEncodable (text, kMelder_textOutputEncoding_ISO_LATIN1)))
{
/*
* Append ASCII or ISOLatin1 text to ASCII or ISOLatin1 file.
*/
- autofile f = Melder_fopen (file, "ab");
+ autofile f2 = Melder_fopen (file, "ab");
size_t n = wcslen (text);
for (size_t i = 0; i < n; i ++) {
- unsigned long kar = sizeof (wchar_t) == 2 ? (unsigned short) text [i] : text [i];
+ uint32_t kar = sizeof (wchar_t) == 2 ?
+ (uint16_t) text [i] : // don't extend sign
+ (uint32_t) text [i];
#ifdef _WIN32
- if (kar == '\n') fputc (13, f);
+ if (kar == '\n') fputc (13, f2);
#endif
- fputc (kar, f);
+ fputc ((uint8_t) kar, f2);
}
- f.close (file);
+ f2.close (file);
} else {
/*
* Convert to wide character file.
*/
autostring oldText = MelderFile_readText (file);
- autofile f = Melder_fopen (file, "wb");
- binputu2 (0xfeff, f);
- unsigned long n = wcslen (oldText.peek());
- for (unsigned long i = 0; i < n; i ++) {
+ autofile f2 = Melder_fopen (file, "wb");
+ binputu2 (0xfeff, f2);
+ size_t n = wcslen (oldText.peek());
+ for (size_t i = 0; i < n; i ++) {
if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16?
- wchar_t kar = oldText [i];
+ char16_t kar = (char16_t) oldText [i]; // reinterpret sign bit
#ifdef _WIN32
- if (kar == '\n') binputu2 (13, f);
+ if (kar == '\n') binputu2 (13, f2);
#endif
- binputu2 (kar, f);
+ binputu2 (kar, f2);
} else { // wchar_t is UTF-32.
- unsigned long kar = oldText [i];
+ char32_t kar = (char32_t) oldText [i]; // sign bit is always 0
#ifdef _WIN32
- if (kar == '\n') binputu2 (13, f);
+ if (kar == '\n') binputu2 (13, f2);
#endif
- if (kar <= 0xFFFF) {
- binputu2 (kar, f);
- } else if (kar <= 0x10FFFF) {
- kar -= 0x10000;
- binputu2 (0xD800 | (kar >> 10), f);
- binputu2 (0xDC00 | (kar & 0x3ff), f);
+ if (kar <= 0x0000FFFF) {
+ binputu2 ((uint16_t) kar, f2); // guarded conversion down
+ } else if (kar <= 0x0010FFFF) {
+ kar -= 0x00010000;
+ binputu2 (0xD800 | (uint16_t) (kar >> 10), f2);
+ binputu2 (0xDC00 | (uint16_t) ((uint16_t) kar & 0x03ff), f2);
} else {
- binputu2 (UNICODE_REPLACEMENT_CHARACTER, f);
+ binputu2 (UNICODE_REPLACEMENT_CHARACTER, f2);
}
}
}
n = wcslen (text);
for (unsigned long i = 0; i < n; i ++) {
if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16?
- unsigned short kar = text [i];
+ char16_t kar = (char16_t) text [i]; // reinterpret sign bit
#ifdef _WIN32
- if (kar == '\n') binputu2 (13, f);
+ if (kar == '\n') binputu2 (13, f2);
#endif
- binputu2 (kar, f);
+ binputu2 (kar, f2);
} else { // wchar_t is UTF-32.
- unsigned long kar = text [i];
+ char32_t kar = (char32_t) text [i]; // sign bit is always 0
#ifdef _WIN32
- if (kar == '\n') binputu2 (13, f);
+ if (kar == '\n') binputu2 (13, f2);
#endif
- if (kar <= 0xFFFF) {
- binputu2 (kar, f);
+ if (kar <= 0x00FFFF) {
+ binputu2 ((char16_t) kar, f2); // guarded conversion down
} else if (kar <= 0x10FFFF) {
- kar -= 0x10000;
- binputu2 (0xD800 | (kar >> 10), f);
- binputu2 (0xDC00 | (kar & 0x3ff), f);
+ kar -= 0x010000;
+ binputu2 (0xD800 | (char16_t) (kar >> 10), f2);
+ binputu2 (0xDC00 | (char16_t) ((char16_t) kar & 0x03ff), f2);
} else {
- binputu2 (UNICODE_REPLACEMENT_CHARACTER, f);
+ binputu2 (UNICODE_REPLACEMENT_CHARACTER, f2);
}
}
}
- f.close (file);
+ f2.close (file);
}
} else {
- autofile f = Melder_fopen (file, "ab");
+ autofile f2 = Melder_fopen (file, "ab");
unsigned long n = wcslen (text);
for (unsigned long i = 0; i < n; i ++) {
if (type == 1) {
if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16?
- unsigned short kar = text [i];
+ uint16_t kar = (uint16_t) text [i]; // reinterpret sign bit
#ifdef _WIN32
- if (kar == '\n') binputu2 (13, f);
+ if (kar == '\n') binputu2 (13, f2);
#endif
- binputu2 (kar, f);
+ binputu2 (kar, f2);
} else { // wchar_t is UTF-32
- unsigned long kar = text [i];
+ char32_t kar = (char32_t) text [i]; // sign bit is always 0
#ifdef _WIN32
- if (kar == '\n') binputu2 (13, f);
+ if (kar == '\n') binputu2 (13, f2);
#endif
- if (kar <= 0xFFFF) {
- binputu2 (kar, f);
+ if (kar <= 0x00FFFF) {
+ binputu2 ((char16_t) kar, f2); // guarded conversion down
} else if (kar <= 0x10FFFF) {
- kar -= 0x10000;
- binputu2 (0xD800 | (kar >> 10), f);
- binputu2 (0xDC00 | (kar & 0x3ff), f);
+ kar -= 0x010000;
+ binputu2 (0xD800 | (uint16_t) (kar >> 10), f2);
+ binputu2 (0xDC00 | (uint16_t) ((uint16_t) kar & 0x03ff), f2);
} else {
- binputu2 (UNICODE_REPLACEMENT_CHARACTER, f);
+ binputu2 (UNICODE_REPLACEMENT_CHARACTER, f2);
}
}
} else {
if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16?
- unsigned short kar = text [i];
+ uint16_t kar = (uint16_t) text [i]; // reinterpret sign bit
#ifdef _WIN32
- if (kar == '\n') binputu2LE (13, f);
+ if (kar == '\n') binputu2LE (13, f2);
#endif
- binputu2LE (kar, f);
+ binputu2LE (kar, f2);
} else { // wchar_t is UTF-32
- unsigned long kar = text [i];
+ char32_t kar = (char32_t) text [i]; // sign bit is always 0
#ifdef _WIN32
- if (kar == '\n') binputu2LE (13, f);
+ if (kar == '\n') binputu2LE (13, f2);
#endif
- if (kar <= 0xFFFF) {
- binputu2LE (kar, f);
+ if (kar <= 0x00FFFF) {
+ binputu2LE ((char16_t) kar, f2); // guarded conversion down
} else if (kar <= 0x10FFFF) {
- kar -= 0x10000;
- binputu2LE (0xD800 | (kar >> 10), f);
- binputu2LE (0xDC00 | (kar & 0x3ff), f);
+ kar -= 0x010000;
+ binputu2LE (0xD800 | (uint16_t) (kar >> 10), f2);
+ binputu2LE (0xDC00 | (uint16_t) ((uint16_t) kar & 0x3ff), f2);
} else {
- binputu2LE (UNICODE_REPLACEMENT_CHARACTER, f);
+ binputu2LE (UNICODE_REPLACEMENT_CHARACTER, f2);
}
}
}
}
- f.close (file);
+ f2.close (file);
}
}
static void _MelderFile_write (MelderFile file, const wchar_t *string) {
if (string == NULL) return;
- unsigned long length = wcslen (string);
+ size_t length = wcslen (string);
FILE *f = file -> filePointer;
if (file -> outputEncoding == kMelder_textOutputEncoding_ASCII || file -> outputEncoding == kMelder_textOutputEncoding_ISO_LATIN1) {
- for (unsigned long i = 0; i < length; i ++) {
- char kar = string [i];
+ for (size_t i = 0; i < length; i ++) {
+ char kar = string [i]; // truncate
if (kar == '\n' && file -> requiresCRLF) putc (13, f);
putc (kar, f);
}
} else if (file -> outputEncoding == kMelder_textOutputEncoding_UTF8) {
- for (unsigned long i = 0; i < length; i ++) {
- unsigned long kar = sizeof (wchar_t) == 2 ? (unsigned short) string [i] : string [i];
+ for (size_t i = 0; i < length; i ++) {
+ char32_t kar = sizeof (wchar_t) == 2 ?
+ (char16_t) string [i] : // don't extend sign
+ (char32_t) string [i];
if (kar <= 0x00007F) {
if (kar == '\n' && file -> requiresCRLF) putc (13, f);
- putc (kar, f);
+ putc ((int) kar, f); // guarded conversion down
} else if (kar <= 0x0007FF) {
putc (0xC0 | (kar >> 6), f);
putc (0x80 | (kar & 0x00003F), f);
} else if (kar <= 0x00FFFF) {
if (sizeof (wchar_t) == 2) {
- if ((kar & 0xF800) == 0xD800) {
- if (kar > 0xDBFF)
+ if ((kar & 0x00F800) == 0x00D800) {
+ if (kar > 0x00DBFF)
Melder_fatal ("Incorrect Unicode value (first surrogate member %lX).", kar);
- unsigned long kar2 = (unsigned short) string [++ i]; // crucial cast: prevents sign extension
- if (kar2 < 0xDC00 || kar2 > 0xDFFF)
+ char32_t kar2 = (char32_t) (char16_t) string [++ i]; // don't extend sign
+ if (kar2 < 0x00DC00 || kar2 > 0x00DFFF)
Melder_fatal ("Incorrect Unicode value (second surrogate member %lX).", kar2);
- kar = (((kar & 0x3FF) << 10) | (kar2 & 0x3FF)) + 0x10000; // decode UTF-16
+ kar = (((kar & 0x0003FF) << 10) | (kar2 & 0x0003FF)) + 0x010000; // decode UTF-16
putc (0xF0 | (kar >> 18), f);
putc (0x80 | ((kar >> 12) & 0x00003F), f);
putc (0x80 | ((kar >> 6) & 0x00003F), f);
@@ -376,18 +382,20 @@ static void _MelderFile_write (MelderFile file, const wchar_t *string) {
}
}
} else {
- for (unsigned long i = 0; i < length; i ++) {
- unsigned long kar = sizeof (wchar_t) == 2 ? (unsigned short) string [i] : string [i];
+ for (size_t i = 0; i < length; i ++) {
+ char32_t kar = sizeof (wchar_t) == 2 ?
+ (char16_t) string [i] : // don't extend sign
+ (char32_t) string [i];
if (kar == '\n' && file -> requiresCRLF) binputu2 (13, f);
if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16?
- binputu2 (kar, f);
+ binputu2 ((char16_t) kar, f);
} else { // wchar_t is UTF-32.
- if (kar <= 0xFFFF) {
- binputu2 (kar, f);
+ if (kar <= 0x00FFFF) {
+ binputu2 ((char16_t) kar, f);
} else if (kar <= 0x10FFFF) {
- kar -= 0x10000;
- binputu2 (0xD800 | (kar >> 10), f);
- binputu2 (0xDC00 | (kar & 0x3ff), f);
+ kar -= 0x010000;
+ binputu2 (0xD800 | (char16_t) (kar >> 10), f);
+ binputu2 (0xDC00 | (char16_t) ((char16_t) kar & 0x03ff), f);
} else {
binputu2 (UNICODE_REPLACEMENT_CHARACTER, f);
}
@@ -398,22 +406,24 @@ static void _MelderFile_write (MelderFile file, const wchar_t *string) {
void MelderFile_writeCharacter (MelderFile file, wchar_t character) {
FILE *f = file -> filePointer;
- unsigned long kar = sizeof (wchar_t) == 2 ? (unsigned short) character : character;
+ char32_t kar = sizeof (wchar_t) == 2 ?
+ (char16_t) character : // don't extend sign
+ (char32_t) character;
if (file -> outputEncoding == kMelder_textOutputEncoding_ASCII || file -> outputEncoding == kMelder_textOutputEncoding_ISO_LATIN1) {
if (kar == '\n' && file -> requiresCRLF) putc (13, f);
putc (kar, f);
} else if (file -> outputEncoding == kMelder_textOutputEncoding_UTF8) {
if (kar <= 0x00007F) {
if (kar == '\n' && file -> requiresCRLF) putc (13, f);
- putc (kar, f);
+ putc ((int) kar, f); // guarded conversion down
} else if (kar <= 0x0007FF) {
putc (0xC0 | (kar >> 6), f);
putc (0x80 | (kar & 0x00003F), f);
} else if (kar <= 0x00FFFF) {
if (sizeof (wchar_t) == 2) {
- if ((kar & 0xF800) == 0xD800) {
- static unsigned long buffer; // NOT REENTRANT
- if (kar >= 0xD800 && kar <= 0xDBFF) {
+ if ((kar & 0x00F800) == 0x00D800) {
+ static char32_t buffer; // NOT REENTRANT
+ if (kar >= 0x00D800 && kar <= 0x00DBFF) {
buffer = kar;
} else {
kar = (((buffer & 0x3FF) << 10) | (kar & 0x3FF)) + 0x10000; // decode UTF-16
@@ -441,14 +451,14 @@ void MelderFile_writeCharacter (MelderFile file, wchar_t character) {
} else {
if (kar == '\n' && file -> requiresCRLF) binputu2 (13, f);
if (sizeof (wchar_t) == 2) { // wchar_t is UTF-16?
- binputu2 (kar, f);
+ binputu2 ((uint16_t) kar, f);
} else { // wchar_t is UTF-32.
- if (kar <= 0xFFFF) {
- binputu2 (kar, f);
- } else if (kar <= 0x10FFFF) {
- kar -= 0x10000;
- binputu2 (0xD800 | (kar >> 10), f);
- binputu2 (0xDC00 | (kar & 0x3ff), f);
+ if (kar <= 0x0000FFFF) {
+ binputu2 ((uint16_t) kar, f);
+ } else if (kar <= 0x0010FFFF) {
+ kar -= 0x00010000;
+ binputu2 (0xD800 | (uint16_t) (kar >> 10), f);
+ binputu2 (0xDC00 | (uint16_t) ((uint16_t) kar & 0x03ff), f);
} else {
binputu2 (UNICODE_REPLACEMENT_CHARACTER, f);
}
diff --git a/sys/oo.h b/sys/oo.h
index 5402d7e..232aa81 100644
--- a/sys/oo.h
+++ b/sys/oo.h
@@ -2,7 +2,7 @@
#define _oo_h_
/* oo.h
*
- * Copyright (C) 1994-2012,2013 Paul Boersma
+ * Copyright (C) 1994-2012,2013,2015 Paul Boersma
*
* 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
@@ -45,6 +45,13 @@
#define oo_UBYTE(x) oo_SIMPLE (unsigned char, u1, x)
#define oo_UINT(x) oo_SIMPLE (unsigned int, u2, x)
#define oo_ULONG(x) oo_SIMPLE (unsigned long, u4, x)
+#define oo_INT8(x) oo_SIMPLE (int8, i8, x)
+#define oo_INT16(x) oo_SIMPLE (int16, i16, x)
+#define oo_INT32(x) oo_SIMPLE (int32, i32, x)
+#define oo_INT64(x) oo_SIMPLE (int64, i64, x)
+#define oo_UINT8(x) oo_SIMPLE (uint8, u8, x)
+#define oo_UINT16(x) oo_SIMPLE (uint16, u16, x)
+#define oo_UINT32(x) oo_SIMPLE (uint32, u32, x)
#define oo_BOOL(x) oo_SIMPLE (unsigned char, u1, x)
#define oo_FLOAT(x) oo_SIMPLE (double, r4, x)
#define oo_DOUBLE(x) oo_SIMPLE (double, r8, x)
diff --git a/sys/oo_DESCRIPTION.h b/sys/oo_DESCRIPTION.h
index 0485756..88f3f34 100644
--- a/sys/oo_DESCRIPTION.h
+++ b/sys/oo_DESCRIPTION.h
@@ -1,6 +1,6 @@
/* oo_DESCRIPTION.h
*
- * Copyright (C) 1994-2012,2013 Paul Boersma
+ * Copyright (C) 1994-2012,2013,2015 Paul Boersma
*
* 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
@@ -23,6 +23,8 @@
#define oo_BYTE(x) { L"" #x, bytewa, Melder_offsetof (ooSTRUCT, x), sizeof (signed char) },
#undef oo_INT
#define oo_INT(x) { L"" #x, intwa, Melder_offsetof (ooSTRUCT, x), sizeof (int) },
+#undef oo_INT32
+#define oo_INT32(x) { L"" #x, intwa, Melder_offsetof (ooSTRUCT, x), sizeof (int32) },
#undef oo_LONG
#define oo_LONG(x) { L"" #x, longwa, Melder_offsetof (ooSTRUCT, x), sizeof (long) },
#undef oo_UBYTE
diff --git a/sys/oo_READ_BINARY.h b/sys/oo_READ_BINARY.h
index aa3e762..cd27af6 100644
--- a/sys/oo_READ_BINARY.h
+++ b/sys/oo_READ_BINARY.h
@@ -129,9 +129,9 @@
#define oo_COLLECTION(Class,x,ItemClass,version) \
{ \
- long n = bingeti4 (f); \
+ int32_t n = bingeti4 (f); \
our x = Class##_create (); \
- for (long i = 1; i <= n; i ++) { \
+ for (int32_t i = 1; i <= n; i ++) { \
long saveVersion = Thing_version; \
auto##ItemClass item = (ItemClass) Thing_new (ItemClass); \
Thing_version = version; \
diff --git a/sys/praat.cpp b/sys/praat.cpp
index dc19f49..453ca5a 100644
--- a/sys/praat.cpp
+++ b/sys/praat.cpp
@@ -1529,8 +1529,18 @@ void praat_run (void) {
Melder_assert ((double) dummy == 40000.0);
Melder_assert ((double) (int16_t) dummy == -25536.0);
}
+ {
+ int64_t dummy = 1000000000000;
+ if (! wcsequ (Melder_integer (dummy), L"1000000000000"))
+ Melder_fatal ("The number 1000000000000 is mistaken written on this machine as %ls", Melder_integer (dummy));
+ }
{ uint32_t dummy = 0xffffffff;
+ Melder_assert ((int64_t) dummy == 4294967295LL);
Melder_assert (wcsequ (Melder_integer (dummy), L"4294967295"));
+ Melder_assert (double (dummy) == 4294967295.0);
+ }
+ { double dummy = 3000000000.0;
+ Melder_assert ((uint32_t) dummy == 3000000000);
}
if (sizeof (off_t) < 8)
diff --git a/sys/praat_logo.cpp b/sys/praat_logo.cpp
index 7f8b75a..9d1c9bd 100644
--- a/sys/praat_logo.cpp
+++ b/sys/praat_logo.cpp
@@ -35,7 +35,7 @@ static void logo_defaultDraw (Graphics g) {
Graphics_text (g, 0.5, 0.6, Melder_peekUtf8ToWcs (praatP.title));
Graphics_setFontStyle (g, 0);
Graphics_setFontSize (g, 12);
- Graphics_text (g, 0.5, 0.25, L"\\s{Built on the} %%Praat shell%\\s{,\\co Paul Boersma, 1992-2012");
+ Graphics_text (g, 0.5, 0.25, L"\\s{Built on the} %%Praat shell%\\s{,© Paul Boersma, 1992-2015");
}
static struct {
@@ -102,7 +102,9 @@ void praat_showLogo (int autoPopDown) {
#define xstr(s) str(s)
#define str(s) #s
gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (dialog), xstr (PRAAT_VERSION_STR));
- gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG (dialog), "Copyright (C) 1992-" xstr(PRAAT_YEAR) " by Paul Boersma and David Weenink");
+ static const wchar_t *copyright = Melder_utf8ToWcs ("Copyright © 1992–" xstr(PRAAT_YEAR) " by Paul Boersma and David Weenink");
+ gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG (dialog),
+ Melder_peekWcsToUtf8 (copyright));
gtk_about_dialog_set_license (GTK_ABOUT_DIALOG (dialog), "GPL");
gtk_about_dialog_set_website (GTK_ABOUT_DIALOG (dialog), "http://www.praat.org");
//gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG (dialog), authors);
diff --git a/sys/praat_objectMenus.cpp b/sys/praat_objectMenus.cpp
index 68137d8..f0b3439 100644
--- a/sys/praat_objectMenus.cpp
+++ b/sys/praat_objectMenus.cpp
@@ -367,7 +367,7 @@ FORM (praat_debug, L"Set debugging options", 0)
LABEL (L"", L"in unpredictable ways.")
INTEGER (L"Debug option", L"0")
OK
-SET_INTEGER (L"Tracing", Melder_getTracing ())
+SET_INTEGER (L"Tracing", Melder_isTracing)
SET_INTEGER (L"Debug option", Melder_debug)
DO
Melder_setTracing (GET_INTEGER (L"Tracing"));
diff --git a/sys/praat_version.h b/sys/praat_version.h
index 438a9dc..a62aacc 100644
--- a/sys/praat_version.h
+++ b/sys/praat_version.h
@@ -1,5 +1,5 @@
-#define PRAAT_VERSION_STR 5.4.04
-#define PRAAT_VERSION_NUM 5404
-#define PRAAT_YEAR 2014
-#define PRAAT_MONTH December
-#define PRAAT_DAY 28
+#define PRAAT_VERSION_STR 5.4.06
+#define PRAAT_VERSION_NUM 5406
+#define PRAAT_YEAR 2015
+#define PRAAT_MONTH February
+#define PRAAT_DAY 21
diff --git a/test/fon/data.praat b/test/fon/data.praat
index a03c850..fb6529e 100644
Binary files a/test/fon/data.praat and b/test/fon/data.praat differ
diff --git a/test/fon/soundFiles.praat b/test/fon/soundFiles.praat
index a3cb433..31b0344 100644
--- a/test/fon/soundFiles.praat
+++ b/test/fon/soundFiles.praat
@@ -56,15 +56,24 @@ procedure test32 .type$ .extension$ .duration
printline 't:4' seconds
endfor
endproc
+Debug... no 18
call test WAV wav 3
+Debug... no 0
call test WAV wav 3
+Debug... no 0
call test AIFF aiff 3
call test AIFC aifc 3
call test Next/Sun au 3
call test NIST nist 3
call test FLAC flac 3
+Debug... no 18
+call test WAV wav 30
+Debug... no 0
call test WAV wav 30
call test24 WAV wav 3
+Debug... no 18
+call test32 WAV wav 3
+Debug... no 0
call test32 WAV wav 3
procedure do
diff --git a/test/runAllTests.praat b/test/runAllTests.praat
index 3313255..d712323 100644
--- a/test/runAllTests.praat
+++ b/test/runAllTests.praat
@@ -1,23 +1,34 @@
# Praat script runAlltests.praat
-# Paul Boersma, 6 May 2013
+# Paul Boersma, 31 December 2014
#
# This script runs all Praat scripts in its subdirectories.
-directories = Create Strings as directory list... directories .
+Text writing preferences: "try ASCII, then UTF-16"
+if macintosh
+ Text reading preferences: "try UTF-8, then MacRoman"
+elif windows
+ Text reading preferences: "try UTF-8, then Windows Latin-1"
+elif unix
+ Text reading preferences: "try UTF-8, then ISO Latin-1"
+else
+ exitScript: "Unknown operating system."
+endif
+
+directories = Create Strings as directory list: "directories", "."
numberOfDirectories = Get number of strings
for directory to numberOfDirectories
-printline 'directory'
- select Strings directories
- directory$ = Get string... directory
- printline 'directory$'
+ appendInfoLine: directory
+ selectObject: directories
+ directory$ = Get string: directory
+ appendInfoLine: directory$
if directory$ <> "manually"
- files = Create Strings as file list... files 'directory$'/*.praat
+ files = Create Strings as file list: "files", directory$ + "/*.praat"
numberOfFiles = Get number of strings
for file to numberOfFiles
- select files
- file$ = Get string... file
- printline ### executing 'directory$'/'file$':
- execute 'directory$'/'file$'
+ selectObject: files
+ file$ = Get string: file
+ appendInfoLine: "### executing ", directory$, "/", file$, ":"
+ runScript: directory$ + "/" + file$
endfor
endif
endfor
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/praat.git
More information about the debian-med-commit
mailing list