diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/app/Makefile.tpl wfdb-10.4.6/app/Makefile.tpl
--- wfdb-10.4.5/app/Makefile.tpl 2006-05-11 15:06:03.000000000 -0400
+++ wfdb-10.4.6/app/Makefile.tpl 2008-04-09 15:17:31.000000000 -0400
@@ -1,19 +1,19 @@
# file: Makefile.tpl G. Moody 23 May 2000
-# Last revised: 11 May 2006
+# Last revised: 9 April 2008
# This section of the Makefile should not need to be changed.
CFILES = ann2rr.c bxb.c calsig.c ecgeval.c epicmp.c fir.c ihr.c mfilt.c \
mrgann.c mxm.c nguess.c nst.c plotstm.c pscgen.c pschart.c psfd.c rdann.c \
- rdsamp.c rr2ann.c rxr.c sampfreq.c sigamp.c sigavg.c skewedit.c \
- snip.c sortann.c sqrs.c sqrs125.c sumann.c sumstats.c tach.c time2sec.c \
- wabp.c wfdbcat.c wfdbcollate.c wfdbdesc.c \
+ rdsamp.c rr2ann.c rxr.c sampfreq.c sigamp.c sigavg.c signame.c signum.c \
+ skewedit.c snip.c sortann.c sqrs.c sqrs125.c sumann.c sumstats.c tach.c \
+ time2sec.c wabp.c wfdbcat.c wfdbcollate.c wfdbdesc.c \
wfdbwhich.c wqrs.c wrann.c wrsamp.c xform.c
XFILES = ann2rr bxb calsig ecgeval epicmp fir ihr mfilt \
mrgann mxm nguess nst plotstm pscgen pschart psfd rdann \
- rdsamp rr2ann rxr sampfreq sigamp sigavg skewedit \
- snip sortann sqrs sqrs125 sumann sumstats tach time2sec \
- wabp wfdbcat wfdbcollate wfdbdesc wfdbwhich wqrs \
- wrann wrsamp xform
+ rdsamp rr2ann rxr sampfreq sigamp sigavg signame signum \
+ skewedit snip sortann sqrs sqrs125 sumann sumstats tach \
+ time2sec wabp wfdbcat wfdbcollate wfdbdesc\
+ wfdbwhich wqrs wrann wrsamp xform
SCRIPTS = cshsetwfdb setwfdb
PSFILES = pschart.pro psfd.pro 12lead.pro
MFILES = Makefile
diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/app/rxr.c wfdb-10.4.6/app/rxr.c
--- wfdb-10.4.5/app/rxr.c 2002-05-20 19:17:35.000000000 -0400
+++ wfdb-10.4.6/app/rxr.c 2008-03-31 12:02:27.000000000 -0400
@@ -1,9 +1,9 @@
/* file: rxr.c G. Moody 16 August 1989
- Last revised: 20 May 2002
+ Last revised: 31 March 2008
-------------------------------------------------------------------------------
rxr: ANSI/AAMI-standard run-by-run annotation file comparator
-Copyright (C) 2002 George B. Moody
+Copyright (C) 1989-2008 George B. Moody
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -52,7 +52,7 @@
char *pname; /* name by which this program was invoked */
char *record;
WFDB_Anninfo an[2];
-WFDB_Annotation annot[2];
+WFDB_Annotation annot[2], tempann;
int fflag = 3;
FILE *ofile, *sfile;
long start, end_time, match_dt;
@@ -86,7 +86,7 @@
void rxr(stat, type)
int stat, type;
{
- int i, j;
+ int i, j, goflag = 1;
int run_length[2];
unsigned int a, b;
long run_start, run_end;
@@ -258,8 +258,15 @@
break;
}
}
- } while (getann(a, &annot[a]) >= 0 &&
- (end_time <= 0L || annot[a].time <= end_time));
+ if (getann(a, &tempann) < 0) {
+ if (run_length[a] > 0)
+ annot[a].anntyp = NORMAL;
+ else
+ goflag = 0;
+ }
+ else
+ annot[a] = tempann;
+ } while (goflag > 0 && (end_time <= 0L || annot[a].time <= end_time));
}
/* `pstat' prints a statistic described by s, defined as the quotient of a and
@@ -369,6 +376,8 @@
return (']');
}
case RHYTHM:
+ if (annot.aux == NULL || *(annot.aux) == 0)
+ return('O');
/* An `(AF' rhythm change annotation is mapped to `{' only if AF is
not already in progress. If VF was in progress, it is assumed to
have ended. */
diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/app/signame.c wfdb-10.4.6/app/signame.c
--- wfdb-10.4.5/app/signame.c 1969-12-31 19:00:00.000000000 -0500
+++ wfdb-10.4.6/app/signame.c 2008-04-09 15:14:44.000000000 -0400
@@ -0,0 +1,138 @@
+/* file: signum.c G. Moody 9 April 2008
+
+-------------------------------------------------------------------------------
+signum: Print signal names for signal numbers given as arguments
+Copyright (C) 2008 George B. Moody
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA.
+
+You may contact the author by e-mail (george@mit.edu) or postal mail
+(MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software,
+please visit PhysioNet (http://www.physionet.org/).
+_______________________________________________________________________________
+
+*/
+
+#include
Harvard-MIT Division of Health Sciences and Technology
-Copyright ©1980-2006 George B. Moody +Copyright ©1980-2008 George B. Moody
The most recent versions of the programs described in this guide may be freely
downloaded from PhysioNet. For
diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/doc/wag-src/wag.tex wfdb-10.4.6/doc/wag-src/wag.tex
--- wfdb-10.4.5/doc/wag-src/wag.tex 2005-06-13 01:05:53.000000000 -0400
+++ wfdb-10.4.6/doc/wag-src/wag.tex 2008-04-09 16:23:17.000000000 -0400
@@ -36,7 +36,7 @@
\pagestyle{empty}
\vspace*{\fill}
\noindent
-Copyright \copyright 1992 -- 2005 George B. Moody
+Copyright \copyright 1992 -- 2008 George B. Moody
\vspace{1 in}
\noindent
diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/doc/wag-src/wrann.1 wfdb-10.4.6/doc/wag-src/wrann.1
--- wfdb-10.4.5/doc/wag-src/wrann.1 2002-08-01 01:12:22.000000000 -0400
+++ wfdb-10.4.6/doc/wag-src/wrann.1 2008-03-27 10:22:07.000000000 -0400
@@ -5,8 +5,8 @@
\fBwrann -r\fR \fIrecord\fR \fB-a\fR \fIannotator\fR
.SH DESCRIPTION
\fBwrann\fR translates its standard input into an annotation file.
-The format of \fBwrann\fR input should be that produced by \fBrdann\fR(1).
-Specifically, the pipeline
+The format of \fBwrann\fR input should be that produced by \fBrdann\fR(1)
+using its default settings. Specifically, the pipeline
.br
\fBrdann -r\fR \fIrecord\fR \fB-a\fR \fIiann\fR \fB-f 0 | wrann -r\fR \fIrecord\fR \fB-a\fR \fIoann\fR
.br
@@ -18,6 +18,9 @@
editing: an annotation file may be translated into ASCII format
using \fBrdann\fR, edited using a text editor, and then translated back
into annotation file format using \fBwrann\fR.
+.PP
+Note the alternate format selected by \fBrdann\fR's \fB-x\fR option is
+incompatible with \fBwrann\fR.
.SH ENVIRONMENT
.PP
It may be necessary to set and export the shell variable \fBWFDB\fR (see
diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/doc/wpg-src/wpg0.tex wfdb-10.4.6/doc/wpg-src/wpg0.tex
--- wfdb-10.4.5/doc/wpg-src/wpg0.tex 2008-02-06 12:14:53.000000000 -0500
+++ wfdb-10.4.6/doc/wpg-src/wpg0.tex 2008-04-09 16:14:03.000000000 -0400
@@ -21,7 +21,7 @@
@center Harvard-MIT Division of Health Sciences and Technology
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1989 -- 2008 George B. Moody
+Copyright @copyright{} 1980 -- 2008 George B. Moody
@sp 2
The most recent versions of the software described in this guide may be
downloaded from @uref{http://www.physionet.org/}. For further
@@ -510,6 +510,37 @@
WFDB Software Package distribution, for information on any more recent
changes that may not be described here.
+@unnumberedsubsec Changes in version 10.4.6
+
+The WFDB functions @code{setafreq()} and @code{getafreq()} (for
+setting and getting the time resolution of newly-created output
+annotation files in ticks per second) were new in version 10.4.5, but
+were undocumented. They are now described in this Guide, and wrappers
+for these functions are now included in @file{fortran/wfdbf.c}.
+
+An important change in the WFDB library: memory allocation errors are
+now treated as fatal by default (in previous versions, the functions
+that encountered them returned error values that permitted the
+application to handle them). These errors occur when there is
+insufficient memory available to the WFDB library. After invoking
+@code{wfdbmemerr(0)}, if such an error occurs, the function in which it
+occurs will continue running if possible. By default, however, such an
+error will cause the process to terminate. In either case, the WFDB
+library emits an appropriate error message to aid in troubleshooting.
+
+New macros for handling dynamically allocated memory are defined in
+@file{lib/wfdblib.h} and used throughout the WFDB library, eliminating most
+known memory leaks. Three known leaks remain (in @code{setecgstr()},
+@code{setannstr()}, and @code{setanndesc()}); these are documented and
+harmless in current applications. Thanks to Yinqi Zhang for reporting a leak
+in @code{copysi()} (an internal WFDB library function defined in
+@file{signal.c}), which prompted the cleanup.
+
+WFDB functions @code{strecg()}, @code{setecgstr()}, @code{strann()},
+@code{setannstr()}, and @code{setanndesc()} now handle NULL string inputs
+properly. (Previous versions passed NULL strings to @code{strcmp()}, with
+undesirable results.)
+
@unnumberedsubsec Changes in version 10.4.5
Bob Farrell and Tony Ricke chased down and provided fixes for memory leaks
@@ -1779,7 +1810,7 @@
The remainder of the nodes in this section describe functions for:
* selecting:: Selecting database records (opening files).
-* special input modes:: Setting the input sampling frequency and more.
+* special I/O modes:: Setting the input sampling frequency and more.
* signal and annotation I/O:: Reading and writing signals and annotations.
* non-sequential:: Non-sequential access to WFDB files.
* conversion:: Time and other conversion functions.
@@ -1861,7 +1892,7 @@
functions that exist to serve unusual applications.
@page
-@node selecting,special input modes,introduction to functions,Functions
+@node selecting,special I/O modes,introduction to functions,Functions
@section Selecting Database Records
@cindex selecting database records
@cindex opening database files
@@ -2289,8 +2320,8 @@
for methods of opening output signal files.
@page
-@node special input modes, signal and annotation I/O, selecting, Functions
-@section Special Input Modes
+@node special I/O modes, signal and annotation I/O, selecting, Functions
+@section Special I/O Modes
@menu
* setifreq:: Setting the input sampling frequency.
@@ -2298,10 +2329,14 @@
* setgvmode:: Setting the resolution for a multifrequency
record.
* getspf:: Determining the number of samples per frame.
+* setafreq:: Setting the time resolution for output
+ annotations.
+* getafreq:: Determining the time resolution for output
+ annotations.
@end menu
@c @group
-@node setifreq, getifreq, special input modes, special input modes
+@node setifreq, getifreq, special I/O modes, special I/O modes
@unnumberedsubsec setifreq
@findex setifreq (10.2.6)
@cindex interpolation
@@ -2375,7 +2410,7 @@
Avoid using @code{wfdbinit} and @code{setifreq} in the same program.
@c @group
-@node getifreq, setgvmode, setifreq, special input modes
+@node getifreq, setgvmode, setifreq, special I/O modes
@unnumberedsubsec getifreq
@findex getifreq (10.2.6)
@@ -2397,7 +2432,7 @@
or the frequency chosen using a previous invocation of @code{setifreq}.
@c @group
-@node setgvmode, getspf, getifreq, special input modes
+@node setgvmode, getspf, getifreq, special I/O modes
@unnumberedsubsec setgvmode
@findex setgvmode (9.0)
@cindex interpolation
@@ -2446,7 +2481,7 @@
The constant @code{WFDB_GVPAD} is defined in @file{
Harvard-MIT Division of Health Sciences and Technology
-Copyright ©1980-2006 George B. Moody. +Copyright ©1980-2008 George B. Moody.
The most recent versions of the software described in this guide are freely downloadable from PhysioNet. For diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/doc/wug-src/wug0.tex wfdb-10.4.6/doc/wug-src/wug0.tex --- wfdb-10.4.5/doc/wug-src/wug0.tex 2006-05-05 12:59:12.000000000 -0400 +++ wfdb-10.4.6/doc/wug-src/wug0.tex 2008-04-09 16:14:54.000000000 -0400 @@ -57,7 +57,7 @@ \pagestyle{empty} \vspace*{\fill} \noindent -Copyright \copyright 1992 -- 2006 George B. Moody +Copyright \copyright 1992 -- 2008 George B. Moody \vspace{1 in} \noindent diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/fortran/wfdbf.c wfdb-10.4.6/fortran/wfdbf.c --- wfdb-10.4.5/fortran/wfdbf.c 2006-02-24 23:23:38.000000000 -0500 +++ wfdb-10.4.6/fortran/wfdbf.c 2008-02-08 10:45:50.000000000 -0500 @@ -1,9 +1,9 @@ /* file: wfdbf.c G. Moody 23 August 1995 - Last revised: 24 February 2006 wfdblib 10.4.0 + Last revised: 8 February 2008 wfdblib 10.4.6 _______________________________________________________________________________ wfdbf: Fortran wrappers for the WFDB library functions -Copyright (C) 1995-2006 George B. Moody +Copyright (C) 1995-2008 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -46,7 +46,7 @@ Fortran program; thus, for example, `annopen_' should be invoked as `annopen'. UNIX Fortran compilers and translators append a `_' to the names of all external symbols referenced in Fortran source files when -generating object files. Thus the linker can recognize that annopen1_ +generating object files. Thus the linker can recognize that annopen_ (defined below) is the function required by a Fortran program that invokes `annopen'; if the Fortran program were to invoke `annopen_', the linker would search (unsuccessfully) for a function named `annopen__'. @@ -233,6 +233,16 @@ return (getifreq()); } +long setafreq_(double *freq) +{ + return (setafreq(*freq)); +} + +double getafreq_(long int *dummy) +{ + return (getafreq()); +} + long getvec_(long int *long_vector) { #ifndef REPACK diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/lib/annot.c wfdb-10.4.6/lib/annot.c --- wfdb-10.4.5/lib/annot.c 2008-01-14 22:26:52.000000000 -0500 +++ wfdb-10.4.6/lib/annot.c 2008-04-08 14:28:58.000000000 -0400 @@ -1,5 +1,5 @@ /* file: annot.c G. Moody 13 April 1989 - Last revised: 14 January 2008 wfdblib 10.4.5 + Last revised: 8 April 2008 wfdblib 10.4.6 WFDB library functions for annotations _______________________________________________________________________________ @@ -174,21 +174,15 @@ p1 = strtok(annot.aux+1, " \t"); a = atoi(p1); if (0 <= a && a <= ACMAX && (p1 = strtok((char *)NULL, " \t"))) { - p2 = p1 + strlen(p1) + 1; - if ((s1 = (char *)malloc(((unsigned)(strlen(p1) + 1)))) == NULL || - (*p2 && - (s2 = (char *)malloc(((unsigned)(strlen(p2)+1)))) == NULL)) { - wfdb_error("annopen: insufficient memory\n"); - return (-1); - } - (void)strcpy(s1, p1); + SSTRCPY(s1, p1); (void)setannstr(a, s1); + p2 = p1 + strlen(p1) + 1; if (*p2) { - (void)strcpy(s2, p2); + SSTRCPY(s2, p2); (void)setanndesc(a, s2); } else - (void)setanndesc(a, (char*)NULL); + (void)setanndesc(a, (char *)NULL); } } @@ -255,20 +249,10 @@ { if (maxiann < n) { /* allocate input annotator data structures */ unsigned m = maxiann; - struct iadata **iadnew = realloc(iad, n*sizeof(struct iadata *)); - if (iadnew == NULL) { - wfdb_error("annopen: too many (%d) input annotators\n", n); - return (-1); - } - iad = iadnew; + SREALLOC(iad, n, sizeof(struct iadata *)); while (m < n) { - if ((iad[m] = calloc(1, sizeof(struct iadata))) == NULL) { - wfdb_error("annopen: too many (%d) input annotators\n", n); - while (--m > maxiann) - free(iad[m]); - return (-1); - } + SUALLOC(iad[m], 1, sizeof(struct iadata)); m++; } maxiann = n; @@ -281,20 +265,10 @@ { if (maxoann < n) { /* allocate output annotator data structures */ unsigned m = maxoann; - struct oadata **oadnew = realloc(oad, n*sizeof(struct oadata *)); - if (oadnew == NULL) { - wfdb_error("annopen: too many (%d) output annotators\n", n); - return (-1); - } - oad = oadnew; + SREALLOC(oad, n, sizeof(struct oadata *)); while (m < n) { - if ((oad[m] = calloc(1, sizeof(struct oadata))) == NULL) { - wfdb_error("annopen: too many (%d) output annotators\n", n); - while (--m > maxoann) - free(oad[m]); - return (-1); - } + SUALLOC(oad[m], 1, sizeof(struct oadata)); m++; } maxoann = n; @@ -356,13 +330,8 @@ aiarray[i].name, record); return (-3); } - if ((ia->info.name = - (char *)malloc((unsigned)(strlen(aiarray[i].name)+1))) - == NULL) { - wfdb_error("annopen: insufficient memory\n"); - return (-3); - } - (void)strcpy(ia->info.name, aiarray[i].name); + ia->info.name = NULL; + SSTRCPY(ia->info.name, aiarray[i].name); /* Try to figure out what format the file is in. AHA-format files begin with a null byte and an ASCII character which is one @@ -411,20 +380,10 @@ aiarray[i].name, record); return (-4); } - if ((oa->info.name = - (char *)malloc((unsigned)(strlen(aiarray[i].name)+1))) - == NULL) { - wfdb_error("annopen: insufficient memory\n"); - return (-4); - } - (void)strcpy(oa->info.name, aiarray[i].name); - if ((oa->rname = - (char *)malloc((unsigned)(strlen(record)+1))) - == NULL) { - wfdb_error("annopen: insufficient memory\n"); - return (-4); - } - (void)strcpy(oa->rname, record); + oa->info.name = NULL; + SSTRCPY(oa->info.name, aiarray[i].name); + oa->rname = NULL; + SSTRCPY(oa->rname, record); oa->ann.time = 0L; oa->info.stat = aiarray[i].stat; oa->out_of_order = 0; @@ -754,6 +713,7 @@ { int code; + if (str == NULL) str = ""; for (code = 1; code <= ACMAX; code++) if (strcmp(str, cstring[code]) == 0) return (code); @@ -764,10 +724,13 @@ FINT setecgstr(int code, char *string) { if (NOTQRS <= code && code <= ACMAX) { - if (cstring[code] == NULL || strcmp(cstring[code], string)) { - char *p = malloc(strlen(string)+1); - if (p) strcpy(cstring[code] = p, string); - } + if (string == NULL) string = ""; + cstring[code] = NULL; /* This statement (and the corresponding + statements in setannstr and setanndesc) + leak memory if the function is called + more than once with the same value for + code -- which is unlikely. */ + SSTRCPY(cstring[code], string); return (0); } wfdb_error("setecgstr: illegal annotation code %d\n", code); @@ -803,6 +766,7 @@ { int code; + if (str == NULL) str = ""; for (code = 1; code <= ACMAX; code++) if (strcmp(str, astring[code]) == 0) return (code); @@ -811,20 +775,16 @@ FINT setannstr(int code, char *string) { - if (0 < code && code <= ACMAX) { + int mflag = 0; + + if (code > 0) mflag = 1; + else code = -code; + if (code <= ACMAX) { + if (string == NULL) string = ""; if (astring[code] == NULL || strcmp(astring[code], string)) { - char *p = malloc(strlen(string)+1); - if (p) { - strcpy(astring[code] = p, string); - modified[code] = 1; - } - } - return (0); - } - else if (-ACMAX < code && code <= 0) { - if (astring[-code] == NULL || strcmp(astring[-code], string)) { - char *p = malloc(strlen(string)+1); - if (p) strcpy(astring[-code] = p, string); + astring[code] = NULL; + SSTRCPY(astring[code], string); + if (mflag) modified[code] = 1; } return (0); } @@ -897,20 +857,16 @@ FINT setanndesc(int code, char *string) { - if (0 < code && code <= ACMAX) { + int mflag = 0; + + if (code > 0) mflag = 1; + else code = -code; + if (code <= ACMAX) { + if (string == NULL) string = ""; if (tstring[code] == NULL || strcmp(tstring[code], string)) { - char *p = malloc(strlen(string)+1); - if (p) { - strcpy(tstring[code] = p, string); - modified[code] = 1; - } - } - return (0); - } - else if (-ACMAX < code && code <= 0) { - if (tstring[-code] == NULL || strcmp(tstring[-code], string)) { - char *p = malloc(strlen(string)+1); - if (p) strcpy(tstring[-code] = p, string); + tstring[code] = NULL; + SSTRCPY(tstring[code], string); + if (mflag) modified[code] = 1; } return (0); } @@ -941,8 +897,8 @@ if (n < niaf && (ia = iad[n]) != NULL && ia->file != NULL) { (void)wfdb_fclose(ia->file); - (void)free(ia->info.name); - (void)free(ia); + SFREE(ia->info.name); + SFREE(ia); while (n < niaf-1) { iad[n] = iad[n+1]; n++; @@ -999,9 +955,9 @@ oa->rname, oa->info.name); wfdb_error("to rearrange annotations in the correct order.\n"); } - (void)free(oa->info.name); - (void)free(oa->rname); - (void)free(oa); + SFREE(oa->info.name); + SFREE(oa->rname); + SFREE(oa); while (n < noaf-1) { oad[n] = oad[n+1]; n++; diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/lib/calib.c wfdb-10.4.6/lib/calib.c --- wfdb-10.4.5/lib/calib.c 2006-02-23 15:56:01.000000000 -0500 +++ wfdb-10.4.6/lib/calib.c 2008-04-08 14:41:36.000000000 -0400 @@ -1,10 +1,10 @@ /* file: calib.c G. Moody 4 July 1991 - Last revised: 23 February 2006 wfdblib 10.4.0 + Last revised: 8 April 2008 wfdblib 10.4.6 WFDB library functions for signal calibration _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1991-2006 George B. Moody +Copyright (C) 1991-2008 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -104,27 +104,11 @@ continue; /* This line appears to be a correctly formatted entry. Allocate - memory for a calibration list entry. (There doesn't seem to be any - way to make lint shut up about the pointer casts below, or about - those in getcal; hence the `#ifndef lint' directives.) */ -#ifndef lint - if ((this_cle = (struct cle *)malloc(sizeof(struct cle))) == NULL || - (this_cle->sigtype = - (char *)malloc((unsigned)(strlen(p1)+1))) == NULL || - (this_cle->units = - (char *)malloc((unsigned)(strlen(p6)+1))) == NULL) { - if (this_cle) { - if (this_cle->sigtype) free(this_cle->sigtype); - free((char *)this_cle); - } - wfdb_error("calopen: insufficient memory\n"); - (void)wfdb_fclose(cfile); - return (-1); - } -#endif + memory for a calibration list entry. */ + SUALLOC(this_cle, 1, (sizeof(struct cle))); /* Fill in the fields of the new calibration list entry. */ - (void)strcpy(this_cle->sigtype, p1); + SSTRCPY(this_cle->sigtype, p1); if (strcmp(p2, "-") == 0) { this_cle->caltype = WFDB_AC_COUPLED; this_cle->low = 0.0; @@ -145,7 +129,7 @@ this_cle->caltype |= WFDB_CAL_SAWTOOTH; /* otherwise pulse shape is undefined */ this_cle->scale = atof(p5); - (void)strcpy(this_cle->units, p6); + SSTRCPY(this_cle->units, p6); this_cle->next = NULL; /* Append the new entry to the end of the list. */ @@ -191,27 +175,13 @@ the calibration list. */ FINT putcal(WFDB_Calinfo *cal) { -#ifndef lint - if ((this_cle = (struct cle *)malloc(sizeof(struct cle))) == NULL || - (this_cle->sigtype = - (char *)malloc((unsigned)(strlen(cal->sigtype)+1))) == NULL || - (this_cle->units = - (char *)malloc((unsigned)(strlen(cal->units)+1))) == NULL) { - if (this_cle) { - if (this_cle->sigtype) free(this_cle->sigtype); - free((char *)this_cle); - } - wfdb_error("putcal: insufficient memory\n"); - return (-1); - } -#endif - - (void)strcpy(this_cle->sigtype, cal->sigtype); + SUALLOC(this_cle, 1, sizeof(struct cle)); + SSTRCPY(this_cle->sigtype, cal->sigtype); this_cle->caltype = cal->caltype; this_cle->low = cal->low; this_cle->high = cal->high; this_cle->scale = cal->scale; - (void)strcpy(this_cle->units, cal->units); + SSTRCPY(this_cle->units, cal->units); this_cle->next = NULL; if (first_cle) { @@ -268,12 +238,10 @@ FVOID flushcal(void) { while (first_cle) { - free(first_cle->sigtype); - free(first_cle->units); + SFREE(first_cle->sigtype); + SFREE(first_cle->units); this_cle = first_cle->next; -#ifndef lint - free(first_cle); -#endif + SFREE(first_cle); first_cle = this_cle; } } diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/lib/signal.c wfdb-10.4.6/lib/signal.c --- wfdb-10.4.5/lib/signal.c 2008-02-06 11:24:58.000000000 -0500 +++ wfdb-10.4.6/lib/signal.c 2008-04-08 13:31:07.000000000 -0400 @@ -1,5 +1,5 @@ /* file: signal.c G. Moody 13 April 1989 - Last revised: 6 February 2008 wfdblib 10.4.5 + Last revised: 8 April 2008 wfdblib 10.4.6 WFDB library functions for signals _______________________________________________________________________________ @@ -153,7 +153,7 @@ if (n < 1) { /* no signals -- quit or try another record, etc. */ } /* Allocate WFDB_Siginfo structures before calling isigopen again. */ - si = calloc(n, sizeof(WFDB_Siginfo)); + SUALLOC(si, n, sizeof(WFDB_Siginfo)); nsig = isigopen("record", si, n); /* Note that nsig equals n only if all signals were readable. */ @@ -161,7 +161,7 @@ for (i = framelen = 0; i < nsig; i++) framelen += si[i].spf; /* Allocate WFDB_Samples before calling getframe. */ - vector = calloc(framelen, sizeof(WFDB_Sample)); + SUALLOC(vector, framelen, sizeof(WFDB_Sample)); getframe(vector); } #endif @@ -327,20 +327,10 @@ { if (maxisig < n) { unsigned m = maxisig; - struct isdata **isdnew = realloc(isd, n*sizeof(struct isdata *)); - if (isdnew == NULL) { - wfdb_error("init: too many (%d) input signals\n", n); - return (-1); - } - isd = isdnew; + SREALLOC(isd, n, sizeof(struct isdata *)); while (m < n) { - if ((isd[m] = calloc(1, sizeof(struct isdata))) == NULL) { - wfdb_error("init: too many (%d) input signals\n", n); - while (--m > maxisig) - free(isd[m]); - return (-1); - } + SUALLOC(isd[m], 1, sizeof(struct isdata)); m++; } maxisig = n; @@ -353,20 +343,10 @@ { if (maxigroup < n) { unsigned m = maxigroup; - struct igdata **igdnew = realloc(igd, n*sizeof(struct igdata *)); - if (igdnew == NULL) { - wfdb_error("init: too many (%d) input signal groups\n", n); - return (-1); - } - igd = igdnew; + SREALLOC(igd, n, sizeof(struct igdata *)); while (m < n) { - if ((igd[m] = calloc(1, sizeof(struct igdata))) == NULL) { - wfdb_error("init: too many (%d) input signal groups\n", n); - while (--m > maxigroup) - free(igd[m]); - return (-1); - } + SUALLOC(igd[m], 1, sizeof(struct igdata)); m++; } maxigroup = n; @@ -379,20 +359,10 @@ { if (maxosig < n) { unsigned m = maxosig; - struct osdata **osdnew = realloc(osd, n*sizeof(struct osdata *)); - if (osdnew == NULL) { - wfdb_error("init: too many (%d) output signals\n", n); - return (-1); - } - osd = osdnew; + SREALLOC(osd, n, sizeof(struct osdata *)); while (m < n) { - if ((osd[m] = calloc(1, sizeof(struct osdata))) == NULL) { - wfdb_error("init: too many (%d) output signals\n", n); - while (--m > maxosig) - free(osd[m]); - return (-1); - } + SUALLOC(osd[m], 1, sizeof(struct osdata)); m++; } maxosig = n; @@ -405,20 +375,10 @@ { if (maxogroup < n) { unsigned m = maxogroup; - struct ogdata **ogdnew = realloc(ogd, n*sizeof(struct ogdata *)); - if (ogdnew == NULL) { - wfdb_error("init: too many (%d) output signal groups\n", n); - return (-1); - } - ogd = ogdnew; + SREALLOC(ogd, n, sizeof(struct ogdata *)); while (m < n) { - if ((ogd[m] = calloc(1, sizeof(struct ogdata))) == NULL) { - wfdb_error("init: too many (%d) output signal groups\n", n); - while (--m > maxogroup) - free(ogd[m]); - return (-1); - } + SUALLOC(ogd[m], 1, sizeof(struct ogdata)); m++; } maxogroup = n; @@ -440,31 +400,10 @@ { if (to == NULL || from == NULL) return (0); *to = *from; - /* The next line works around an optimizer bug in gcc (version 2.96, maybe - others). */ to->fname = to->desc = to->units = NULL; - if (from->fname) { - to->fname = (char *)malloc((size_t)strlen(from->fname)+1); - if (to->fname == NULL) return (-1); - (void)strcpy(to->fname, from->fname); - } - if (from->desc) { - to->desc = (char *)malloc((size_t)strlen(from->desc)+1); - if (to->desc == NULL) { - (void)free(to->fname); - return (-1); - } - (void)strcpy(to->desc, from->desc); - } - if (from->units) { - to->units = (char *)malloc((size_t)strlen(from->units)+1); - if (to->units == NULL) { - (void)free(to->desc); - (void)free(to->fname); - return (-1); - } - (void)strcpy(to->units, from->units); - } + SSTRCPY(to->fname, from->fname); + SSTRCPY(to->desc, from->desc); + SSTRCPY(to->units, from->units); return (1); } @@ -514,12 +453,11 @@ int i; need_sigmap = nvsig = tspf = 0; - if (ovec) { free(ovec); ovec = NULL; } + SFREE(ovec); if (smi) { for (i = 0; i < tspf; i += smi[i].spf) - if (smi[i].desc) free(smi[i].desc); - free(smi); - smi = NULL; + SFREE(smi[i].desc); + SFREE(smi); } if (vsd) { @@ -527,13 +465,12 @@ while (maxvsig) if (is = vsd[--maxvsig]) { - if (is->info.fname) (void)free(is->info.fname); - if (is->info.units) (void)free(is->info.units); - if (is->info.desc) (void)free(is->info.desc); - (void)free(is); + SFREE(is->info.fname); + SFREE(is->info.units); + SFREE(is->info.desc); + SFREE(is); } - (void)free(vsd); - vsd = NULL; + SFREE(vsd); } } @@ -548,20 +485,10 @@ if (maxvsig < nvsig) { unsigned m = maxvsig; - struct isdata **vsdnew = realloc(vsd, nvsig*sizeof(struct isdata *)); - if (vsdnew == NULL) { - wfdb_error("init: too many (%d) input signals\n", nvsig); - return (-1); - } - vsd = vsdnew; + SREALLOC(vsd, nvsig, sizeof(struct isdata *)); while (m < nvsig) { - if ((vsd[m] = calloc(1, sizeof(struct isdata))) == NULL) { - wfdb_error("init: too many (%d) input signals\n", nvsig); - while (--m > maxvsig) - free(isd[m]); - return (-1); - } + SUALLOC(vsd[m], 1, sizeof(struct isdata)); m++; } maxvsig = nvsig; @@ -587,18 +514,9 @@ nvsig = nisig; for (s = tspf = 0; s < nisig; s++) tspf += isd[s]->info.spf; - if ((smi = malloc(tspf * sizeof(struct sigmapinfo))) == NULL) { - wfdb_error("sigmap_init: out of memory\n"); - return (-1); - } - + SALLOC(smi, tspf, sizeof(struct sigmapinfo)); for (i = s = 0; i < nisig; i++) { - if (smi[s].desc = malloc(strlen(isd[i]->info.desc)+1)) - strcpy(smi[s].desc, isd[i]->info.desc); - else { - wfdb_error("sigmap_init: out of memory\n"); - return (-1); - } + SSTRCPY(smi[s].desc, isd[i]->info.desc); smi[s].gain = isd[i]->info.gain; smi[s].baseline = isd[i]->info.baseline; k = smi[s].spf = isd[i]->info.spf; @@ -606,11 +524,7 @@ smi[s + j] = smi[s]; s += k; } - - if ((ovec = malloc(tspf * sizeof(WFDB_Sample))) == NULL) { - wfdb_error("sigmap_init: out of memory\n"); - return (-1); - } + SALLOC(ovec, tspf, sizeof(WFDB_Sample)); return (make_vsd()); } @@ -729,35 +643,18 @@ /* Allocate workspace. */ if (maxhsig < nsig) { unsigned m = maxhsig; - struct hsdata **hsdnew = realloc(hsd, nsig*sizeof(struct hsdata *)); - if (hsdnew == NULL) { - wfdb_error("init: too many (%d) signals in header file\n", nsig); - return (-2); - } - hsd = hsdnew; + SREALLOC(hsd, nsig, sizeof(struct hsdata *)); while (m < nsig) { - if ((hsd[m] = calloc(1, sizeof(struct hsdata))) == NULL) { - wfdb_error("init: too many (%d) signals in header file\n", - nsig); - while (--m > maxhsig) - free(hsd[m]); - return (-2); - } + SUALLOC(hsd[m], 1, sizeof(struct hsdata)); m++; } maxhsig = nsig; } - if ((dmax = malloc(nsig * sizeof(long))) == NULL || - (dmin = malloc(nsig * sizeof(long))) == NULL || - (pmax = malloc(nsig * sizeof(double))) == NULL || - (pmin = malloc(nsig * sizeof(double))) == NULL) { - wfdb_error("init: too many (%d) signals in header file\n", nsig); - if (pmax) free(pmax); - if (dmin) free(dmin); - if (dmax) free(dmax); - return (-2); - } + SUALLOC(dmax, nsig, sizeof(long)); + SUALLOC(dmin, nsig, sizeof(long)); + SUALLOC(pmax, nsig, sizeof(double)); + SUALLOC(pmin, nsig, sizeof(double)); /* Strip off any path info from the EDF file name. */ p = edf_fname + strlen(edf_fname) - 4; @@ -768,8 +665,7 @@ for (s = 0; s < nsig; s++) { hsd[s]->start = offset; hsd[s]->skew = 0; - if (hsd[s]->info.fname = (char *)malloc(strlen(edf_fname)+1)) - strcpy(hsd[s]->info.fname, edf_fname); + SSTRCPY(hsd[s]->info.fname, edf_fname); hsd[s]->info.group = hsd[s]->info.bsize = hsd[s]->info.cksum = 0; hsd[s]->info.fmt = 16; hsd[s]->info.nsamp = nframes; @@ -778,8 +674,7 @@ junk[16] = ' '; for (i = 16; i >= 0 && junk[i] == ' '; i--) junk[i] = '\0'; - if (hsd[s]->info.desc = (char *)malloc(strlen(junk)+1)) - strcpy(hsd[s]->info.desc, junk); + SSTRCPY(hsd[s]->info.desc, junk); } for (s = 0; s < nsig; s++) @@ -789,8 +684,7 @@ wfdb_fread(buf, 1, 8, ifile); /* signal units */ for (i = 7; i >= 0 && buf[i] == ' '; i--) buf[i] = '\0'; - if (hsd[s]->info.units = (char *)malloc(strlen(buf)+1)) - strcpy(hsd[s]->info.units, buf); + SSTRCPY(hsd[s]->info.units, buf); } for (s = 0; s < nsig; s++) { @@ -852,10 +746,10 @@ hour, minute, second, day, month, year); setbasetime(buf); - free(pmin); - free(pmax); - free(dmin); - free(dmax); + SFREE(pmin); + SFREE(pmax); + SFREE(dmin); + SFREE(dmax); isedf = 1; return (nsig); } @@ -877,10 +771,9 @@ if (in_msrec && vsd) { char *p; - hsd = calloc(1, sizeof(struct hsdata *)); - hsd[0] = calloc(1, sizeof(struct hsdata)); - p = calloc(2, sizeof(char)); *p = '~'; - hsd[0]->info.desc = p; + SALLOC(hsd, 1, sizeof(struct hsdata *)); + SALLOC(hsd[0], 1, sizeof(struct hsdata)); + SSTRCPY(hsd[0]->info.desc, "~"); hsd[0]->info.spf = 1; hsd[0]->info.fmt = 0; hsd[0]->info.nsamp = nsamples = segp->nsamp; @@ -1059,12 +952,7 @@ msbdate = bdate; msnsamples = nsamples; /* Read the names and lengths of the segment records. */ - segarray = (struct segrec *)calloc(segments, sizeof(struct segrec)); - if (segarray == (struct segrec *)NULL) { - wfdb_error("init: insufficient memory\n"); - segments = 0; - return (-2); - } + SALLOC(segarray, segments, sizeof(struct segrec)); segp = segarray; for (i = 0, ns = (WFDB_Time)0L; i < segments; i++, segp++) { /* Get next segment spec, skip empty lines and comments. */ @@ -1073,8 +961,7 @@ wfdb_error( "init: unexpected EOF in header file for record %s\n", record); - (void)free(segarray); - segarray = (struct segrec *)NULL; + SFREE(segarray); segments = 0; return (-2); } @@ -1083,8 +970,7 @@ wfdb_error( "init: `%s' is too long for a segment name in record %s\n", p, record); - (void)free(segarray); - segarray = (struct segrec *)NULL; + SFREE(segarray); segments = 0; return (-2); } @@ -1094,8 +980,7 @@ wfdb_error( "init: length must be specified for segment %s in record %s\n", segp->recname, record); - (void)free(segarray); - segarray = (struct segrec *)NULL; + SFREE(segarray); segments = 0; return (-2); } @@ -1117,21 +1002,10 @@ /* Allocate workspace. */ if (maxhsig < nsig) { unsigned m = maxhsig; - struct hsdata **hsdnew = realloc(hsd, nsig*sizeof(struct hsdata *)); - if (hsdnew == NULL) { - wfdb_error("init: too many (%d) signals in header file\n", nsig); - return (-2); - } - hsd = hsdnew; + SREALLOC(hsd, nsig, sizeof(struct hsdata *)); while (m < nsig) { - if ((hsd[m] = calloc(1, sizeof(struct hsdata))) == NULL) { - wfdb_error("init: too many (%d) signals in header file\n", - nsig); - while (--m > maxhsig) - free(hsd[m]); - return (-2); - } + SUALLOC(hsd[m], 1, sizeof(struct hsdata)); m++; } maxhsig = nsig; @@ -1160,13 +1034,8 @@ match that of the previous signal, the group number is one greater than that of the previous signal. */ if (s == 0 || strcmp(p, hp->info.fname)) { - hs->info.group = (s == 0) ? 0 : hp->info.group + 1; - if ((hs->info.fname =(char *)malloc((unsigned)(strlen(p)+1))) - == NULL) { - wfdb_error("init: insufficient memory\n"); - return (-2); - } - (void)strcpy(hs->info.fname, p); + hs->info.group = (s == 0) ? 0 : hp->info.group + 1; + SSTRCPY(hs->info.fname, p); } /* If the file names of the current and previous signals match, they are assigned the same group number and share a copy of the @@ -1176,12 +1045,7 @@ this has been done. */ else { hs->info.group = hp->info.group; - if ((hs->info.fname = (char *)malloc(strlen(hp->info.fname)+1)) - == NULL) { - wfdb_error("init: insufficient memory\n"); - return (-2); - } - (void)strcpy(hs->info.fname, hp->info.fname); + SSTRCPY(hs->info.fname, hp->info.fname); } /* Determine the signal format. */ @@ -1228,10 +1092,7 @@ break; } if (p && *p) { - if ((hs->info.units=(char *)malloc(WFDB_MAXUSL+1)) == NULL) { - wfdb_error("init: insufficient memory\n"); - return (-2); - } + SALLOC(hs->info.units, WFDB_MAXUSL+1, 1); (void)strncpy(hs->info.units, p, WFDB_MAXUSL); } else @@ -1288,10 +1149,7 @@ /* Get the signal description. If missing, a description of the form "record xx, signal n" is filled in. */ - if ((hs->info.desc = (char *)malloc(WFDB_MAXDSL+1)) == NULL) { - wfdb_error("init: insufficient memory\n"); - return (-2); - } + SALLOC(hs->info.desc, 1, WFDB_MAXDSL+1); if (p = strtok((char *)NULL, "\n\r")) (void)strncpy(hs->info.desc, p, WFDB_MAXDSL); else @@ -1308,13 +1166,12 @@ if (hsd) { while (maxhsig) if (hs = hsd[--maxhsig]) { - if (hs->info.fname) (void)free(hs->info.fname); - if (hs->info.units) (void)free(hs->info.units); - if (hs->info.desc) (void)free(hs->info.desc); - (void)free(hs); + SFREE(hs->info.fname); + SFREE(hs->info.units); + SFREE(hs->info.desc); + SFREE(hs); } - (void)free(hsd); - hsd = NULL; + SFREE(hsd); } maxhsig = 0; } @@ -1326,20 +1183,18 @@ /* if (nisig == 0) return; */ if (sbuf && !in_msrec) { - (void)free(sbuf); - sbuf = NULL; + SFREE(sbuf); sample_vflag = 0; } if (isd) { while (nisig) if (is = isd[--nisig]) { - if (is->info.fname) (void)free(is->info.fname); - if (is->info.units) (void)free(is->info.units); - if (is->info.desc) (void)free(is->info.desc); - (void)free(is); + SFREE(is->info.fname); + SFREE(is->info.units); + SFREE(is->info.desc); + SFREE(is); } - (void)free(isd); - isd = NULL; + SFREE(isd); } else nisig = 0; @@ -1349,11 +1204,10 @@ while (nigroups) if (ig = igd[--nigroups]) { if (ig->fp) (void)wfdb_fclose(ig->fp); - if (ig->buf) (void)free(ig->buf); - (void)free(ig); + SFREE(ig->buf); + SFREE(ig); } - (void)free(igd); - igd = NULL; + SFREE(igd); } else nigroups = 0; @@ -1378,13 +1232,12 @@ if (osd) { while (nosig) if (os = osd[--nosig]) { - if (os->info.fname) (void)free(os->info.fname); - if (os->info.units) (void)free(os->info.units); - if (os->info.desc) (void)free(os->info.desc); - (void)free(os); + SFREE(os->info.fname); + SFREE(os->info.units); + SFREE(os->info.desc); + SFREE(os); } - (void)free(osd); - osd = NULL; + SFREE(osd); } else nosig = 0; @@ -1407,11 +1260,10 @@ og->fp = NULL; } } - if (og->buf) (void)free(og->buf); - (void)free(og); + SFREE(og->buf); + SFREE(og); } - (void)free(ogd); - ogd = NULL; + SFREE(ogd); } else nogroups = 0; @@ -2029,9 +1881,7 @@ if ((ig->bsize = hs->info.bsize) == 0) ig->bsize = ibsize; ig->seek = 1; } - - /* Skip this group if a buffer can't be allocated. */ - if ((ig->buf = (char *)malloc(ig->bsize)) == NULL) continue; + SALLOC(ig->buf, 1, ig->bsize); /* Check that the signal file is readable. */ if (hs->info.fmt == 0) @@ -2040,8 +1890,7 @@ ig->fp = wfdb_open(hs->info.fname, (char *)NULL, WFDB_READ); /* Skip this group if the signal file can't be opened. */ if (ig->fp == NULL) { - (void)free(ig->buf); - ig->buf = NULL; + SFREE(ig->buf); continue; } } @@ -2051,10 +1900,7 @@ ig->start = hs->start; ig->stat = 1; while (si < sj && s < nsig) { - if (copysi(&is->info, &hs->info) < 0) { - wfdb_error("isigopen: insufficient memory\n"); - return (-3); - } + copysi(&is->info, &hs->info); is->info.group = nigroups + g; is->skew = hs->skew; ++s; @@ -2077,10 +1923,8 @@ maximum number of samples per signal per frame and the maximum skew. */ for (si = 0; si < s; si++) { is = isd[nisig + si]; - if (siarray != NULL && copysi(&siarray[si], &is->info) < 0) { - wfdb_error("isigopen: insufficient memory\n"); - return (-3); - } + if (siarray) + copysi(&siarray[si], &is->info); is->samp = is->info.initval; if (ispfmax < is->info.spf) ispfmax = is->info.spf; if (skewmax < is->skew) skewmax = is->skew; @@ -2098,12 +1942,9 @@ framelen += isd[si]->info.spf; /* Allocate workspace for getvec and isgsettime. */ - if (framelen > tuvlen && - ((tvector = realloc(tvector, sizeof(WFDB_Sample)*framelen)) == NULL || - (uvector = realloc(uvector, sizeof(WFDB_Sample)*framelen)) == NULL)) { - wfdb_error("isigopen: can't allocate frame buffer\n"); - if (tvector) (void)free(tvector); - return (-3); + if (framelen > tuvlen) { + SREALLOC(tvector, framelen, sizeof(WFDB_Sample)); + SREALLOC(uvector, framelen, sizeof(WFDB_Sample)); } tuvlen = framelen; @@ -2112,11 +1953,7 @@ if (skewmax != 0 && (!in_msrec || dsbuf == NULL)) { dsbi = -1; /* mark buffer contents as invalid */ dsblen = framelen * (skewmax + 1); - if (dsbuf) free(dsbuf); - if ((dsbuf=(WFDB_Sample *)malloc(dsblen*sizeof(WFDB_Sample))) == NULL) - wfdb_error("isigopen: can't allocate buffer for deskewing\n"); - /* If the buffer couldn't be allocated, the signals can still be read, - but won't be deskewed. */ + SALLOC(dsbuf, dsblen, sizeof(WFDB_Sample)); } return (s); } @@ -2163,11 +2000,8 @@ os = osd[nosig]; /* Copy signal information from readheader's workspace. */ - if (copysi(&os->info, &hsd[s]->info) < 0 || - copysi(siarray, &hsd[s]->info) < 0) { - wfdb_error("osigopen: insufficient memory\n"); - return (-3); - } + copysi(&os->info, &hsd[s]->info); + copysi(siarray, &hsd[s]->info); if (os->info.spf < 1) os->info.spf = siarray->spf = 1; os->info.cksum = siarray->cksum = 0; os->info.nsamp = siarray->nsamp = (WFDB_Time)0L; @@ -2180,11 +2014,7 @@ og = ogd[os->info.group]; og->bsize = os->info.bsize; obuflen = og->bsize ? og->bsize : obsize; - if ((og->buf = (char *)malloc(obuflen)) == NULL) { - wfdb_error("osigopen: can't allocate buffer for %s\n", - os->info.fname); - return (-3); - } + SALLOC(og->buf, 1, obuflen); og->bp = og->buf; og->be = og->buf + obuflen; if (os->info.fmt == 0) @@ -2194,8 +2024,7 @@ og->fp = wfdb_open(os->info.fname,(char *)NULL, WFDB_WRITE); if (og->fp == NULL) { wfdb_error("osigopen: can't open %s\n", os->info.fname); - free(og->buf); - og->buf = NULL; + SFREE(og->buf); osigclose(); return (-3); } @@ -2290,10 +2119,7 @@ } /* Copy signal information from the caller's array. */ - if (copysi(&os->info, siarray) < 0) { - wfdb_error("osigfopen: insufficient memory\n"); - return (-3); - } + copysi(&os->info, siarray); if (os->info.spf < 1) os->info.spf = 1; os->info.cksum = 0; os->info.nsamp = (WFDB_Time)0L; @@ -2306,11 +2132,7 @@ og->bsize = os->info.bsize; obuflen = og->bsize ? og->bsize : obsize; /* This is the first signal in a new group; allocate buffer. */ - if ((og->buf = (char *)malloc(obuflen)) == NULL) { - wfdb_error("osigfopen: can't allocate buffer for %s\n", - os->info.fname); - return (-3); - } + SALLOC(og->buf, 1,obuflen); og->bp = og->buf; og->be = og->buf + obuflen; if (os->info.fmt == 0) @@ -2320,8 +2142,7 @@ og->fp = wfdb_open(os->info.fname,(char *)NULL, WFDB_WRITE); if (og->fp == NULL) { wfdb_error("osigfopen: can't open %s\n", os->info.fname); - free(og->buf); - og->buf = NULL; + SFREE(og->buf); osigclose(); return (-3); } @@ -2406,14 +2227,8 @@ if (f > 0.0) { WFDB_Frequency error, g = sfreq; - gv0 = realloc(gv0, nisig*sizeof(WFDB_Sample)); - gv1 = realloc(gv1, nisig*sizeof(WFDB_Sample)); - if (gv0 == NULL || gv1 == NULL) { - wfdb_error("setifreq: too many (%d) input signals\n", nisig); - if (gv0) (void)free(gv0); - ifreq = 0.0; - return (-2); - } + SREALLOC(gv0, nisig, sizeof(WFDB_Sample)); + SREALLOC(gv1, nisig, sizeof(WFDB_Sample)); setafreq(ifreq = f); /* The 0.005 below is the maximum tolerable error in the resampling frequency (in Hz). The code in the while loop implements Euclid's @@ -2671,22 +2486,16 @@ /* Remove trailing .hea, if any, from record name. */ wfdb_striphea(record); - if ((osi = malloc(nosig*sizeof(WFDB_Siginfo))) == NULL) { - wfdb_error("newheader: insufficient memory\n"); - return (-1); - } + SUALLOC(osi, nosig, sizeof(WFDB_Siginfo)); for (s = 0; s < nosig; s++) - if (copysi(&osi[s], &osd[s]->info) < 0) { - wfdb_error("newheader: insufficient memory\n"); - return (-1); - } + copysi(&osi[s], &osd[s]->info); stat = setheader(record, osi, nosig); for (s = 0; s < nosig; s++) { - if (osi[s].fname) (void)free(osi[s].fname); - if (osi[s].desc) (void)free(osi[s].desc); - if (osi[s].units) (void)free(osi[s].units); + SFREE(osi[s].fname); + SFREE(osi[s].desc); + SFREE(osi[s].units); } - (void)free(osi); + SFREE(osi); return (stat); } @@ -2793,17 +2602,13 @@ return (-1); } - if ((ns = (long *)malloc((unsigned)(sizeof(long)*nsegments))) == NULL) { - wfdb_error("setmsheader: insufficient memory\n"); - return (-2); - } - + SUALLOC(ns, nsegments, (sizeof(long)*nsegments)); for (i = 0; i < nsegments; i++) { if (strlen(segment_name[i]) > WFDB_MAXRNL) { wfdb_error( "setmsheader: `%s' is too long for a segment name in record %s\n", segment_name[i], record); - (void)free(ns); + SFREE(ns); return (-2); } in_msrec = 1; @@ -2812,13 +2617,13 @@ if (n < 0) { wfdb_error("setmsheader: can't read segment %s header\n", segment_name[i]); - (void)free(ns); + SFREE(ns); return (-3); } if ((ns[i] = hsd[0]->info.nsamp) <= 0L) { wfdb_error("setmsheader: length of segment %s must be specified\n", segment_name[i]); - (void)free(ns); + SFREE(ns); return (-4); } if (i == 0) { @@ -2835,14 +2640,14 @@ wfdb_error( "setmsheader: incorrect number of signals in segment %s\n", segment_name[i]); - (void)free(ns); + SFREE(ns); return (-4); } if (msfreq != ffreq) { wfdb_error( "setmsheader: incorrect sampling frequency in segment %s\n", segment_name[i]); - (void)free(ns); + SFREE(ns); return (-4); } msnsamples += ns[i]; @@ -2853,7 +2658,7 @@ if ((oheader = wfdb_open("hea", record, WFDB_WRITE)) == NULL) { wfdb_error("setmsheader: can't create header file for record %s\n", record); - (void)free(ns); + SFREE(ns); return (-1); } @@ -2881,7 +2686,7 @@ for (i = 0; i < nsegments; i++) (void)wfdb_fprintf(oheader, "%s %ld\r\n", segment_name[i], ns[i]); - (void)free(ns); + SFREE(ns); return (0); } @@ -3313,12 +3118,8 @@ /* Allocate the sample buffer on the first call. */ if (sbuf == NULL) { - sbuf= (WFDB_Sample *)malloc((unsigned)nisig*BUFLN*sizeof(WFDB_Sample)); - if (sbuf) tt = (WFDB_Time)-1L; - else { - (void)fprintf(stderr, "sample(): insufficient memory\n"); - exit(2); - } + SALLOC(sbuf, nisig, BUFLN*sizeof(WFDB_Sample)); + tt = (WFDB_Time)-1L; } /* If the caller requested a sample from an unavailable signal, return @@ -3374,8 +3175,7 @@ void wfdb_sampquit(void) { if (sbuf) { - (void)free(sbuf); - sbuf = NULL; + SFREE(sbuf); sample_vflag = 0; } } @@ -3389,32 +3189,25 @@ pdays = (WFDB_Date)-1; segments = in_msrec = skewmax = 0; if (dsbuf) { - (void)free(dsbuf); - dsbuf = NULL; + SFREE(dsbuf); dsbi = -1; } if (segarray) { int i; - (void)free(segarray); - segarray = segp = segend = (struct segrec *)NULL; + SFREE(segarray); + segp = segend = (struct segrec *)NULL; for (i = 0; i < maxisig; i++) { - if (isd[i]->info.desc) { - (void)free(isd[i]->info.desc); - isd[i]->info.desc = NULL; - } - if (isd[i]->info.units) { - (void)free(isd[i]->info.units); - isd[i]->info.units = NULL; - } + SFREE(isd[i]->info.fname); /* missing before 10.4.6 */ + SFREE(isd[i]->info.desc); + SFREE(isd[i]->info.units); } } - if (gv0) (void)free(gv0); - if (gv1) (void)free(gv1); - if (tvector) (void)free(tvector); - if (uvector) (void)free(uvector); + SFREE(gv0); + SFREE(gv1); + SFREE(tvector); + SFREE(uvector); tuvlen = 0; - gv0 = gv1 = tvector = uvector = NULL; sigmap_cleanup(); } diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/lib/wfdb.h0 wfdb-10.4.6/lib/wfdb.h0 --- wfdb-10.4.5/lib/wfdb.h0 2008-01-11 13:03:57.000000000 -0500 +++ wfdb-10.4.6/lib/wfdb.h0 2008-02-08 10:33:17.000000000 -0500 @@ -1,5 +1,5 @@ /* file: wfdb.h G. Moody 13 June 1983 - Last revised: 11 January 2008 wfdblib 10.4.5 + Last revised: 8 February 2008 wfdblib 10.4.6 WFDB library type, constant, structure, and function interface definitions _______________________________________________________________________________ @@ -33,7 +33,7 @@ /* WFDB library version. */ #define WFDB_MAJOR 10 #define WFDB_MINOR 4 -#define WFDB_RELEASE 5 +#define WFDB_RELEASE 6 #define WFDB_NETFILES 1 /* if 1, library includes code for HTTP, FTP clients */ #define WFDB_NETFILES_LIBCURL 1 diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/lib/wfdbio.c wfdb-10.4.6/lib/wfdbio.c --- wfdb-10.4.5/lib/wfdbio.c 2008-01-11 13:52:52.000000000 -0500 +++ wfdb-10.4.6/lib/wfdbio.c 2008-04-08 16:56:36.000000000 -0400 @@ -1,5 +1,5 @@ /* file: wfdbio.c G. Moody 18 November 1988 - Last revised: 11 January 2008 wfdblib 10.4.5 + Last revised: 8 April 2008 wfdblib 10.4.6 Low-level I/O functions for the WFDB library _______________________________________________________________________________ @@ -37,9 +37,12 @@ wfdbverbose [4.0] (enables WFDB library error messages) wfdberror [4.5] (returns the most recent WFDB library error message) wfdbfile [4.3] (returns the complete pathname of a WFDB file) + wfdbmemerr [10.4.6] (set behavior on memory errors) These functions, also defined here, are intended only for the use of WFDB library functions defined elsewhere: + + wfdb_me_fatal [10.4.6] (indicates if memory errors are fatal) wfdb_g16 (reads a 16-bit integer) wfdb_g32 (reads a 32-bit integer) wfdb_p16 (writes a 16-bit integer) @@ -181,9 +184,7 @@ if (p == NULL && (p = getenv("WFDB")) == NULL) p = DEFWFDB; wfdb_parse_path(p); - if (wfdbpath) free(wfdbpath); - if (wfdbpath = (char *)malloc(strlen(p)+1)) - strcpy(wfdbpath, p); + SSTRCPY(wfdbpath, p); wfdb_export_config(); } @@ -225,8 +226,24 @@ else return (NULL); } +/* Determine how the WFDB library handles memory allocation errors (running +out of memory). Call wfdbmemerr(0) in order to have these errors returned +to the caller; by default, such errors cause the running process to exit. */ + +static int wfdb_mem_behavior = 1; + +FVOID wfdbmemerr(int behavior) +{ + wfdb_mem_behavior = behavior; +} + /* Private functions (for the use of other WFDB library functions only). */ +int wfdb_me_fatal() /* used by the MEMERR macro defined in wfdblib.h */ +{ + return (wfdb_mem_behavior); +} + /* The next four functions read and write integers in PDP-11 format, which is common to both MIT and AHA database files. The purpose is to achieve interchangeability of binary database files between machines which may use @@ -290,8 +307,8 @@ while (c1) { c0 = c1->next; - if (c1->prefix) (void)free(c1->prefix); - (void)free(c1); + SFREE(c1->prefix); + SFREE(c1); c1 = c0; } wfdb_path_list = NULL; @@ -432,12 +449,8 @@ } while (!found_end); /* current component begins at p, ends at q-1 */ - if ((c1 = calloc(1, sizeof(struct wfdb_path_component))) == NULL || - (c1->prefix = calloc(q-p+1, sizeof(char))) == NULL) { - wfdb_error("wfdb_parse_path: insufficient memory\n"); - if (c1) (void)free(c1); - return (-1); - } + SUALLOC(c1, 1, sizeof(struct wfdb_path_component)); + SALLOC(c1->prefix, q-p+1, sizeof(char)); memcpy(c1->prefix, p, q-p); c1->type = current_type; if (c0) c0->next = c1; @@ -474,13 +487,11 @@ if (fseek(wfdbpfile, 0L, SEEK_END) == 0) len = ftell(wfdbpfile); else len = 255; - if ((p = (char *)malloc((unsigned)len+1)) == NULL) p = ""; - else { - rewind(wfdbpfile); - len = fread(p, 1, (int)len, wfdbpfile); - while (p[len-1] == '\n' || p[len-1] == '\r') - p[--len] = '\0'; - } + SUALLOC(p, 1, len+1); + rewind(wfdbpfile); + len = fread(p, 1, (int)len, wfdbpfile); + while (p[len-1] == '\n' || p[len-1] == '\r') + p[--len] = '\0'; (void)fclose(wfdbpfile); } } @@ -501,28 +512,25 @@ { char *p; - if (p = (char *)malloc(strlen(wfdbpath)+6)) { - sprintf(p, "WFDB=%s", wfdbpath); - putenv(p); - free(p); - } + SUALLOC(p, 1, strlen(wfdbpath)+6); + sprintf(p, "WFDB=%s", wfdbpath); + putenv(p); if (getenv("WFDBCAL") == NULL) { - if (p = malloc(strlen(DEFWFDBCAL)+9)) { - sprintf(p, "WFDBCAL=%s", DEFWFDBCAL); - putenv(p); - free(p); - } + SALLOC(p, 1, strlen(DEFWFDBCAL)+9); + sprintf(p, "WFDBCAL=%s", DEFWFDBCAL); + putenv(p); } if (getenv("WFDBANNSORT") == NULL) { - static char p[14]; + SALLOC(p, 1, 14); sprintf(p, "WFDBANNSORT=%d", DEFWFDBANNSORT == 0 ? 0 : 1); putenv(p); } if (getenv("WFDBGVMODE") == NULL) { - static char p[13]; + SALLOC(p, 1, 13); sprintf(p, "WFDBGVMODE=%d", DEFWFDBGVMODE == 0 ? 0 : 1); putenv(p); } + SFREE(p); } #endif @@ -572,16 +580,13 @@ /* If we've come this far, the path component of s was not found in the current WFDB path; now append it. */ len = strlen(wfdbpath); /* wfdbpath set by getwfdb() -- see above */ - if ((t = (char *)malloc((unsigned)(len + i + 2))) == NULL) { - wfdb_error("wfdb_addtopath: insufficient memory\n"); - return; /* WFDB path is unchanged */ - } + SUALLOC(t, 1, len + i + 2); (void)strcpy(t, wfdbpath); t[len++] = PSEP; /* append a path separator */ (void)strncpy(t+len, s, i); /* append the new path component */ t[len+i] = '\0'; setwfdb(t); - free(t); + SFREE(t); } /* The wfdb_error function handles error messages, normally by printing them @@ -1042,16 +1047,11 @@ { char *libcurl_ver; static char *s = NULL; - if (s) { - free(s); - s = NULL; - } + libcurl_ver = curl_version(); - s = malloc(32 + strlen(libcurl_ver)); - if (s) { - sprintf(s, "libwfdb/%d.%d.%d (%s)", WFDB_MAJOR, WFDB_MINOR, + SALLOC(s, 1, 32 + strlen(libcurl_ver)); + sprintf(s, "libwfdb/%d.%d.%d (%s)", WFDB_MAJOR, WFDB_MINOR, WFDB_RELEASE, libcurl_ver); - } return (s); } @@ -1233,16 +1233,10 @@ /* Create a new, empty chunk. */ static CHUNK *curl_chunk_new(long len) { - struct chunk *c = malloc(sizeof(struct chunk)); - if (!c) { - wfdb_error("curl_chunk_new: not enough memory\n"); - return NULL; - } - if (!(c->data = malloc(len))) { - wfdb_error("curl_chunk_new: not enough memory\n"); - free(c); - return NULL; - } + struct chunk *c; + + SUALLOC(c, 1, sizeof(struct chunk)); + SALLOC(c->data, 1, len); c->size = 0L; c->buffer_size = len; return c; @@ -1252,9 +1246,8 @@ static void curl_chunk_delete(struct chunk *c) { if (c) { - if (c->data) - free(c->data); - free(c); + SFREE(c->data); + SFREE(c); } } @@ -1267,19 +1260,13 @@ { size_t count=0; char *p; - struct chunk *c = (struct chunk *) stream; + while (nmemb > 0) { while ((c->size + size) > c->buffer_size) { c->buffer_size += 1024; - if (p = realloc(c->data, c->buffer_size)) - c->data = p; - else { - wfdb_error("curl_chunk_write: insufficient memory\n"); - return (count); - } + SREALLOC(c->data, 1, c->buffer_size); } - memcpy(c->data + c->size, ptr, size); c->size += size; count += size; @@ -1475,9 +1462,9 @@ static void nf_delete(netfile *nf) { if (nf) { - if (nf->url) free(nf->url); - if (nf->data) free(nf->data); - free(nf); + SFREE(nf->url); + SFREE(nf->data); + SFREE(nf); } } @@ -1498,17 +1485,15 @@ to do this would be to invoke HTLoadToFile(url, request, filename); */ -static netfile* nf_new(const char* url) +static netfile *nf_new(const char* url) { - netfile* nf = NULL; - CHUNK* chunk = NULL; + netfile *nf; + CHUNK *chunk = NULL; long bytes_received = 0L; - nf = malloc(sizeof(netfile)); - + SUALLOC(nf, 1, sizeof(netfile)); if (nf && url && *url) { - nf->url = calloc(strlen(url) + 1, sizeof(char)); - strcpy(nf->url, url); + SSTRCPY(nf->url, url); nf->base_addr = 0; nf->pos = 0; nf->data = NULL; @@ -1535,9 +1520,10 @@ nf->mode = NF_FULL_MODE; bytes_received = nf->cont_len = chunk_size(chunk); } - if (bytes_received > 0L && - (nf->data = calloc(bytes_received, sizeof(char)))) - memcpy(nf->data, chunk_data(chunk), bytes_received); + if (bytes_received > 0L) { + SALLOC(nf->data, bytes_received, sizeof(char)); + memcpy(nf->data, chunk_data(chunk), bytes_received); + } if (nf->data == NULL) { if (bytes_received > 0L) wfdb_error("nf_new: insufficient memory (needed %ld bytes)\n", @@ -1855,19 +1841,16 @@ status = fclose(wp->fp); #endif if (wp->fp != stdin) - (void)free(wp); + SFREE(wp); return (status); } WFDB_FILE *wfdb_fopen(char *fname, const char *mode) { char *p = fname; - WFDB_FILE *wp = (WFDB_FILE *)malloc(sizeof(WFDB_FILE)); + WFDB_FILE *wp; - if (wp == NULL) { - wfdb_error("wfdb_fopen: out of memory\n"); - return (NULL); - } + SUALLOC(wp, 1, sizeof(WFDB_FILE)); while (*p) if (*p++ == ':' && *p++ == '/' && *p++ == '/') { #if WFDB_NETFILES @@ -1876,7 +1859,7 @@ return (wp); } #endif - free(wp); + SFREE(wp); return (NULL); } if (wp->fp = fopen(fname, mode)) { @@ -1909,7 +1892,7 @@ return (wp); } } - free(wp); + SFREE(wp); return (NULL); } diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/lib/wfdblib.h0 wfdb-10.4.6/lib/wfdblib.h0 --- wfdb-10.4.5/lib/wfdblib.h0 2008-01-11 13:14:01.000000000 -0500 +++ wfdb-10.4.6/lib/wfdblib.h0 2008-04-08 17:28:52.000000000 -0400 @@ -1,5 +1,5 @@ /* file: wfdblib.h G. Moody 13 April 1989 - Last revised: 11 January 2008 wfdblib 10.4.5 + Last revised: 8 April 2008 wfdblib 10.4.6 External definitions for WFDB library private functions _______________________________________________________________________________ @@ -200,6 +200,18 @@ #define FALSE 0 #endif +/* Dynamic memory allocation macros for the WFDB library. */ +#define MEMERR(P, N, S) \ + { wfdb_error("WFDB: can't allocate (%ld*%ld) bytes for %s\n", \ + (size_t)N, (size_t)S, #P); \ + if (wfdb_me_fatal()) exit(1); } +#define SFREE(P) { if (P) { free (P); P = 0; } } +#define SUALLOC(P, N, S) { if (!(P = calloc((N), (S)))) MEMERR(P, (N), (S)); } +#define SALLOC(P, N, S) { SFREE(P); SUALLOC(P, (N), (S)) } +#define SREALLOC(P, N, S) { if (!(P = realloc(P, (N)*(S)))) MEMERR(P,(N),(S)); } +#define SSTRCPY(P, Q) { if (Q) { \ + SALLOC(P, (size_t)strlen(Q)+1,1); strcpy(P, Q); } } + /* Structures used by internal WFDB library functions only */ struct netfile { char *url; diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/MANIFEST wfdb-10.4.6/MANIFEST --- wfdb-10.4.5/MANIFEST 2006-05-11 15:18:15.000000000 -0400 +++ wfdb-10.4.6/MANIFEST 2008-04-09 18:18:37.000000000 -0400 @@ -32,6 +32,8 @@ app/setwfdb app/sigamp.c app/sigavg.c +app/signame.c +app/signum.c app/skewedit.c app/snip.c app/sortann.c @@ -158,6 +160,7 @@ convert/md2a.c convert/mit2edf.c convert/mit2wav.c +convert/rdedfann.c convert/readid.c convert/README convert/revise.c @@ -303,6 +306,7 @@ doc/wag-src/pschart.1 doc/wag-src/psfd.1 doc/wag-src/rdann.1 +doc/wag-src/rdedfann.1 doc/wag-src/rdsamp.1 doc/wag-src/README doc/wag-src/rxr.1 @@ -311,6 +315,8 @@ doc/wag-src/sigamp.1 doc/wag-src/sigavg.1 doc/wag-src/signal.5 +doc/wag-src/signame.1 +doc/wag-src/signum.1 doc/wag-src/skewedit.1 doc/wag-src/snip.1 doc/wag-src/sortann.1 diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/NEWS wfdb-10.4.6/NEWS --- wfdb-10.4.5/NEWS 2008-02-06 11:57:05.000000000 -0500 +++ wfdb-10.4.6/NEWS 2008-04-09 15:49:23.000000000 -0400 @@ -1,3 +1,51 @@ +10.4.6: + The WFDB functions setafreq() and getafreq() (for setting and getting + the time resolution of newly-created output annotation files in ticks + per second) were new in version 10.4.5, but were undocumented. They + are now described in the WFDB Programmer's Guide, and wrappers for + these functions are now included in fortran/wfdbf.c. + + An important change in the WFDB library: memory allocation errors are + now treated as fatal by default (in previous versions, the functions + that encountered them returned error values that permitted the + application to handle them). These errors occur when there is + insufficient memory available to the WFDB library. After invoking + wfdbmemerr(0), if such an error occurs, the function in which it + occurs will continue if possible. By default, however, such an + error will cause the process to terminate. In either case, the WFDB + library emits an appropriate error message to aid in troubleshooting. + + New macros for handling dynamically allocated memory are defined in + lib/wfdblib.h and used throughout the WFDB library, eliminating most + known memory leaks. Three known leaks remain (in setecgstr, setannstr, + and setanndesc); these are documented and harmless in current + applications. Thanks to Yinqi Zhang for reporting a leak in copysi() + (an internal WFDB library function defined in signal.c), which prompted + the cleanup. + + WFDB functions strecg(), setecgstr(), strann(), setannstr(), and + setanndesc() now handle NULL string inputs properly. (Previous versions + passed NULL strings to strcmp(), with undesirable results.) + + A pair of new utility applications, signame and signum, convert signal + numbers to signal names and vice versa. + + A new format converter, rdedfann, is included in convert/. It extracts + annotations from EDF+ files and writes them to the standard output in + rdann output format. After changing the EDF+ annotation mnemonics + to WFDB mnemonics (using your favorite scripting language, such as + perl or sed), wrann can then write a WFDB-compatible annotation file + from the transformed text. + + wrann now works when creating annotation files for EDF and other + multifrequency records. The incompatibility between rdann's -x + format and wrann has now been noted in the rdann and wrann man pages. + + rxr did not account properly for runs that are not followed by at + least one beat annotation (common in the cudb). Shibu Kallidukkil + supplied an example that evoked this problem, which has now been + corrected. + 10.4.5: Bob Farrell and Tony Ricke chased down and provided fixes for memory leaks in several WFDB library functions, and also provided revisions diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/wave/annot.c wfdb-10.4.6/wave/annot.c --- wfdb-10.4.5/wave/annot.c 2005-06-10 10:33:55.000000000 -0400 +++ wfdb-10.4.6/wave/annot.c 2008-03-14 15:49:18.000000000 -0400 @@ -1,10 +1,10 @@ /* file: annot.c G. Moody 1 May 1990 - Last revised: 10 June 2005 + Last revised: 14 March 2008 Annotation list handling and display functions for WAVE ------------------------------------------------------------------------------- WAVE: Waveform analyzer, viewer, and editor -Copyright (C) 1990-2005 George B. Moody +Copyright (C) 1990-2008 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -152,11 +152,13 @@ tupdate = time((time_t *)NULL); /* Return 0 if no annotations are requested or available. */ + setafreq(freq); if (nann < 1 || annopen(record, &af, 1) < 0) { ap_start = annp = scope_annp = NULL; if (frame) xv_set(frame, FRAME_BUSY, FALSE, NULL); return (annotations = 0); } + setafreq(freq); if ((ap_start = annp = scope_annp = a = get_ap()) == NULL || getann(0, &(a->this))) { (void)annopen(record, NULL, 0); @@ -956,6 +958,7 @@ } af.stat = (af.stat == WFDB_AHA_READ) ? WFDB_AHA_WRITE : WFDB_WRITE; + setafreq(freq); if (annopen(record, &af, 1)) { /* An error from annopen is most likely to result from not being able to create the output file. Warn the user and try again later. */ @@ -1029,6 +1032,7 @@ } a = a->next; } + setafreq(freq); (void)annopen(record, NULL, 0); /* force flush and close of output */ changes = 0; diff -Naur --exclude Makefile --exclude info wfdb-10.4.5/wave/init.c wfdb-10.4.6/wave/init.c --- wfdb-10.4.5/wave/init.c 2005-08-05 12:02:17.000000000 -0400 +++ wfdb-10.4.6/wave/init.c 2008-03-14 14:20:30.000000000 -0400 @@ -1,10 +1,10 @@ /* file: init.c G. Moody 1 May 1990 - Last revised: 5 August 2005 + Last revised: 14 March 2008 Initialization functions for WAVE ------------------------------------------------------------------------------- WAVE: Waveform analyzer, viewer, and editor -Copyright (C) 1990-2005 George B. Moody +Copyright (C) 1990-2008 George B. Moody This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -145,6 +145,7 @@ if the value were WFDB_DEFFREQ (from wfdb.h); the units are samples per second per signal. */ if (nsig < 0 || (freq = sampfreq(NULL)) <= 0.) freq = WFDB_DEFFREQ; + setifreq(freq); /* Quit if isigopen failed. */ if (nsig < 0)