diff -Naur '--exclude=Makefile' wfdb-10.5.24/Makefile.tpl wfdb-10.6.0/Makefile.tpl --- wfdb-10.5.24/Makefile.tpl 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/Makefile.tpl 2017-03-09 18:13:18.000000000 -0500 @@ -1,23 +1,24 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 26 August 2014 +# Last revised: 8 March 2017 # This section of the Makefile should not need to be changed. # 'make' or 'make all': compile the WFDB applications without installing them all: config.cache - $(MAKE) WFDBROOT=`pwd`/build LIBDIR=`pwd`/build/lib install check + $(MAKE) WFDBROOT=`pwd`/build LIBDIR=`pwd`/build/lib install + $(MAKE) WFDBROOT=`pwd`/build LIBDIR=`pwd`/build/lib check # 'make install': compile and install the WFDB software package install: config.cache - cd lib; $(MAKE) clean install - cd app; $(MAKE) clean install - cd convert; $(MAKE) clean install - cd data; $(MAKE) clean install - cd fortran; $(MAKE) clean install - cd psd; $(MAKE) clean install - -( cd wave; $(MAKE) clean install ) - cd waverc; $(MAKE) clean install - -( cd xml; $(MAKE) clean install ) - test -d doc && ( cd doc; $(MAKE) clean install ) + cd lib; $(MAKE) clean; $(MAKE) install + cd app; $(MAKE) clean; $(MAKE) install + cd convert; $(MAKE) clean; $(MAKE) install + cd data; $(MAKE) clean; $(MAKE) install + cd fortran; $(MAKE) clean; $(MAKE) install + cd psd; $(MAKE) clean; $(MAKE) install + cd wave; $(MAKE) clean; $(MAKE) install + cd waverc; $(MAKE) clean; $(MAKE) install + -( cd xml; $(MAKE) clean; $(MAKE) install ) + test -d doc && ( cd doc; $(MAKE) clean; $(MAKE) install ) # 'make collect': collect the installed files into /tmp/wfdb/ collect: @@ -27,7 +28,7 @@ cd data; $(MAKE) collect cd fortran; $(MAKE) collect cd psd; $(MAKE) collect - -( cd wave; $(MAKE) collect ) + cd wave; $(MAKE) collect cd waverc; $(MAKE) collect -( cd xml; $(MAKE) collect ) test -d doc && ( cd doc; $(MAKE) collect ) @@ -43,7 +44,7 @@ cd waverc; $(MAKE) uninstall cd xml; $(MAKE) uninstall test -d doc && ( cd doc; $(MAKE) uninstall ) - ./uninstall.sh $(WFDBROOT) + ./uninstall.sh $(DESTDIR)$(WFDBROOT) # 'make clean': remove binaries, other cruft from source directories clean: diff -Naur '--exclude=Makefile' wfdb-10.5.24/NEWS wfdb-10.6.0/NEWS --- wfdb-10.5.24/NEWS 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/NEWS 2018-01-26 16:43:40.000000000 -0500 @@ -1,3 +1,61 @@ +10.6.0 (26 January 2018): + A wide variety of bugs have been fixed in the WFDB library, and several + new features have been added. See the WFDB Programmer's Guide for + details. In particular, the library returns more accurate results when + reading a multi-segment record or an EDF file; many WFDB applications + may produce different output as a result. + + The WFDB library now supports reading variable-layout, multi-frequency + records, provided that each signal's sampling frequency is constant + across the entire record. + + 'sortann' and 'mrgann' preserve the original time resolution of their + input files, and 'rdann' displays the elapsed time with higher + precision, if possible. + + 'wfdb2mat' uses the "version 5" format instead of "version 4". It + displays the correct instructions for computing physical values, in the + case of an 8-bit data file. + + 'mrgann' correctly interprets the argument to the first '-mX' option, if + any. + + 'xform' correctly computes the lower limit of the output ADC range. + This will result in different output if the '-c' option is used and the + signals are clipped. + + 'psfd' and 'pschart' correctly handle custom annotation mnemonics that + include parentheses or backslashes. + + WAVE sets the X resource 'OpenWindows.SelectDisplaysMenu' to 'true' by + default, so that the left mouse button will do what users normally + expect it to do. If you prefer the traditional XView behavior, you can + set this to 'false' in your .Xdefaults or .Xresources. + + WAVE permits viewing records at finer time scales, up to 500 mm/ms. + + In some circumstances, when jumping to the beginning of a record in + WAVE, the signals would mysteriously disappear. This was most apparent + with very short records; it has now been fixed. + + Some systems (particulary those based on systemd) allow programs to open + a larger range of file descriptors than what the C select() function + accepts. This causes older versions of the XView library to crash. + WAVE now works around this bug. + + Changes in 'configure' and the various '.def' files make it simpler to + cross-compile WFDB using the GNU toolchain. Further improvements to the + makefiles permit parallel compilation (when using the -j option of GNU + make) and permit installation into a temporary staging directory (using + the DESTDIR variable.) + + The 'install-wave32' script has been updated to work on current versions + of Fedora and Scientific Linux. + + Now that all of PhysioNet is accessible using secure HTTPS, the + 'pnwlogin' script has been updated to use HTTPS for all remote file + access (PhysioBank as well as PhysioNetWorks.) + 10.5.24 (28 May 2015): A security flaw was found in the 'pnwlogin' script used to access PhysioNetWorks projects, owing to a combination of bugs in WFDB and diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/Makefile.tpl wfdb-10.6.0/app/Makefile.tpl --- wfdb-10.5.24/app/Makefile.tpl 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/Makefile.tpl 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 23 May 2000 -# Last revised: 28 February 2014 +# Last revised: 8 March 2017 # This section of the Makefile should not need to be changed. CFILES = ann2rr.c bxb.c calsig.c ecgeval.c epicmp.c fir.c gqfuse.c gqpost.c \ @@ -33,14 +33,14 @@ $(STRIP) $(XFILES) # `make' or `make install': build and install applications -install: all $(BINDIR) $(PSPDIR) scripts +install: all $(DESTDIR)$(BINDIR) $(DESTDIR)$(PSPDIR) scripts rm -f pschart psfd pschart.exe psfd.exe $(MAKE) pschart psfd # be sure compiled-in paths are up-to-date $(STRIP) pschart psfd $(SETXPERMISSIONS) $(XFILES) - ../install.sh $(BINDIR) $(XFILES) - cp $(PSFILES) $(PSPDIR) - cd $(PSPDIR); $(SETPERMISSIONS) $(PSFILES) + ../install.sh $(DESTDIR)$(BINDIR) $(XFILES) + cp $(PSFILES) $(DESTDIR)$(PSPDIR) + cd $(DESTDIR)$(PSPDIR); $(SETPERMISSIONS) $(PSFILES) # 'make collect': retrieve the installed applications collect: @@ -48,22 +48,24 @@ ../conf/collect.sh $(PSPDIR) $(PSFILES) # `make scripts': install customized scripts for setting WFDB path -scripts: - sed s+/usr/local/database+$(DBDIR)+g $(BINDIR)/setwfdb - sed s+/usr/local/database+$(DBDIR)+g $(BINDIR)/cshsetwfdb - sed s+/usr/local/database+$(DBDIR)+g $(BINDIR)/pnwlogin - cd $(BINDIR); $(SETPERMISSIONS) *setwfdb; $(SETXPERMISSIONS) pnwlogin +scripts: $(DESTDIR)$(BINDIR) + sed s+/usr/local/database+$(DBDIR)+g $(DESTDIR)$(BINDIR)/setwfdb + sed s+/usr/local/database+$(DBDIR)+g $(DESTDIR)$(BINDIR)/cshsetwfdb + sed s+/usr/local/database+$(DBDIR)+g $(DESTDIR)$(BINDIR)/pnwlogin + cd $(DESTDIR)$(BINDIR); $(SETPERMISSIONS) *setwfdb; $(SETXPERMISSIONS) pnwlogin uninstall: - ../uninstall.sh $(PSPDIR) $(PSFILES) - ../uninstall.sh $(BINDIR) $(XFILES) $(SCRIPTS) - ../uninstall.sh $(LIBDIR) + ../uninstall.sh $(DESTDIR)$(PSPDIR) $(PSFILES) + ../uninstall.sh $(DESTDIR)$(BINDIR) $(XFILES) $(SCRIPTS) + ../uninstall.sh $(DESTDIR)$(LIBDIR) # Create directories for installation if necessary. -$(BINDIR): - mkdir -p $(BINDIR); $(SETDPERMISSIONS) $(BINDIR) -$(PSPDIR): - mkdir -p $(PSPDIR); $(SETDPERMISSIONS) $(PSPDIR) +$(DESTDIR)$(BINDIR): + mkdir -p $(DESTDIR)$(BINDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(BINDIR) +$(DESTDIR)$(PSPDIR): + mkdir -p $(DESTDIR)$(PSPDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(PSPDIR) # `make clean': remove intermediate and backup files clean: diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/mrgann.c wfdb-10.6.0/app/mrgann.c --- wfdb-10.5.24/app/mrgann.c 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/mrgann.c 2017-11-03 18:15:52.000000000 -0400 @@ -1,5 +1,5 @@ /* file mrgann.c G. Moody 28 May 1995 - Last revised: 30 April 1999 + Last revised: 3 November 2017 ------------------------------------------------------------------------------- mrgann: Merge annotation files by segments @@ -61,6 +61,7 @@ char *pname, *record = NULL; static int ateof[2], map0 = -1, map1 = -1, vflag; +static WFDB_Frequency sfreq, ffreq, afreq = 0; static WFDB_Anninfo ai[3]; static WFDB_Annotation annot[2]; void help(), mergeann(); @@ -118,13 +119,14 @@ pname, argv[i-1]); exit(1); } - tf = strtim(argv[i]); - if (tf < (WFDB_Time)0) tf = -tf; - if (argv[i][0] == 'e') tf = (WFDB_Time)(-1); if (mode == UNINITIALIZED) { init(); mode = MERGE; } + tf = strtim(argv[i]); + if (tf < (WFDB_Time)0) tf = -tf; + if (argv[i][0] == 'e') tf = (WFDB_Time)(-1); + else tf = (tf * afreq / sfreq) + 0.5; mergeann(mode, tf); switch (*(argv[i-1]+2)) { case '0': mode = DISCARD_ALL; break; @@ -181,15 +183,31 @@ init() { + WFDB_Frequency af1, af2; if (record == NULL || ai[0].name == NULL || ai[1].name == NULL || ai[2].name == NULL) { help(); exit(1); } - if (sampfreq(record) < 0.) - (void)setsampfreq(WFDB_DEFFREQ); + if ((sfreq = sampfreq(record)) < 0.) + (void)setsampfreq(sfreq = WFDB_DEFFREQ); + ffreq = sfreq / getspf(); + if (annopen(record, ai, 3) < 0) exit(2); + af1 = getiaorigfreq(0); + af2 = getiaorigfreq(1); + if (af1 > 0 && af2 > 0) + setafreq(afreq = (af1 > af2 ? af1 : af2)); + else if (af1 > 0) + setafreq(afreq = (af1 > ffreq ? af1 : ffreq)); + else if (af2 > 0) + setafreq(afreq = (af2 > ffreq ? af2 : ffreq)); + else + afreq = ffreq; + setiafreq(0, afreq); + setiafreq(1, afreq); + ateof[0] = getann(0, &annot[0]); ateof[1] = getann(1, &annot[1]); } diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/pnwlogin wfdb-10.6.0/app/pnwlogin --- wfdb-10.5.24/app/pnwlogin 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/pnwlogin 2016-11-02 18:17:23.000000000 -0400 @@ -1,7 +1,7 @@ #! /bin/bash # file: pnwlogin G. Moody 12 August 2012 -# Last revised: 30 July 2014 +# Last revised: 2 November 2016 # # Log in to PhysioNetWorks # @@ -42,7 +42,7 @@ rm -f .pnwhome if [ -z "${WFDB+xxx}" ] then - WFDB=". /usr/local/database http://physionet.org/physiobank/database" + WFDB=". /usr/local/database https://physionet.org/physiobank/database" fi WFDB="$WFDB https://physionet.org/works/\ https://physionet.org/users/$PNWUSER/works/" diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/pschart.c wfdb-10.6.0/app/pschart.c --- wfdb-10.5.24/app/pschart.c 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/pschart.c 2017-11-02 13:57:11.000000000 -0400 @@ -1,5 +1,5 @@ /* file: pschart.c G. Moody 15 March 1988 - Last revised: 27 May 2009 + Last revised: 2 November 2017 ------------------------------------------------------------------------------- pschart: Produce annotated `chart recordings' on a PostScript device @@ -1180,9 +1180,10 @@ case NOTE: if (annot.time == 0L) break; /* don't show modification records */ - if (annot.aux == NULL || *annot.aux == 0) - (void)printf("(%s) %d a\n", - annstr(annot.anntyp), x0+si(x)); + if (annot.aux == NULL || *annot.aux == 0) { + plabel(annstr(annot.anntyp), 0); + (void)printf(" %d a\n", x0 + si(x)); + } else { move(x0 + si(x), y + pt(fs_ann * 1.1)); if (aux_shorten && *annot.aux > 1) @@ -1191,9 +1192,10 @@ } break; case RHYTHM: - if (annot.aux == NULL || *annot.aux == 0) - (void)printf("(%s) %d a\n", - annstr(annot.anntyp), x0+si(x)); + if (annot.aux == NULL || *annot.aux == 0) { + plabel(annstr(annot.anntyp), 0); + (void)printf(" %d a\n", x0 + si(x)); + } else { move(x0 + si(x), ya[ia] - pt(fs_ann * 1.1)); label(annot.aux+1); @@ -1202,17 +1204,9 @@ case NORMAL: (void)printf("%d A\n", x0 + si(x) ); break; - case WFON: - (void)printf("(\\%s) %d a\n", - annstr(annot.anntyp), x0 + si(x)); - break; - case WFOFF: - (void)printf("(\\%s) %d a\n", - annstr(annot.anntyp), x0 + si(x)); - break; default: - (void)printf("(%s) %d a\n", - annstr(annot.anntyp), x0 + si(x)); + plabel(annstr(annot.anntyp), 0); + (void)printf(" %d a\n", x0 + si(x)); break; } } @@ -1610,7 +1604,9 @@ (void)putchar(*s); s++; } - (void)printf(")%c\n", t); + (void)putchar(')'); + if (t != 0) + (void)printf("%c\n", t); } /* Print a string beginning at the current point. */ diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/psfd.c wfdb-10.6.0/app/psfd.c --- wfdb-10.5.24/app/psfd.c 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/psfd.c 2017-11-02 13:57:11.000000000 -0400 @@ -1,5 +1,5 @@ /* file: psfd.c G. Moody 9 August 1988 - Last revised: 21 November 2013 + Last revised: 2 November 2017 ------------------------------------------------------------------------------- psfd: Produces annotated full-disclosure ECG plots on a PostScript device @@ -1093,9 +1093,10 @@ case NOTE: if (annot.time == 0L) break; /* don't show modification records */ - if (annot.aux == NULL || *annot.aux == 0) - (void)printf("(%s) %d a\n", - annstr(annot.anntyp), x0+si(x)); + if (annot.aux == NULL || *annot.aux == 0) { + plabel(annstr(annot.anntyp), 0); + (void)printf(" %d a\n", x0 + si(x)); + } else { move(x0 + si(x), y + pt(fs_ann * 1.1)); if (aux_shorten && *annot.aux > 1) @@ -1104,9 +1105,10 @@ } break; case RHYTHM: - if (annot.aux == NULL || *annot.aux == 0) - (void)printf("(%s) %d a\n", - annstr(annot.anntyp), x0+si(x)); + if (annot.aux == NULL || *annot.aux == 0) { + plabel(annstr(annot.anntyp), 0); + (void)printf(" %d a\n", x0 + si(x)); + } else { move(x0 + si(x), ya[ia] - pt(fs_ann * 1.1)); label(annot.aux+1); @@ -1115,17 +1117,9 @@ case NORMAL: (void)printf("%d A\n", x0 + si(x)); break; - case WFON: - (void)printf("(\\%s) %d a\n", - annstr(annot.anntyp), x0 + si(x)); - break; - case WFOFF: - (void)printf("(\\%s) %d a\n", - annstr(annot.anntyp), x0 + si(x)); - break; default: - (void)printf("(%s) %d a\n", - annstr(annot.anntyp), x0 + si(x)); + plabel(annstr(annot.anntyp), 0); + (void)printf(" %d a\n", x0 + si(x)); break; } } @@ -1496,7 +1490,9 @@ (void)putchar(*s); s++; } - (void)printf(")%c\n", t); + (void)putchar(')'); + if (t != 0) + (void)printf("%c\n", t); } /* Print a string beginning at the current point. */ diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/rdann.c wfdb-10.6.0/app/rdann.c --- wfdb-10.5.24/app/rdann.c 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/rdann.c 2017-11-03 18:54:35.000000000 -0400 @@ -1,5 +1,5 @@ /* file rdann.c T. Baker and G. Moody 27 July 1981 - Last revised: 4 June 2010 + Last revised: 3 November 2017 ------------------------------------------------------------------------------- rdann: Print an annotation file in ASCII form @@ -54,13 +54,15 @@ { char *record = NULL, *prog_name(); signed char cflag = 0, chanmatch, nflag = 0, nummatch, sflag = 0, submatch; - double sps, spm, sph; + double sps, tps, tpm, tph, n; + int sprec, mprec, hprec; int eflag = 0, i, j, vflag = 0, xflag = 0; long afrom = 0L, anum = 0L, ato = 0L, bfrom = 0L, bnum = 0L, bto = 0L, from = 0L, to = 0L, atol(); static char flag[ACMAX+1]; static WFDB_Anninfo ai; WFDB_Annotation annot; + WFDB_Time sample_num; void help(); pname = prog_name(argv[0]); @@ -197,13 +199,37 @@ if ((sps = sampfreq(record)) < 0.) (void)setsampfreq(sps = WFDB_DEFFREQ); - spm = 60.0*sps; - sph = 60.0*spm; ai.stat = WFDB_READ; if (annopen(record, &ai, 1) < 0) /* open annotation file */ exit(2); + if ((tps = getiaorigfreq(0)) < sps) + tps = sps; + + sprec = 3; + n = 1000; + while (n < tps) { + sprec++; + n *= 10; + } + + tpm = 60.0*tps; + mprec = 5; + n = 100000; + while (n < tpm) { + mprec++; + n *= 10; + } + + tph = 60.0*tpm; + hprec = 7; + n = 10000000; + while (n < tph) { + hprec++; + n *= 10; + } + if (from) { if (*argv[(int)from] == 'a') { if ((afrom = atol(argv[(int)from]+1)) < 0L) @@ -261,18 +287,32 @@ (void)printf("Type Sub Chan Num\tAux\n"); } - while (getann(0, &annot) == 0 && (to == 0L || annot.time <= to)) { + setsampfreq(tps); + setiafreq(0, tps); + while (getann(0, &annot) == 0) { + if (tps == sps) { + sample_num = annot.time; + } + else { + sample_num = annot.time * sps / tps + 0.5; + if (sample_num > annot.time * sps / tps + 0.5) + sample_num--; + } + if (to != 0L && sample_num > to) + break; if ((flag[0] || (isann(annot.anntyp) && flag[annot.anntyp])) && (cflag == 0 || annot.chan == chanmatch) && (nflag == 0 || annot.num == nummatch) && (sflag == 0 || annot.subtyp == submatch)) { if (eflag) - (void)printf("%s %7ld", mstimstr(annot.time), annot.time); + (void)printf("%s %7ld", mstimstr(annot.time), sample_num); else if (xflag) - (void)printf("%9.3lf %9.5lf %9.7lf", - annot.time/sps, annot.time/spm, annot.time/sph); + (void)printf("%*.*f %*.*f %*.*f", + sprec + 6, sprec, annot.time/tps, + mprec + 4, mprec, annot.time/tpm, + hprec + 2, hprec, annot.time/tph); else - (void)printf("%s %7ld", mstimstr(-annot.time), annot.time); + (void)printf("%s %7ld", mstimstr(-annot.time), sample_num); (void)printf("%6s%5d%5d%5d", annstr(annot.anntyp), annot.subtyp, annot.chan, annot.num); if (annot.aux != NULL) (void)printf("\t%s", annot.aux + 1); diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/rdsamp.c wfdb-10.6.0/app/rdsamp.c --- wfdb-10.5.24/app/rdsamp.c 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/rdsamp.c 2018-01-23 17:03:04.000000000 -0500 @@ -1,5 +1,5 @@ /* file: rdsamp.c G. Moody 23 June 1983 - Last revised: 6 October 2010 + Last revised: 11 December 2017 ------------------------------------------------------------------------------- rdsamp: Print an arbitrary number of samples from each signal @@ -381,7 +381,7 @@ (void)printf("\n"); } - if (xflag) (void)printf("\n", nsig+1); + if (xflag) (void)printf("\n"); while ((to == 0L || from < to) && getvec(v) >= 0) { if (cflag == 0) { switch (timeunits) { @@ -437,7 +437,7 @@ } else { /* output in raw units */ - if (xflag) (void)printf("\n", nsig+1); + if (xflag) (void)printf("\n"); while ((to == 0L || from < to) && getvec(v) >= 0) { (void)printf(tfmt, from++); for (i = 0; i < nsig; i++) diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/sortann.c wfdb-10.6.0/app/sortann.c --- wfdb-10.5.24/app/sortann.c 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/sortann.c 2017-11-03 18:11:54.000000000 -0400 @@ -1,5 +1,5 @@ /* file sortann.c G. Moody 7 April 1997 - Last revised: 4 October 2010 + Last revised: 3 November 2017 ------------------------------------------------------------------------------- sortann: Rearrange annotations in canonical order Copyright (C) 1997-2010 George B. Moody @@ -82,7 +82,7 @@ char *record = NULL, *prog_name(); long from = 0L, nann = 0L, to = 0L, atol(); int i, insert_ann(); - double sps, spm; + double sps, spm, tps; void cleanup(), help(); pname = prog_name(argv[0]); @@ -119,6 +119,16 @@ ai[1].name = argv[i]; break; case 'r': /* input record name follows */ + /* If -r is followed by a non-empty string (with no + intervening space), use that string as the WFDB path, + overriding the library or environment defaults. When + the WFDB library invokes sortann, it uses '-r.' to + indicate that the input file is located in the current + working directory. This is done to ensure + compatibility in both directions: older versions of + sortann will treat '-r.' as equivalent to '-r'. */ + if (argv[i][2] != 0) + setwfdb(&argv[i][2]); if (++i >= argc) { (void)fprintf(stderr, "%s: input record name must follow -r\n", @@ -184,6 +194,13 @@ if (to < 0L) to = -to; } + if ((tps = getiaorigfreq(0)) > 0) { + setafreq(tps); + setiafreq(0, tps); + from = from * tps / sps + 0.5; + to = to * tps / sps + 0.5; + } + /* Build a linked list of annotations in memory. */ while (getann(0, &annot) == 0) { if (annot.time < from || (to > 0L && annot.time >= to)) @@ -200,7 +217,7 @@ } nann++; } - wfdbquit(); + iannclose(0); if (in_order && ai[1].name == NULL) { /* If all of the annotations were in order, don't copy them unless diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/sumstats.c wfdb-10.6.0/app/sumstats.c --- wfdb-10.5.24/app/sumstats.c 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/sumstats.c 2017-12-11 15:55:32.000000000 -0500 @@ -1,5 +1,5 @@ /* file: sumstats.c G. Moody 17 August 1989 - Last revised: 10 August 2010 + Last revised: 11 December 2017 ------------------------------------------------------------------------------- sumstats: Derive aggregate statistics from bxb, rxr, or epic line-format output Copyright (C) 1989-2010 George B. Moody @@ -301,7 +301,7 @@ static char rts[20], tts[20]; static double rre, ds, dp, err, mref; static int cts, cfn, ctp, cfp, sts, sfn, stp, sfp, lts, lfn, ltp, lfp; - static int dummy, nt, vt, ft, qt; + static long dummy, nt, vt, ft, qt; static long ets, efn, etp, efp; static long nn, sn, vn, fn, on, ns, ss, vs, fs, os; static long nv, sv, vv, fv, ov, no, so, vo, fo; diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/wfdbtime.c wfdb-10.6.0/app/wfdbtime.c --- wfdb-10.5.24/app/wfdbtime.c 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/wfdbtime.c 2017-08-29 16:51:46.000000000 -0400 @@ -1,4 +1,5 @@ /* file: wfdbtime.c G. Moody 16 February 2009 + Last revised: 29 August 2017 ------------------------------------------------------------------------------- wfdbtime: convert to and from sample number, elapsed time, and absolute time @@ -36,7 +37,6 @@ for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-r") == 0) { if (record) wfdbquit(); - setgvmode(WFDB_HIGHRES); if (++i == argc) break; record = argv[i]; if (isigopen(record, NULL, 0) < 0) exit(2); diff -Naur '--exclude=Makefile' wfdb-10.5.24/app/xform.c wfdb-10.6.0/app/xform.c --- wfdb-10.5.24/app/xform.c 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/app/xform.c 2018-01-23 18:16:22.000000000 -0500 @@ -1,5 +1,5 @@ /* file: xform.c G. Moody 8 December 1983 - Last revised: 3 November 2010 + Last revised: 9 January 2018 ------------------------------------------------------------------------------- xform: Sampling frequency, amplitude, and format conversion for WFDB records Copyright (C) 1983-2010 George B. Moody @@ -32,15 +32,30 @@ #define DITHER (((double)rand() + (double)rand())/RAND_MAX - 1.0) char *pname, *prog_name(); +char *script = NULL; double gcd(); void help(); +static char *script_fgets(char *buffer, size_t length, FILE *f) +{ + if (!fgets(buffer, length, f)) { + if (script) { + fprintf(stderr, "\n%s: unexpected end of file in %s\n", pname, script); + exit(1); + } + else { + strcpy(buffer, "\n"); + } + } + return (buffer); +} + main(argc, argv) int argc; char *argv[]; { char btstring[30], **description, **filename, *irec = NULL, *orec = NULL, - *nrec = NULL, *script = NULL, *startp = "0:0", **units; + *nrec = NULL, *startp = "0:0", **units; double *gain, ifreq, ofreq = 0.0; int clip = 0, *deltav, dflag = 0, fflag = 0, gflag = 0, Hflag = 0, i, iframelen, j, m, Mflag = 0, mn, *msiglist, n, nann = 0, nisig, @@ -333,7 +348,7 @@ (void)fprintf(stderr, "Choose a name for the output record (up to %d characters): ", WFDB_MAXRNL); - (void)fgets(record, WFDB_MAXRNL+2, ttyin); + script_fgets(record, WFDB_MAXRNL+2, ttyin); record[strlen(record)-1] = '\0'; } while (record[0] == '\0' || newheader(record) < 0); nrec = record; @@ -344,12 +359,12 @@ (void)fprintf(stderr, "Number of signals to be written (1-%d) [%d]: ", nisig, nosig); - (void)fgets(answer, sizeof(answer), ttyin); + script_fgets(answer, sizeof(answer), ttyin); (void)sscanf(answer, "%d", &nosig); if (nosig == 0) { (void)fprintf(stderr, "No signals will be written. Are you sure? [n]: "); - (void)fgets(answer, sizeof(answer), ttyin); + script_fgets(answer, sizeof(answer), ttyin); if (*answer != 'y' && *answer != 'Y') nosig = -1; } @@ -366,7 +381,7 @@ (void)fprintf(stderr, "Output sampling frequency (Hz per signal, > 0) [%g]: ", ofreq); - (void)fgets(answer, sizeof(answer), ttyin); + script_fgets(answer, sizeof(answer), ttyin); (void)sscanf(answer, "%lf", &ofreq); } while (ofreq < 0); if (ofreq == 0) ofreq = WFDB_DEFFREQ; @@ -376,7 +391,7 @@ (void)fprintf(stderr, " signals should be written, or press to write\n"); (void)fprintf(stderr, " them in the current directory: "); - (void)fgets(directory, sizeof(directory)-1, ttyin); + script_fgets(directory, sizeof(directory)-1, ttyin); if (*directory == '\n') *directory = '\0'; else directory[strlen(directory)-1] = '/'; (void)fprintf(stderr,"Any of these output formats may be used:\n"); @@ -402,14 +417,14 @@ (void)fprintf(stderr, "Choose an output format (8/16/61/80/160/212/310/311/24/32) [%d]: ", format); - (void)fgets(answer, sizeof(answer), ttyin); + script_fgets(answer, sizeof(answer), ttyin); (void)sscanf(answer, "%d", &format); for (i = 1; i < WFDB_NFMTS; i++) /* skip format[0] (= 0) */ if (format == formats[i]) break; } while (i >= WFDB_NFMTS); if (nosig > 1) { (void)fprintf(stderr, "Save all signals in one file? [y]: "); - (void)fgets(answer, sizeof(answer), ttyin); + script_fgets(answer, sizeof(answer), ttyin); } /* Use the input signal specifications as defaults for output. */ for (i = 0; i < nosig; i++) @@ -456,13 +471,13 @@ (void)fprintf(stderr, "Signal %d description (up to %d characters): ", i, WFDB_MAXDSL); - (void)fgets(description[i], WFDB_MAXDSL+2, ttyin); + script_fgets(description[i], WFDB_MAXDSL+2, ttyin); description[i][strlen(description[i])-1] = '\0'; dfout[i].desc = description[i]; (void)fprintf(stderr, "Signal %d units (up to %d characters): ", i, WFDB_MAXUSL); - (void)fgets(units[i], WFDB_MAXUSL+2, ttyin); + script_fgets(units[i], WFDB_MAXUSL+2, ttyin); for (p = units[i]; *p; p++) { if (*p == ' ' || *p == '\t') *p = '_'; else if (*p == '\n') { *p = '\0'; break; } @@ -472,7 +487,7 @@ (void)fprintf(stderr, " Signal %d gain (adu/%s) [%g]: ", i, dfout[i].units ? dfout[i].units : "mV", dfout[i].gain); - (void)fgets(answer, sizeof(answer), ttyin); + script_fgets(answer, sizeof(answer), ttyin); sscanf(answer, "%lf", &dfout[i].gain); do { if (i > 0) dfout[i].adcres = dfout[i-1].adcres; @@ -504,12 +519,12 @@ (void)fprintf(stderr, " Signal %d ADC resolution in bits (8-32) [%d]: ", i, dfout[i].adcres); - (void)fgets(answer, sizeof(answer), ttyin); + script_fgets(answer, sizeof(answer), ttyin); (void)sscanf(answer, "%d", &dfout[i].adcres); } while (dfout[i].adcres < 8 || dfout[i].adcres > 32); (void)fprintf(stderr, " Signal %d ADC zero level (adu) [%d]: ", i, dfout[i].adczero); - (void)fgets(answer, sizeof(answer), ttyin); + script_fgets(answer, sizeof(answer), ttyin); (void)sscanf(answer, "%d", &dfout[i].adczero); } } @@ -732,8 +747,8 @@ /* Determine the legal range of sample values for each output signal. */ for (i = 0; i < nosig; i++) { - vmax[i] = dfout[i].adczero + (1 << (dfout[i].adcres-1)) - 1; - vmin[i] = dfout[i].adczero + (-1 << (dfout[i].adcres-1)) + 1; + vmax[i] = dfout[i].adczero + (1UL << (dfout[i].adcres-1)) - 1; + vmin[i] = dfout[i].adczero - (1UL << (dfout[i].adcres-1)); } /* If resampling is required, initialize the interpolation/decimation diff -Naur '--exclude=Makefile' wfdb-10.5.24/checkpkg/Makefile.tpl wfdb-10.6.0/checkpkg/Makefile.tpl --- wfdb-10.5.24/checkpkg/Makefile.tpl 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/checkpkg/Makefile.tpl 2017-03-09 18:13:18.000000000 -0500 @@ -1,10 +1,13 @@ all: @rm -f lcheck @make lcheck - -@./libcheck $(DBDIR) $(LIBDIR) >libcheck.out - @./appcheck $(INCDIR) $(BINDIR) $(LIBDIR) + -@./libcheck $(DESTDIR)$(DBDIR) $(DESTDIR)$(LIBDIR) >libcheck.out + @./appcheck $(DESTDIR)$(INCDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(PSPDIR) @echo @cat libcheck.out appcheck.out + @grep 'all .* tests passed' libcheck.out > grep.out + @grep 'all .* tests passed' appcheck.out > grep.out + @rm -f grep.out lcheck: lcheck.c @echo Compiling WFDB library test application ... diff -Naur '--exclude=Makefile' wfdb-10.5.24/checkpkg/appcheck wfdb-10.6.0/checkpkg/appcheck --- wfdb-10.5.24/checkpkg/appcheck 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/checkpkg/appcheck 2017-03-09 18:13:18.000000000 -0500 @@ -1,6 +1,6 @@ #!/bin/sh # file: appcheck G. Moody 7 September 2001 -# Last revised: 8 March 2014 +# Last revised: 8 March 2017 # # This script checks the basic functionality of most of the WFDB applications # in the 'app' directory. These programs are not (yet) tested by this script: @@ -17,6 +17,7 @@ INCDIR=$1 BINDIR=$2 LIBDIR=$3 +PSPDIR=$4 PASS=0 FAIL=0 @@ -25,6 +26,11 @@ PATH=$BINDIR:$PATH export PATH +PSCHARTPRO=$PSPDIR/pschart.pro +export PSCHARTPRO +PSFDPRO=$PSPDIR/psfd.pro +export PSFDPRO + case `uname` in Darwin*) if [ "x$DYLD_LIBRARY_PATH" = x ] diff -Naur '--exclude=Makefile' wfdb-10.5.24/checkpkg/dosify wfdb-10.6.0/checkpkg/dosify --- wfdb-10.5.24/checkpkg/dosify 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/checkpkg/dosify 2016-11-02 18:17:23.000000000 -0400 @@ -1,6 +1,6 @@ #! /bin/bash # file: dosify G. Moody 19 November 2013 -# Last revised: 8 March 2014 +# Last revised: 23 December 2015 # Convert expected test results to MS-DOS/MS-Windows format for MinGW, using # mv, sed, u2d, and bash builtins. @@ -8,16 +8,15 @@ if [ ! -e wfdbwhich.out.orig ] then mv wfdbwhich.out wfdbwhich.out.orig - sed s+/+\\\\+ wfdbwhich.out - u2d wfdbwhich.out + sed 's+/+\\+;s+\r*$+\r+' wfdbwhich.out fi for F in lcheck.log-NETFILES lcheck.log-no-NETFILES bxb.out rxr.out psfd.ps test.des test.key do if [ ! -e $F.orig ] then - cp $F $F.orig - u2d $F + mv $F $F.orig + sed 's+\r*$+\r+' < $F.orig > $F fi done diff -Naur '--exclude=Makefile' wfdb-10.5.24/checkpkg/expected/100s.mix wfdb-10.6.0/checkpkg/expected/100s.mix --- wfdb-10.5.24/checkpkg/expected/100s.mix 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/checkpkg/expected/100s.mix 2017-11-03 18:10:51.000000000 -0400 @@ -1 +1 @@ -pü(N;%$&ë f0$.4(*((9($&*0" 5/)!-'0=(!$-+)$#/,+"41(&$ \ No newline at end of file +Xü## time resolution: 360ìÿÿÿÿpü(N;%$&ë f0$.4(*((9($&*0" 5/)!-'0=(!$-+)$#/,+"41(&$ \ No newline at end of file diff -Naur '--exclude=Makefile' wfdb-10.5.24/checkpkg/expected/100s.mrg wfdb-10.6.0/checkpkg/expected/100s.mrg --- wfdb-10.5.24/checkpkg/expected/100s.mrg 2015-05-28 15:55:11.000000000 -0400 +++ wfdb-10.6.0/checkpkg/expected/100s.mrg 2017-11-03 18:14:45.000000000 -0400 @@ -1 +1 @@ -ìÕ#'*0! 5(             ý           ÿ ý      û   ü               \ No newline at end of file +Xü## time resolution: 360ìÿÿÿÿ>          Ð K      ú ìá#'*0! 5(             ý           ÿ ý      û   ü               \ No newline at end of file diff -Naur '--exclude=Makefile' wfdb-10.5.24/checkpkg/lcheck.c wfdb-10.6.0/checkpkg/lcheck.c --- wfdb-10.5.24/checkpkg/lcheck.c 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/checkpkg/lcheck.c 2017-08-29 16:07:15.000000000 -0400 @@ -1,5 +1,5 @@ /* file: lcheck.c G. Moody 7 September 2001 - Last revised: 26 November 2010 + Last revised: 15 August 2017 ------------------------------------------------------------------------------- wfdbcheck: test WFDB library Copyright (C) 2001-2010 George B. Moody @@ -60,7 +60,7 @@ strcpy(libversion, p); /* Print the library version number and date. */ - fprintf(stderr, "Testing %s", libversion = wfdberror()); + fprintf(stderr, "Testing %s", libversion); /* Check that the installed matches the library. */ sprintf(headerversion, "WFDB library version %d.%d.%d", @@ -496,7 +496,7 @@ /* *** aduphys, physadu *** */ x = aduphys((WFDB_Signal)0, (WFDB_Sample)1000); - if (x != -0.12) { + if (x > -0.119999999 || x < -0.120000001) { printf("Error: aduphys returned %g (should have been -0.12)\n", x); errors++; } diff -Naur '--exclude=Makefile' wfdb-10.5.24/checkpkg/libcheck wfdb-10.6.0/checkpkg/libcheck --- wfdb-10.5.24/checkpkg/libcheck 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/checkpkg/libcheck 2017-10-24 17:00:20.000000000 -0400 @@ -1,6 +1,6 @@ #!/bin/sh # file: libcheck G. Moody 8 September 2001 -# Last revised: 26 November 2010 +# Last revised: 19 October 2017 # # This script checks the functionality of the WFDB library by comparing the # outputs of 'lcheck' with expected outputs. See 'lcheck.c' for details of @@ -24,10 +24,6 @@ exit fi -# If WFDB was set by the user, unset it for the duration of this test so -# that we have a known WFDB path. -unset WFDB - case $# in 0) VERBOSE=0 ;; *) VERBOSE=1 ;; @@ -36,29 +32,39 @@ DBDIR=$1 LIBDIR=$2 -case `uname` in - Darwin*) - if [ "x$DYLD_LIBRARY_PATH" != x ] - then - DYLD_LIBRARY_PATH=$LIBDIR:$DYLD_LIBRARY_PATH - else - DYLD_LIBRARY_PATH=$LIBDIR - fi - export DYLD_LIBRARY_PATH - ;; - CYGWIN*|MINGW*) - export PATH=.:$LIBDIR/../bin:$PATH - ;; - *) - if [ "x$LD_LIBRARY_PATH" != x ] - then - LD_LIBRARY_PATH=$LIBDIR:$LD_LIBRARY_PATH - else - LD_LIBRARY_PATH=$LIBDIR - fi - export LD_LIBRARY_PATH - ;; -esac +# If not using DESTDIR, test the built-in path used by the WFDB library. +# If using DESTDIR, set the WFDB path explicitly. +if [ "x$DESTDIR" = x ] +then + unset WFDB +else + WFDB=". $DBDIR http://physionet.org/physiobank/database" + export WFDB +fi + +## Darwin +if [ "x$DYLD_LIBRARY_PATH" != x ] +then + DYLD_LIBRARY_PATH=$LIBDIR:$DYLD_LIBRARY_PATH +else + DYLD_LIBRARY_PATH=$LIBDIR +fi +export DYLD_LIBRARY_PATH + +## Windows (Cygwin/MinGW) and Wine +PATH=.:$LIBDIR/../bin:$PATH +export PATH +WINEPATH=$LIBDIR/../bin\;$WINEPATH +export WINEPATH + +## Other *nix +if [ "x$LD_LIBRARY_PATH" != x ] +then + LD_LIBRARY_PATH=$LIBDIR:$LD_LIBRARY_PATH +else + LD_LIBRARY_PATH=$LIBDIR +fi +export LD_LIBRARY_PATH test -s Makefile || ( cd ..; ./configure ) test -s lcheck || make lcheck diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/cygwin-slib.def wfdb-10.6.0/conf/cygwin-slib.def --- wfdb-10.5.24/conf/cygwin-slib.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/cygwin-slib.def 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: cygwin-slib.def I. Henry and G. Moody 19 November 2002 -# Last revised: 6 August 2014 +# Last revised: 8 March 2017 # This section contains settings suitable for generating a DLL (shared library) # under MS Windows using the free Cygwin/gcc ANSI C compiler, available from @@ -53,7 +53,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb # CC is the name of your C compiler. CC = gcc @@ -69,7 +69,7 @@ # CFLAGS is the set of C compiler options used when compiling the shared # library. CFLAGS should always include CCDEFS. -CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # WFDBLIB_BASENAME is the name, without version numbers, of the alternate # library. WFDBLIB_SONAME is the shared object name ("soname") of the @@ -93,7 +93,7 @@ # BUILDLIB is the command that creates the shared WFDB library once its # components have been compiled separately; the list of *.o files that # make up the library will be appended to BUILDLIB. -BUILDLIB = gcc -shared -o $(WFDBLIB_DLLNAME) \ +BUILDLIB = $(CC) -shared -o $(WFDBLIB_DLLNAME) \ -Wl,--out-implib=$(WFDBLIB) \ -Wl,--export-all-symbols \ -Wl,--enable-auto-import @@ -129,21 +129,23 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) - test -d $(BINDIR) || \ - ( mkdir -p $(BINDIR); $(SETDPERMISSIONS) $(BINDIR) ) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) + test -d $(DESTDIR)$(BINDIR) || \ + ( mkdir -p $(DESTDIR)$(BINDIR); \ + $(SETDPERMISSIONS) $(DESTDIR)$(BINDIR) ) test /usr/bin = $(BINDIR) || \ - ( cp -p /usr/bin/cygwin1.dll $(BINDIR); \ - cp -p /usr/bin/cygz.dll $(BINDIR) ) - cp $(WFDBLIB_DLLNAME) $(BINDIR) - cd $(BINDIR); $(SETLPERMISSIONS) *.dll + ( cp -p /usr/bin/cygwin1.dll $(DESTDIR)$(BINDIR); \ + cp -p /usr/bin/cygz.dll $(DESTDIR)$(BINDIR) ) + cp $(WFDBLIB_DLLNAME) $(DESTDIR)$(BINDIR) + cd $(DESTDIR)$(BINDIR); $(SETLPERMISSIONS) *.dll test $(BINDIR) = $(LIBDIR) && \ - ( mkdir $(WFDBROOT)/lib; ln -sf $(BINDIR)/$(WFDBLIB_BASENAME) $(WFDBROOT)/lib ) + ( mkdir $(DESTDIR)$(WFDBROOT)/lib; \ + ln -sf $(BINDIR)/$(WFDBLIB_BASENAME) $(DESTDIR)$(WFDBROOT)/lib ) lib-post-uninstall: - rm -f $(LIBDIR)/$(WFDBLIB_BASENAME) - rm -f $(LIBDIR)/$(WFDBLIB_SONAME) - rm -f $(BINDIR)/$(WFDBLIB_DLLNAME) - + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_BASENAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_SONAME) + rm -f $(DESTDIR)$(BINDIR)/$(WFDBLIB_DLLNAME) + #______________________________________________________________________________ diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/cygwin.def wfdb-10.6.0/conf/cygwin.def --- wfdb-10.5.24/conf/cygwin.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/cygwin.def 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: cygwin.def G. Moody 6 June 2000 -# Last revised: 13 May 2010 +# Last revised: 8 March 2017 # # This file contains default 'make' definitions for compiling the WFDB Software # Package under MS Windows using the free Cygwin/gcc ANSI C compiler, available @@ -97,11 +97,11 @@ # -O if you trust your C compiler's optimizer # With the exception of `gcc', most C compilers do not allow you to use -g and # -O simultaneously. -CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(LL) # WFDBLIB is the name of the standard WFDB library. In order to access it via # `-lwfdb', WFDBLIB should be `libwfdb.a'. diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/darwin-slib.def wfdb-10.6.0/conf/darwin-slib.def --- wfdb-10.5.24/conf/darwin-slib.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/darwin-slib.def 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: darwin-slib.def I. Henry and G. Moody 14 November 2002 -# Last revised: 17 September 2014 +# Last revised: 8 March 2017 # Based on 'freebsd-slib.def'. # This section contains settings suitable for generating a shared library under @@ -52,7 +52,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb # CC is the name of your C compiler. CC = gcc @@ -68,7 +68,7 @@ # CFLAGS is the set of C compiler options used when compiling the shared # library. CFLAGS should always include CCDEFS. -CFLAGS = $(MFLAGS) -fPIC -fno-common -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -fPIC -fno-common -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # WFDBLIB_BASENAME is the name, without version numbers, of the alternate # library. WFDBLIB_SONAME is the shared object name ("soname") of the @@ -92,7 +92,7 @@ # BUILDLIB is the command that creates the shared WFDB library once its # components have been compiled separately; the list of *.o files that # make up the library will be appended to BUILDLIB. -BUILDLIB = gcc $(MFLAGS) -dynamiclib \ +BUILDLIB = $(CC) $(MFLAGS) -dynamiclib \ -install_name $(LIBDIR)/$(WFDBLIB_SONAME) \ -compatibility_version $(MAJOR).$(MINOR) \ -current_version $(MAJOR).$(MINOR).$(RELEASE) \ @@ -125,11 +125,11 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) lib-post-uninstall: - rm -f $(LIBDIR)/$(WFDBLIB_BASENAME) - rm -f $(LIBDIR)/$(WFDBLIB_SONAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_BASENAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_SONAME) #______________________________________________________________________________ diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/darwin.def wfdb-10.6.0/conf/darwin.def --- wfdb-10.5.24/conf/darwin.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/darwin.def 2018-01-25 17:46:30.000000000 -0500 @@ -1,5 +1,5 @@ # file: darwin.def G. Moody and I. Henry 14 November 2002 -# Last revised: 17 September 2014 +# Last revised: 25 January 2018 # 'make' definitions for compiling the WFDB Software Package under Darwin # # Based on 'freebsd.def'. @@ -74,11 +74,11 @@ # CFLAGS is the set of C compiler options. CFLAGS should always include # CCDEFS. -CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(LL) # WFDBLIB is the name of the standard WFDB library. In order to access it via # `-lwfdb', WFDBLIB should be `libwfdb.a'. @@ -89,6 +89,10 @@ # make up the library will be appended to BUILDLIB. BUILDLIB = $(AR) $(ARFLAGS) $(WFDBLIB) +# RANLIB is the command that builds an index of symbols in the static +# library, after it has been created by the BUILDLIB command. +RANLIB = ranlib + # PRINT is the name of the program used to produce listings (including any # options for the desired formatting). PRINT = lpr @@ -150,7 +154,7 @@ WMFLAGS = # WCFLAGS is the set of C compiler options to use when compiling WAVE. -WCFLAGS = $(WMFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) -I$(OWINCDIR) -I$(XINCDIR) +WCFLAGS = $(WMFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) -I$(OWINCDIR) -I$(XINCDIR) # HELPOBJ can be set to "help.o" if you wish to recompile the XView spot help # functions in "wave/help.c" (recommended under Linux). @@ -168,7 +172,7 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - ranlib $(LIBDIR)/$(WFDBLIB) + $(RANLIB) $(DESTDIR)$(LIBDIR)/$(WFDBLIB) lib-post-uninstall: echo "Nothing to be done for lib-post-uninstall" diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/freebsd-slib.def wfdb-10.6.0/conf/freebsd-slib.def --- wfdb-10.5.24/conf/freebsd-slib.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/freebsd-slib.def 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: freebsd-slib.def G. Moody 5 March 2002 -# Last revised: 13 August 2014 +# Last revised: 8 March 2017 # Based on 'linux-slib.def'. # This section contains settings suitable for generating an ELF-format shared @@ -57,7 +57,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(RPATHFLAGS) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(RPATHFLAGS) # CC is the name of your C compiler. CC = gcc @@ -73,7 +73,7 @@ # CFLAGS is the set of C compiler options used when compiling the shared # library. CFLAGS should always include CCDEFS. -CFLAGS = $(MFLAGS) -fpic -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -fpic -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # WFDBLIB_BASENAME is the name, without version numbers, of the alternate # library. WFDBLIB_SONAME is the shared object name ("soname") of the @@ -130,12 +130,12 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) @$(LDCONFIG) || echo Warning: "$(LDCONFIG)" was unsuccessful lib-post-uninstall: - rm -f $(LIBDIR)/$(WFDBLIB_BASENAME) - rm -f $(LIBDIR)/$(WFDBLIB_SONAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_BASENAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_SONAME) @$(LDCONFIG) || echo Warning: "$(LDCONFIG)" was unsuccessful #______________________________________________________________________________ diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/freebsd.def wfdb-10.6.0/conf/freebsd.def --- wfdb-10.5.24/conf/freebsd.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/freebsd.def 2018-01-25 17:46:36.000000000 -0500 @@ -1,5 +1,5 @@ # file: freebsd.def G. Moody 5 March 2002 -# Last revised: 13 August 2014 +# Last revised: 25 January 2018 # 'make' definitions for compiling the WFDB Software Package under FreeBSD # # Based on 'linux.def', with edits for FreeBSD thanks to Giuseppe Pagnoni. @@ -86,7 +86,7 @@ # CFLAGS is the set of C compiler options. CFLAGS should always include # CCDEFS. -CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # RPATHFLAGS is a set of C compiler options that cause the program to # search for shared libraries in a non-standard location at run-time. @@ -95,7 +95,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(LL) # WFDBLIB is the name of the standard WFDB library. In order to access it via # `-lwfdb', WFDBLIB should be `libwfdb.a'. @@ -106,6 +106,10 @@ # make up the library will be appended to BUILDLIB. BUILDLIB = $(AR) $(ARFLAGS) $(WFDBLIB) +# RANLIB is the command that builds an index of symbols in the static +# library, after it has been created by the BUILDLIB command. +RANLIB = ranlib + # PRINT is the name of the program used to produce listings (including any # options for the desired formatting). PRINT = lpr @@ -181,7 +185,7 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - ranlib $(LIBDIR)/$(WFDBLIB) + $(RANLIB) $(DESTDIR)$(LIBDIR)/$(WFDBLIB) lib-post-uninstall: echo "Nothing to be done for lib-post-uninstall" diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/generic-slib.def wfdb-10.6.0/conf/generic-slib.def --- wfdb-10.5.24/conf/generic-slib.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/generic-slib.def 2018-01-25 17:51:48.000000000 -0500 @@ -1,5 +1,5 @@ # file: generic-slib.def G. Moody 31 May 2000 -# Last revised: 13 August 2014 +# Last revised: 25 January 2018 # This section contains settings suitable for compiling a shared version of the # WFDB library under versions of UNIX that are not otherwise recognized by # 'configure'. Not all versions of UNIX support shared libraries, so you may @@ -63,7 +63,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(RPATHFLAGS) $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(RPATHFLAGS) $(LL) # CC is the name of your C compiler. CC = gcc @@ -92,7 +92,7 @@ # CFLAGS is the set of C compiler options used when compiling the shared # library. CFLAGS should always include CCDEFS. -CFLAGS = $(MFLAGS) -fpic -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -fpic -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # WFDBLIB_BASENAME is the name, without version numbers, of the alternate # library. WFDBLIB_SONAME is the shared object name ("soname") of the @@ -117,8 +117,8 @@ # make up the library will be appended to BUILDLIB. This command varies # considerably depending on the operating system; the setting here works # if gcc and the GNU binutils are installed. -BUILDLIB = gcc $(MFLAGS) -shared -Wl,-soname,$(SWFDBLIB_SONAME) \ - -o $(SWFDBLIB) +BUILDLIB = $(CC) $(MFLAGS) -shared -Wl,-soname,$(WFDBLIB_SONAME) \ + -o $(WFDBLIB) # BUILDLIB_LDFLAGS is a list of arguments appended to BUILDLIB following # the list of *.o files (for most platforms, BUILDLIB_LDFLAGS is empty). @@ -160,13 +160,13 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) - $(RANLIB) $(LIBDIR)/$(WFDBLIB) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) + $(SRANLIB) $(DESTDIR)$(LIBDIR)/$(WFDBLIB) @$(LDCONFIG) || echo Warning: "$(LDCONFIG)" was unsuccessful lib-post-uninstall: - rm -f $(LIBDIR)/$(WFDBLIB_BASENAME) - rm -f $(LIBDIR)/$(WFDBLIB_SONAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_BASENAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_SONAME) @$(LDCONFIG) || echo Warning: "$(LDCONFIG)" was unsuccessful #______________________________________________________________________________ diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/generic.def wfdb-10.6.0/conf/generic.def --- wfdb-10.5.24/conf/generic.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/generic.def 2018-01-25 17:49:49.000000000 -0500 @@ -1,5 +1,5 @@ # file: generic.def G. Moody 31 May 2000 -# Last revised: 13 August 2014 +# Last revised: 25 January 2018 # This file contains default 'make' definitions for compiling the WFDB Software # Package under versions of UNIX that are not otherwise recognized by # 'configure'. @@ -112,7 +112,7 @@ # -O simultaneously. # CFLAGS = -g $(CCDEFS) $(LC) -I$(INCDIR) # `gcc' users may comment out the previous line, and uncomment the next one. -CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # RPATHFLAGS is a set of C compiler options that cause the program to # search for shared libraries in a non-standard location at run-time. @@ -121,7 +121,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(LL) # WFDBLIB is the name of the standard WFDB library. In order to access it via # `-lwfdb', WFDBLIB should be `libwfdb.a'. @@ -220,7 +220,7 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - echo "Nothing to be done for lib-post-install" + $(RANLIB) $(DESTDIR)$(LIBDIR)/$(WFDBLIB) lib-post-uninstall: echo "Nothing to be done for lib-post-uninstall" diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/hpux-slib.def wfdb-10.6.0/conf/hpux-slib.def --- wfdb-10.5.24/conf/hpux-slib.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/hpux-slib.def 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: hpux-slib.def G. Moody 31 May 2000 -# Last revised: 13 August 2014 +# Last revised: 8 March 2017 # This section contains settings suitable for generating a shared library under # HP-UX. @@ -59,7 +59,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(RPATHFLAGS) $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(RPATHFLAGS) $(LL) # CC is the name of your C compiler. CC = gcc @@ -75,7 +75,7 @@ # CFLAGS is the set of C compiler options used when compiling the shared # library. CFLAGS should always include CCDEFS. -CFLAGS = $(MFLAGS) -fpic -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -fpic -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # WFDBLIB_BASENAME is the name, without version numbers, of the alternate # library. WFDBLIB_SONAME is the shared object name ("soname") of the @@ -127,10 +127,10 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) lib-post-uninstall: - rm -f $(LIBDIR)/$(WFDBLIB_BASENAME) - rm -f $(LIBDIR)/$(WFDBLIB_SONAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_BASENAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_SONAME) #______________________________________________________________________________ diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/hpux.def wfdb-10.6.0/conf/hpux.def --- wfdb-10.5.24/conf/hpux.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/hpux.def 2018-01-25 17:46:52.000000000 -0500 @@ -1,5 +1,5 @@ # file: hpux.def G. Moody 31 May 2000 -# Last revised: 13 August 2014 +# Last revised: 25 January 2018 # 'make' definitions for compiling the WFDB library under HP-UX # Choose a value for WFDBROOT to determine where the WFDB Software Package will @@ -87,7 +87,7 @@ # -O simultaneously. # CFLAGS = -g $(CCDEFS) $(LC) -I$(INCDIR) # `gcc' users may comment out the previous line, and uncomment the next one. -CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # RPATHFLAGS is a set of C compiler options that cause the program to # search for shared libraries in a non-standard location at run-time. @@ -96,7 +96,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(LL) # WFDBLIB is the name of the standard WFDB library. In order to access it via # `-lwfdb', WFDBLIB should be `libwfdb.a'. @@ -115,6 +115,10 @@ # changed. BUILDLIB = $(AR) $(ARFLAGS) $(WFDBLIB) `lorder $(OFILES) | tsort` +# RANLIB is the command that builds an index of symbols in the static +# library, after it has been created by the BUILDLIB command. +RANLIB = ranlib + # PRINT is the name of the program used to produce listings (including any # options for the desired formatting). PRINT = lpr @@ -190,7 +194,7 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - ranlib $(LIBDIR)/$(WFDBLIB) + $(RANLIB) $(DESTDIR)$(LIBDIR)/$(WFDBLIB) lib-post-uninstall: echo "Nothing to be done for lib-post-uninstall" diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/linux-slib.def wfdb-10.6.0/conf/linux-slib.def --- wfdb-10.5.24/conf/linux-slib.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/linux-slib.def 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: linux-slib.def G. Moody 31 May 2000 -# Last revised: 13 August 2014 +# Last revised: 8 March 2017 # This section contains settings suitable for generating an ELF-format shared # library under Linux. @@ -55,7 +55,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(RPATHFLAGS) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(RPATHFLAGS) # CC is the name of your C compiler. CC = gcc @@ -72,7 +72,7 @@ # CFLAGS is the set of C compiler options used when compiling the shared # library. CFLAGS should always include CCDEFS. -CFLAGS = $(MFLAGS) -fpic -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -fpic -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # WFDBLIB_BASENAME is the name, without version numbers, of the alternate # library. WFDBLIB_SONAME is the shared object name ("soname") of the @@ -95,7 +95,7 @@ # BUILDLIB is the command that creates the shared WFDB library once its # components have been compiled separately; the list of *.o files that # make up the library will be appended to BUILDLIB. -BUILDLIB = gcc $(MFLAGS) -shared -Wl,-soname,$(WFDBLIB_SONAME) \ +BUILDLIB = $(CC) $(MFLAGS) -shared -Wl,-soname,$(WFDBLIB_SONAME) \ -o $(WFDBLIB) # BUILDLIB_LDFLAGS is a list of arguments appended to BUILDLIB following @@ -129,14 +129,14 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - -(cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME)) - -(cd $(LIBDIR); ln -sf $(WFDBLIB_SONAME) $(WFDBLIB_BASENAME)) - -([$EUID -eq 0 -a -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled && /sbin/restorecon $(LIBDIR)/$(WFDBLIB)) + -(cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME)) + -(cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB_SONAME) $(WFDBLIB_BASENAME)) + -([$EUID -eq 0 -a -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled && /sbin/restorecon $(DESTDIR)$(LIBDIR)/$(WFDBLIB)) -([$EUID -eq 0] && ($(LDCONFIG) 2>/dev/null || \ echo Warning: "$(LDCONFIG)" was unsuccessful)) lib-post-uninstall: - rm -f $(LIBDIR)/$(WFDBLIB_BASENAME) - rm -f $(LIBDIR)/$(WFDBLIB_SONAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_BASENAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_SONAME) -@$(LDCONFIG) || echo Warning: "$(LDCONFIG)" was unsuccessful #______________________________________________________________________________ diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/linux.def wfdb-10.6.0/conf/linux.def --- wfdb-10.5.24/conf/linux.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/linux.def 2018-01-25 17:47:02.000000000 -0500 @@ -1,5 +1,5 @@ # file: linux.def G. Moody 31 May 2000 -# Last revised: 13 August 2014 +# Last revised: 25 January 2018 # 'make' definitions for compiling the WFDB Software Package under Linux # Choose a value for WFDBROOT to determine where the WFDB Software Package will @@ -73,7 +73,7 @@ # CFLAGS is the set of C compiler options. CFLAGS should always include # CCDEFS. -CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # RPATHFLAGS is a set of C compiler options that cause the program to # search for shared libraries in a non-standard location at run-time. @@ -82,7 +82,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(LL) # WFDBLIB is the name of the standard WFDB library. In order to access it via # `-lwfdb', WFDBLIB should be `libwfdb.a'. @@ -93,6 +93,10 @@ # make up the library will be appended to BUILDLIB. BUILDLIB = $(AR) $(ARFLAGS) $(WFDBLIB) +# RANLIB is the command that builds an index of symbols in the static +# library, after it has been created by the BUILDLIB command. +RANLIB = ranlib + # PRINT is the name of the program used to produce listings (including any # options for the desired formatting). PRINT = lpr @@ -172,7 +176,7 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - ranlib $(LIBDIR)/$(WFDBLIB) + $(RANLIB) $(DESTDIR)$(LIBDIR)/$(WFDBLIB) lib-post-uninstall: echo "Nothing to be done for lib-post-uninstall" diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/mingw-slib.def wfdb-10.6.0/conf/mingw-slib.def --- wfdb-10.5.24/conf/mingw-slib.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/mingw-slib.def 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: mingw-slib.def I. Henry and G. Moody 11 February 2005 -# Last revised: 18 August 2014 +# Last revised: 8 March 2017 # # This section contains settings suitable for generating a DLL (shared library) # under MS Windows using the free gcc ANSI C compiler. @@ -51,7 +51,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb # CC is the name of your C compiler ('configure' will modify this). CC = gcc NOCYGWIN @@ -67,7 +67,7 @@ # CFLAGS is the set of C compiler options used when compiling the shared # library. CFLAGS should always include CCDEFS. -CFLAGS =$(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS =$(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # WFDBLIB_BASENAME is the name, without version numbers, of the alternate # library. WFDBLIB_SONAME is the shared object name ("soname") of the @@ -94,7 +94,7 @@ # BUILDLIB is the command that creates the shared WFDB library once its # components have been compiled separately; the list of *.o files that # make up the library will be appended to BUILDLIB. -BUILDLIB = gcc NOCYGWIN -shared -o $(WFDBLIB_DLLNAME) \ +BUILDLIB = $(CC) NOCYGWIN -shared -o $(WFDBLIB_DLLNAME) \ -Wl,--out-implib=$(WFDBLIB) \ -Wl,--export-all-symbols \ -Wl,--enable-auto-import @@ -130,14 +130,14 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) - cd $(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) - mkdir -p $(BINDIR); $(SETDPERMISSIONS) $(BINDIR) - cp $(WFDBLIB_DLLNAME) $(BINDIR) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_BASENAME) + cd $(DESTDIR)$(LIBDIR); ln -sf $(WFDBLIB) $(WFDBLIB_SONAME) + mkdir -p $(DESTDIR)$(BINDIR); $(SETDPERMISSIONS) $(DESTDIR)$(BINDIR) + cp $(WFDBLIB_DLLNAME) $(DESTDIR)$(BINDIR) lib-post-uninstall: - rm -f $(LIBDIR)/$(WFDBLIB_BASENAME) - rm -f $(LIBDIR)/$(WFDBLIB_SONAME) - rm -f $(BINDIR)/$(WFDBLIB_DLLNAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_BASENAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_SONAME) + rm -f $(DESTDIR)$(BINDIR)/$(WFDBLIB_DLLNAME) #______________________________________________________________________________ diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/mingw.def wfdb-10.6.0/conf/mingw.def --- wfdb-10.5.24/conf/mingw.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/mingw.def 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: mingw.def I. Henry and G. Moody 11 February 2005 -# Last revised: 19 November 2013 +# Last revised: 8 March 2017 # # This file contains default 'make' definitions for compiling the WFDB Software # Package under MS Windows using the free Mininmalist GNU for Windows (MinGW) @@ -95,11 +95,11 @@ # CFLAGS is the set of C compiler options. CFLAGS should always include # CCDEFS. -CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(LL) # WFDBLIB is the name of the standard WFDB library. In order to access it via # `-lwfdb', WFDBLIB should be `libwfdb.a'. diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/solaris-slib.def wfdb-10.6.0/conf/solaris-slib.def --- wfdb-10.5.24/conf/solaris-slib.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/solaris-slib.def 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: solaris-slib.def G. Moody 31 May 2000 -# Last revised: 13 August 2014 +# Last revised: 8 March 2017 # This section contains settings suitable for generating a shared library under # Solaris. @@ -55,7 +55,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(RPATHFLAGS) $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(RPATHFLAGS) $(LL) # CC is the name of your C compiler. CC = gcc @@ -72,7 +72,7 @@ # CFLAGS is the set of C compiler options used when compiling the shared # library. CFLAGS should always include CCDEFS. These settings are for use # with gcc: -CFLAGS = $(MFLAGS) -fpic -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -fpic -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # For SunOS cc, uncomment the next line. MFLAGS is gcc-specific, thus excluded. # CFLAGS = -pic -O $(CCDEFS) $(LC) -I$(INCDIR) # For Solaris or SVR4 cc, uncomment the next line. @@ -128,11 +128,11 @@ # `make lib-post-install' should be run after installing the WFDB library. lib-post-install: - cd $(LIBDIR); rm $(WFDBLIB_BASENAME) $(WFDBLIB_SONAME); \ + cd $(DESTDIR)$(LIBDIR); rm $(WFDBLIB_BASENAME) $(WFDBLIB_SONAME); \ ln -s $(WFDBLIB) $(WFDBLIB_BASENAME); \ ln -s $(WFDBLIB) $(WFDBLIB_SONAME) lib-post-uninstall: - rm -f $(LIBDIR)/$(WFDBLIB_BASENAME) - rm -f $(LIBDIR)/$(WFDBLIB_SONAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_BASENAME) + rm -f $(DESTDIR)$(LIBDIR)/$(WFDBLIB_SONAME) #______________________________________________________________________________ diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/solaris.def wfdb-10.6.0/conf/solaris.def --- wfdb-10.5.24/conf/solaris.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/solaris.def 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: solaris.def G. Moody 31 May 2000 -# Last revised: 13 August 2014 +# Last revised: 8 March 2017 # 'make' definitions for compiling the WFDB Software Package under Solaris # Choose a value for WFDBROOT to determine where the WFDB Software Package will @@ -81,7 +81,7 @@ # use -g and -O simultaneously. MFLAGS is gcc-specific. # CFLAGS = -O $(CCDEFS) $(LC) -I$(INCDIR) # `gcc' users may comment out the previous line, and uncomment the next one. -CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(DESTDIR)$(INCDIR) # RPATHFLAGS is a set of C compiler options that cause the program to # search for shared libraries in a non-standard location at run-time. @@ -90,7 +90,7 @@ # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. -LDFLAGS = -L$(LIBDIR) -lwfdb $(LL) +LDFLAGS = -L$(DESTDIR)$(LIBDIR) -lwfdb $(LL) # WFDBLIB is the name of the standard WFDB library. In order to access it via # `-lwfdb', WFDBLIB should be `libwfdb.a'. diff -Naur '--exclude=Makefile' wfdb-10.5.24/conf/version.def wfdb-10.6.0/conf/version.def --- wfdb-10.5.24/conf/version.def 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/conf/version.def 2018-01-26 16:43:04.000000000 -0500 @@ -1,12 +1,12 @@ # file: version.def G. Moody 24 May 2000 -# Last revised: 12 July 2010 +# Last revised: 25 January 2018 # Each release of the WFDB Software Package is identified by a three-part # version number, defined below. Be sure to leave a single space before # and after the "=" in each of the next three lines! MAJOR = VMAJ MINOR = VMIN RELEASE = VREL -VERSION = $(MAJOR).$(MINOR).$(RELEASE) +VERSION = VTAG # RPMRELEASE can be incremented if changes are made between official # releases. It should be reset to 1 whenever the VERSION is changed. @@ -17,6 +17,6 @@ VDEFS = -DWFDB_MAJOR=$(MAJOR) -DWFDB_MINOR=$(MINOR) -DWFDB_RELEASE=$(RELEASE) # WAVEVERSION is the WAVE version number. -WAVEVERSION = 6.11 +WAVEVERSION = 6.12 # _____________________________________________________________________________ diff -Naur '--exclude=Makefile' wfdb-10.5.24/configure wfdb-10.6.0/configure --- wfdb-10.5.24/configure 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/configure 2018-01-25 18:16:19.000000000 -0500 @@ -1,6 +1,6 @@ #! /bin/sh # file: configure G. Moody 24 May 2000 -# Last revised: 19 May 2015 +# Last revised: 25 January 2018 # Configuration script for the WFDB Software Package # This script was not generated using 'autoconf'. If you can implement @@ -18,10 +18,12 @@ DIR=/usr/local MANDIR=unknown LIBDIR=unknown +HOST= MFLAGS= NETLIB=unknown WAVE=unknown +OWHOME=/usr/openwin LC_ALL=C export LC_ALL @@ -41,18 +43,22 @@ else MFLAGS="$MFLAGS $i" fi ;; + --host=*) HOST=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` ;; --mandir=*) MANDIR=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` ;; --prefix=*) DIR=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` ;; --libdir=*) LIBDIR=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` ;; -q) ;; # ignored --shared) LIBTYPE=dynamic ;; - --static) LIBTYPE=static ;; + --static) LIBTYPE=static + SYSLIBS=dynamic ;; --static_only) LIBTYPE=static SYSLIBS=static ;; --without-cygwin) NOCYGWIN=yes ;; --without-netfiles) NETLIB=none ;; --with-libcurl) NETLIB=libcurl ;; - --with-libwww) NETLIB=libwww ;; + --without-xview) WAVE=0 ;; + --with-xview=*) OWHOME=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` + WAVE=1 ;; *) cat <gitver.t1` + rm -f gitver.t1 + if [ "x$VERSION" = "x" ] + then + echo "unknown" + else + echo "$VERSION" + fi +fi +if [ "x$VERSION" = "x" ] +then + VERSION=`echo "$PACKAGE" | sed s/^wfdb-//` +fi MAJOR= MINOR= RELEASE= -case $PACKAGE in - wfdb-*) MAJOR=`echo $PACKAGE | cut -c6- | cut -d . -f 1` - MINOR=`echo $PACKAGE | cut -c6- | cut -d . -f 2` - RELEASE=`echo $PACKAGE | cut -c6- | cut -d . -f 3` ;; - *) ./prompt "Major version number: "; read MAJOR - ./prompt "Minor version number: "; read MINOR - ./prompt "Release number: "; read RELEASE ;; +VNUM=`echo "$VERSION" | sed 's/[^0-9.].*//'` +case $VNUM in + *.*.*) MAJOR=`echo $VNUM | cut -d . -f 1` + MINOR=`echo $VNUM | cut -d . -f 2` + RELEASE=`echo $VNUM | cut -d . -f 3` ;; + *) ./prompt "Major version number: "; read MAJOR + ./prompt "Minor version number: "; read MINOR + ./prompt "Release number: "; read RELEASE + VERSION=$MAJOR.$MINOR.$RELEASE ;; esac if [ "x$MAJOR" = "x" ]; then MAJOR=0; fi @@ -140,7 +193,7 @@ if [ "x$RELEASE" = "x" ]; then RELEASE=0; fi sed s/VMAJ/$MAJOR/ site.def + sed s/VREL/$RELEASE/ | sed "s/VTAG/$VERSION/" >site.def echo "# Definitions generated by 'configure'" >>site.def echo >>site.def echo "PACKAGE = $PACKAGE" >>site.def @@ -150,6 +203,13 @@ echo YEAR = `date '+%Y'` >>site.def echo "ARCH = $ARCH" >>site.def +if [ "x$HOST" = "x" ] +then + echo "BUILD_CC = \$(CC)" >> site.def +else + echo "BUILD_CC = cc" >> site.def +fi + echo "# _____________________________________________________________________________" >>site.def echo >>site.def @@ -201,12 +261,7 @@ sed 's/NOCYGWIN/-mno-cygwin/' mingw.def >>site.def ;; Darwin) echo "It is normal for Mac OS X to be recognized as Darwin." - if [ x$LIBTYPE != xdynamic ] - then - echo "Building static libraries is not supported on Darwin." - LIBTYPE=dynamic - fi - case `uname -m` in + case $MACHINE in x86_64) LMFLAGS="$MFLAGS -arch i386 -arch x86_64" WMFLAGS="$MFLAGS -arch i386" ;; i386) LMFLAGS="$MFLAGS -arch i386" @@ -276,7 +331,7 @@ else SYSLIBS=dynamic - dynamic_ldflags=`sed -n '/^LDFLAGS =/{s/LDFLAGS = *//;p}' site.tmp mv site.tmp site.def @@ -285,14 +340,18 @@ echo ./prompt "Looking for the C compiler ..." -WCC=`which gcc 2>&1` +if [ "x$HOST" != "x" ] +then + CROSS_COMPILE=$HOST- +fi +WCC=`which ${CROSS_COMPILE}gcc 2>&1` if [ "x$WCC" = "x" ] then WCC="no gcc" fi if ( echo $WCC | egrep "no |not |unknown " >wcc.t1 ) then - WCC=`which cc 2>&1` + WCC=`which ${CROSS_COMPILE}cc 2>&1` if [ "x$WCC" = "x" ] then WCC="no cc" @@ -304,22 +363,51 @@ echo "The WFDB software cannot be compiled, because there does not" echo "appear to be a C compiler installed on this system. Please" echo "install one, be sure that it is in your PATH, and that it is" - echo "accessible as either 'cc' or 'gcc', then run ./configure again." + echo "accessible as either '${CROSS_COMPILE}cc' or '${CROSS_COMPILE}gcc', then run ./configure again." cd .. exit else - sed "s/CC = gcc/CC = cc/" site.tmp - mv site.tmp site.def - sed "s/CC = gcc/CC = cc/" site.tmp - mv site.tmp site-slib.def - CC=cc + CC=${CROSS_COMPILE}cc fi else - CC=gcc + CC=${CROSS_COMPILE}gcc fi echo "$CC" +sed "s|CC = gcc|CC = $CC|" site.tmp +mv site.tmp site.def +sed "s|CC = gcc|CC = $CC|" site.tmp +mv site.tmp site-slib.def rm -f wcc.t1 wcc.t2 +./prompt "Looking for the command to strip debugging metadata ..." +WSTRIP=`which ${CROSS_COMPILE}strip 2>&1` +if [ "x$WSTRIP" = "x" ] +then + WSTRIP="no strip" +fi +if ( echo $WSTRIP | egrep "no |not |unknown " >wstrip.t1 ) +then + STRIP=: + echo "not found" +else + STRIP=${CROSS_COMPILE}strip + echo "$STRIP" +fi +rm -f wstrip.t1 +if [ "x$STRIP" != "xstrip" ] +then + sed "s|^STRIP = .*|STRIP = $STRIP|" site.tmp + mv site.tmp site.def + sed "s|^STRIP = .*|STRIP = $STRIP|" site.tmp + mv site.tmp site-slib.def +fi + +if [ $LIBTYPE = static ] && [ "x${CROSS_COMPILE}" != "x" ] +then + sed "s|^RANLIB = ranlib|RANLIB = ${CROSS_COMPILE}ranlib|" site.tmp + mv site.tmp site.def +fi + if [ x$DIR = x ] then echo @@ -364,9 +452,8 @@ then case $OS in Linux*) - cpu=`uname -m` nativelibdirs=`$CC -print-search-dirs | sed -n '/^libraries:/{s/^[^=]*=//; s/:/\n/g; p}' | sed ':LP; s+/[^/]*/\.\./+/+; tLP; s+/$++'` - if [ "$cpu" = "x86_64" ] && echo "$nativelibdirs" | grep -q "^$DIR/lib64"; then + if [ "$MACHINE" = "x86_64" ] && echo "$nativelibdirs" | grep -q "^$DIR/lib64"; then if [ "x$MFLAGS" = "x-m32" ]; then LIB=lib else @@ -444,26 +531,11 @@ if ( echo $WHICH | egrep "no |not |unknown " >which.t1 ) then echo "not found" - ./prompt "Looking for libwww ..." - WHICH=`which libwww-config 2>&1` - if [ "x$WHICH" = "x" ] - then - WHICH="no libwww-config" - fi - if ( echo $WHICH | egrep "no |not |unknown " >which.t2 ) - then - echo "not found" - echo "The WFDB software will be compiled without NETFILES" - echo "access, because neither libcurl nor libwww appears to" - echo "be installed on this system. To add NETFILES access," - echo "install libcurl or libwww and run ./configure again." - NETLIB=none - else - echo "found" - echo "The WFDB software will be compiled with NETFILES access" - echo "using libwww." - NETLIB=libwww - fi + echo "The WFDB software will be compiled without NETFILES" + echo "access, because libcurl does not appear to be" + echo "installed on this system. To add NETFILES access," + echo "install libcurl and run ./configure again." + NETLIB=none else echo "found" echo "The WFDB software will be compiled with NETFILES access" @@ -481,13 +553,6 @@ VIANF=" via libcurl" WITHNF=with ;; - libwww) LC="\`libwww-config --cflags\`" - LL="\`libwww-config --libs\`" - NETFILES=1 - NETFILES_LIBCURL=0 - VIANF=" via libwww" - WITHNF=with - ;; none) LC="" LL="" NETFILES=0 @@ -540,13 +605,8 @@ echo rm conf/site.def conf/site-slib.def -if [ "x$WAVE" = "x0" ] +if [ "x$WAVE" = "xunknown" ] then - cp -p wave/nomake wave/Makefile - cp -p wave/nomake waverc/Makefile - echo "WAVE=0" >>config.cache - WAVECOMP="WAVE will not be compiled." -else echo conf/prompt "Looking for the XView libraries ..." TEXTEDIT=`which textedit 2>&1` @@ -554,24 +614,21 @@ then TEXTEDIT="no textedit" fi - if [ -d /usr/openwin ] + if [ -d $OWHOME ] then WAVE=1; elif [ -d /usr/local/openwin ] then WAVE=1; - sed "s+/usr/openwin+/usr/local/openwin+" tmp.$$ - mv tmp.$$ wave/Makefile + OWHOME=/usr/local/openwin elif [ -d /opt/openwin ] then WAVE=1; - sed "s+/usr/openwin+/opt/openwin+" tmp.$$ - mv tmp.$$ wave/Makefile + OWHOME=/opt/openwin elif [ -d /usr/include/xview ] then WAVE=1; - sed "s+/usr/openwin+/usr+" tmp.$$ - mv tmp.$$ wave/Makefile + OWHOME=/usr elif ( echo $TEXTEDIT | egrep "no |not |unknown " >textedit.t1 ) then WAVE=0; @@ -579,8 +636,6 @@ WAVE=1; TEDIR=`dirname $TEXTEDIT`; OWHOME=`dirname $TEDIR`; - sed "s+/usr/openwin+$OWHOME+" tmp.$$ - mv tmp.$$ wave/Makefile fi rm -f textedit.t1 if [ $WAVE = 0 ] @@ -590,17 +645,24 @@ echo "appear to be installed on this system." echo "To compile WAVE, install XView, add the directory containing the" echo "XView textedit application to your PATH, and run ./configure again." - cp -p wave/nomake wave/Makefile - cp -p wave/nomake waverc/Makefile - echo "WAVE=0" >>config.cache - WAVECOMP="WAVE will not be compiled." else echo "found" - WAVECOMP="WAVE will be compiled and installed in '$DIR/bin'." - echo "WAVE=1" >>config.cache fi fi +if [ "x$WAVE" = "x1" ] + then + sed "s+/usr/openwin+$OWHOME+" tmp.$$ + mv tmp.$$ wave/Makefile + WAVECOMP="WAVE will be compiled and installed in '$DIR/bin'." + echo "WAVE=1" >>config.cache +else + cp -p wave/nomake wave/Makefile + cp -p wave/nomake waverc/Makefile + echo "WAVE=0" >>config.cache + WAVECOMP="WAVE will not be compiled." +fi + # Clean up old *.o files in lib, to avoid possibly using binaries intended # for a shared library in a static library or vice versa. rm -f lib/*.o diff -Naur '--exclude=Makefile' wfdb-10.5.24/convert/Makefile.tpl wfdb-10.6.0/convert/Makefile.tpl --- wfdb-10.5.24/convert/Makefile.tpl 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/convert/Makefile.tpl 2017-03-09 18:13:18.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 5 March 2014 +# Last revised: 8 March 2017 # This section of the Makefile should not need to be changed. CFILES = a2m.c ad2m.c ahaecg2mit.c m2a.c md2a.c readid.c makeid.c edf2mit.c \ @@ -20,16 +20,16 @@ $(STRIP) $(XFILES) # `make' or `make install': build and install applications -install: $(BINDIR) all $(SCRIPTS) +install: $(DESTDIR)$(BINDIR) all $(SCRIPTS) $(SETXPERMISSIONS) $(XFILES) $(SCRIPTS) - ../install.sh $(BINDIR) $(XFILES) $(SCRIPTS) + ../install.sh $(DESTDIR)$(BINDIR) $(XFILES) $(SCRIPTS) # 'make collect': retrieve the installed applications collect: ../conf/collect.sh $(BINDIR) $(XFILES) $(SCRIPTS) uninstall: - ../uninstall.sh $(BINDIR) $(XFILES) $(SCRIPTS) + ../uninstall.sh $(DESTDIR)$(BINDIR) $(XFILES) $(SCRIPTS) # `make clean': remove intermediate and backup files clean: @@ -40,5 +40,6 @@ $(PRINT) README $(MFILES) $(CFILES) # Create directory for installation if necessary. -$(BINDIR): - mkdir -p $(BINDIR); $(SETDPERMISSIONS) $(BINDIR) +$(DESTDIR)$(BINDIR): + mkdir -p $(DESTDIR)$(BINDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(BINDIR) diff -Naur '--exclude=Makefile' wfdb-10.5.24/convert/ahaecg2mit.c wfdb-10.6.0/convert/ahaecg2mit.c --- wfdb-10.5.24/convert/ahaecg2mit.c 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/convert/ahaecg2mit.c 2017-12-11 15:55:32.000000000 -0500 @@ -1,5 +1,5 @@ /* file: ahaecg2mit.c G. Moody 7 May 2008 - Last revised: 11 July 2012 + Last revised: 11 December 2017 Convert *.ecg or *.txt files from an AHA Database DVD to WFDB-compatible format */ @@ -30,8 +30,8 @@ int readtxtdata(void) { - char buf[16]; - int c, i, n; + char buf[16], c; + int i, n; for (i = 0; i < sizeof(buf); i++) { c = getc(ifile); diff -Naur '--exclude=Makefile' wfdb-10.5.24/convert/parsescp.c wfdb-10.6.0/convert/parsescp.c --- wfdb-10.5.24/convert/parsescp.c 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/convert/parsescp.c 2017-12-11 15:55:32.000000000 -0500 @@ -1,5 +1,5 @@ /* file: parsescp.c G. Moody and E. Moody 10 January 2000 - Last revised: 8 March 2014 + Last revised: 11 December 2017 ------------------------------------------------------------------------------- parsescp: parse an SCP-ECG file (read from the standard input) Copyright (C) 2000-2014 George B. Moody and Edna S. Moody @@ -242,6 +242,10 @@ #ifndef NOWFDB #include #endif +#ifdef _WINDOWS +#include +#include +#endif #define VERSION_STRING "#ECG/1.0" #define min(A, B) (((A) <= (B)) ? (A) : (B)) @@ -906,9 +910,14 @@ } } +#ifdef _WINDOWS + _setmode(_fileno(stdin), _O_BINARY); + if (aflag) _setmode(_fileno(stdout), _O_BINARY); +#endif + bytesread = fread(header, 1, 6, stdin); if (bytesread != 6) { - fprintf(stderr, "%s: input too short (only %d bytes)\n", + fprintf(stderr, "%s: input too short (only %lu bytes)\n", pname, bytesread); exit(1); } @@ -925,7 +934,7 @@ while (!ferror(stdin) && bytesread < length && i > 0) bytesread += i = fread(data+bytesread, 1, length-bytesread, stdin); if (bytesread < length) { - fprintf(stderr, "%s: input too short (%d byte%s missing)\n", + fprintf(stderr, "%s: input too short (%lu byte%s missing)\n", pname, length-bytesread, (length-bytesread == 1) ? "" : "s"); exit(3); } @@ -943,8 +952,8 @@ if (sec_len < 8) { if (vflag) printf( " Warning: section length too short (must be at least 8 bytes)\n" - " Remaining data (%d bytes) following short section will not be read\n", - data+length-(p+8)); + " Remaining data (%lu bytes) following short section will not be read\n", + (unsigned long) (data+length-(p+8))); sec_len = 8; // break; /* don't attempt to read any further */ } @@ -1275,7 +1284,7 @@ if (*p == 255) break; /* tag 255 is the terminator */ vlen = get16(p+1); if (vlen > len) { - if (vflag) printf(" Error: tagged field (%d bytes) overlaps next section\n"); + if (vflag) printf(" Error: tagged field overlaps next section\n"); return (0); } switch (*p) { @@ -1623,7 +1632,7 @@ if ((nsamp=(unsigned long *)malloc((nleads+4)*sizeof(unsigned long))) == NULL){ - if (vflag) printf(" Error: too many (%ld) leads\n", nleads); + if (vflag) printf(" Error: too many (%d) leads\n", nleads); return (0); } @@ -1666,7 +1675,7 @@ } else if (vflag) printf(" "); - if (vflag) printf(": ID %d, samples %d to %d\n", *(p+8), + if (vflag) printf(": ID %d, samples %lu to %lu\n", *(p+8), get32(p), get32(p+4)); nsamp[i++] = get32(p+4) - get32(p) + 1; p += 9; len -= 9; @@ -1675,7 +1684,7 @@ /* allocate space for 4 extra signals that will be calculated later, and for a NULL pointer to signal the end of the array */ if ((ecg = (short **)malloc((nleads+5)*sizeof(short *))) == NULL) { - if (vflag) printf(" Error: too many (%ld) leads\n", nleads); + if (vflag) printf(" Error: too many (%d) leads\n", nleads); return (0); } @@ -1684,7 +1693,7 @@ else if (nsamp[i] > nsmax) nsmax = nsamp[i]; if (nsamp[i] < 1) nsamp[i] = 1; if ((ecg[i] = (short *)calloc(nsamp[i], sizeof(short))) == NULL) { - if (vflag) printf(" Error: too many (%ld) leads\n", nleads); + if (vflag) printf(" Error: too many (%d) leads\n", nleads); return (0); } } @@ -1707,7 +1716,7 @@ fcM = get16(p+2); nqrs = get16(p+4); if (vflag) { - printf(" Length of reference beat type 0 data: %d msec\n", rblenms); + printf(" Length of reference beat type 0 data: %ld msec\n", rblenms); printf( " Sample # of fiducial relative to start of ref beat type 0: %d\n", fcM); @@ -1735,7 +1744,8 @@ if (vflag) { printf( - " %2d Type: %2d start: %7d fiducial: %7d end: %7d\n", + " %2d Type: %2d start: %7ld" + " fiducial: %7ld end: %7ld\n", i+1, subz[i].type, subz[i].t0, subz[i].t1, subz[i].t2); if (subz[i].type != 0 && (subz[i].t0 != 0 || subz[i].t2 != 0)) @@ -1753,7 +1763,7 @@ if (len >= nqrs*8) { if (vflag) printf(" QRS locations:\n"); for (i = 0; i < nqrs; i++) { - if (vflag) printf(" %2d start: %7d end: %7d\n", + if (vflag) printf(" %2d start: %7lu end: %7lu\n", i+1, get32(p), get32(p+4)); p += 8; len -= 8; } @@ -1978,17 +1988,17 @@ return (0); } if ((leadlen=(unsigned long *)malloc(nleads*sizeof(unsigned long)))==NULL){ - if (vflag) printf(" Error: too many (%ld) leads\n", nleads); + if (vflag) printf(" Error: too many (%d) leads\n", nleads); return (0); } for (i = 0; i < nleads; i++, p += 2, len -= 2) { tleadlen += leadlen[i] = get16(p); - if (vflag) printf(" Lead %d:%5d bytes\n", i, leadlen[i]); + if (vflag) printf(" Lead %d:%5lu bytes\n", i, leadlen[i]); } if (len < tleadlen) { - if (vflag) printf(" Error: %d data byte%s missing from section %d\n", + if (vflag) printf(" Error: %lu data byte%s missing from section %d\n", tleadlen - len, (tleadlen - len == 1) ? "" : "s", section); @@ -1997,7 +2007,7 @@ } else if (len > ((tleadlen + 1) & ~1)) /* the expression above rounds tleadlen up to an even number */ - if (vflag) printf(" Warning: %d extra byte%s in section %d\n", + if (vflag) printf(" Warning: %lu extra byte%s in section %d\n", len - tleadlen, (len - tleadlen == 1) ? "" : "s", section); @@ -2060,7 +2070,7 @@ if (xflag && vflag) hexdump(p, len); if (len < 20) { /* there isn't enough room left for measurements */ - if (vflag) printf(" Error: section 7 is too short (len = %d)\n", len); + if (vflag) printf(" Error: section 7 is too short (len = %ld)\n", len); return (0); } @@ -2167,7 +2177,7 @@ #endif - printf("%d bytes remaining in section 7\n", len - (q - p)); + printf("%ld bytes remaining in section 7\n", len - (q - p)); while (q < p + len) { printf(" %5d", get16(q)); printf(" [%3d]", *q++); diff -Naur '--exclude=Makefile' wfdb-10.5.24/convert/wfdb2mat.c wfdb-10.6.0/convert/wfdb2mat.c --- wfdb-10.5.24/convert/wfdb2mat.c 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/convert/wfdb2mat.c 2018-01-23 18:59:01.000000000 -0500 @@ -1,5 +1,5 @@ /* file: wfdb2mat.c G. Moody 26 February 2009 - Last revised: 8 December 2013 + Last revised: 23 January 2018 ------------------------------------------------------------------------------- wfdb2mat: Convert (all or part of) a WFDB signal file to Matlab .mat format Copyright (C) 2009-2013 George B. Moody @@ -44,7 +44,7 @@ record, as specified using the -f option). If this seems odd, transpose your matrix after reading it! -This program writes version 4 MAT-file format output files, as documented in +This program writes version 5 MAT-file format output files, as documented in http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf The samples are written as 32-bit signed integers (mattype=20 below) in little-endian format if the record contains any format 24 or format 32 signals, @@ -52,10 +52,11 @@ signals, or as 16-bit signed integers in little-endian format (mattype=30) otherwise. -Although version 5 and newer versions of Matlab normally use a different (less -compact and more complex) format, they can read these files without difficulty. -The advantage of version 4 MAT-file format, apart from compactness and -portability, is that files in these formats are still WFDB-compatible, given +The maximum size of the output variable is 2^31 bytes. wfdb2mat from versions +10.5.24 and earlier of the WFDB software package writes version 4 MAT files +which have the additional constraint of 100,000,000 elements per variable. + +The output files (recordm.mat + recordm.hea) are still WFDB-compatible, given the .hea file constructed by this program. Example: @@ -75,11 +76,12 @@ #include #include -/* Output .mat file types (values of mattype), defined by the .mat format - specification, see above */ -#define MAT8 50 /* 8 bits per sample */ -#define MAT16 30 /* 16 bits per sample */ -#define MAT32 20 /* 32 bits per sample */ +/* Output .mat data storage types (values of mattype), defined by the + .mat format specification. These variables are for the sub4 tag + data STORAGE type. */ +#define MAT8 2 /* 8 bits per sample unsigned */ +#define MAT16 3 /* 16 bits per sample signed */ +#define MAT32 5 /* 32 bits per sample signed */ char *pname; @@ -88,9 +90,36 @@ char *argv[]; { char *matname, *orec, *p, *q, *record = NULL, *search = NULL, *prog_name(); - static char prolog[24]; + + /* The entire file is composed of: + - 128 byte descriptive text + - 8 byte master tag. 4 bytes indicate data type = matrix, 4 + bytes indicate data size. + - 4 subelements. Each subelement has a 4 byte tag giving the + data type of the elements, a 4 byte tag giving the subelement + size, and the subelement's actual content. + - Subelement 1: array flags (8 + 8 bytes) + - Subelement 2: array dimension (8 + 8 bytes) + - Subelement 3: array name (8 + 8 bytes) + - Subelement 4: array content (8 + ?? bytes) + */ + static char prolog[192]; /* 128 byte descriptive text + + 64 bytes of fixed length content */ + /* mastertype=matrix, sub1type=UINT32, sub2type=INT32, sub3type=INT8 + fieldversion=0x0100 indicating mat file */ int highres = 0, i, isiglist, mattype, nisig, nosig = 0, pflag = 0, - s, sfname = 0, *sig = NULL, stat = 0, vflag = 0, wfdbtype; + mastertype = 14, sub1type = 6, sub2type = 5, sub3type = 1, sub4type, + fieldversion = 256, s, sfname = 0, *sig = NULL, stat = 0, vflag = 0, + sub1class = 6, nbytesperelement, wfdbtype, offset; + + /* nbytesmaster is the value specified in the master tag + representing the size of all following content. + nbytesofdata gives the number of bytes of signal data. + lremain stores the number of bytes to pad to make the file size + a multiple of 8. + max_length is the maximum permissible signal length. */ + unsigned long nbytesmaster, nbytesofdata, lremain, max_length; + WFDB_Frequency freq; WFDB_Sample *vi, *vo; WFDB_Siginfo *si, *so; @@ -257,21 +286,43 @@ /* Determine if we can write 8-bit unsigned samples, or if 16 or 32 bits are needed per sample. */ - mattype = MAT8; - wfdbtype = 80; - for (i = 0; i < nosig; i++) - switch (si[sig[i]].fmt) { - case 24: - case 32: mattype = MAT32; wfdbtype = 32; break; - case 80: break; - default: if (mattype != MAT32) mattype = MAT16; wfdbtype = 16; break; + nbytesperelement = 1; + for (i = 0; i < nosig; i++) { + if (si[sig[i]].adcres > 0) { + if (si[sig[i]].adcres > 16) + nbytesperelement = 4; + else if (si[sig[i]].adcres > 8 && nbytesperelement < 2) + nbytesperelement = 2; } + else { + /* adcres not specified; try to guess from format */ + if (si[sig[i]].fmt == 24 || si[sig[i]].fmt == 32) + nbytesperelement = 4; + else if (si[sig[i]].fmt != 80 && nbytesperelement < 2) + nbytesperelement = 2; + } + } + if (nbytesperelement == 1) { + sub4type = MAT8; + wfdbtype = 80; + } + else if (nbytesperelement == 2) { + sub4type = MAT16; + wfdbtype = 16; + } + else { + sub4type = MAT32; + wfdbtype = 32; + } + for (i = 0; i < nosig; i++) { so[i] = si[sig[i]]; so[i].fname = matname; so[i].group = 0; so[i].spf = 1; so[i].fmt = wfdbtype; + so[i].adczero = 0; + so[i].baseline -= si[sig[i]].adczero; /* handle possibly missing units strings */ if (so[i].units == NULL) { /* in a .hea file, missing units can be assumed to be millivolts */ @@ -284,6 +335,32 @@ } } + + /* Ensure the signal size does not exceed 2^31 byte limit */ + max_length = 2147483648/nbytesperelement/nosig; + if ((to - from) > max_length){ + (void)fprintf(stderr, "%s: cannot write mat file -" + " data size exceeds 2GB limit\n", pname); + exit(1); + } + + nbytesofdata = nbytesperelement*nosig*(to-from); /* Bytes of actual data */ + lremain = nbytesofdata%8; /* This is the remaining no. bytes that + don't fit into integer multiple of + 8. ie if 18 bytes, lremain=2, from 17 + to 18. */ + + /* nbytesmaster= (8 + 8) + (8 + 8) + (8 + 8) + (8 + nbytesofdata) + padding. + Must be integer multiple 8. */ + if (lremain==0){ + nbytesmaster = nbytesofdata + 56; + } + else{ + nbytesmaster = nbytesofdata + 64 - (lremain); + for (i = 0; i < nosig; i++) + so[i].bsize = 8; + } + /* Create an empty .mat file. */ if (osigfopen(so, nosig) != nosig) { wfdbquit(); /* failed to open output, quit */ @@ -291,26 +368,73 @@ } /* Fill in the .mat file's prolog and write it. (Elements of prolog[] - not set explicitly below are always zero.) */ - prolog[ 0] = mattype & 0xff; /* format */ - prolog[ 1] = (mattype >> 8) & 0xff; - prolog[ 4] = nosig & 0xff; /* number of rows */ - prolog[ 5] = (nosig >> 8) & 0xff; - prolog[ 6] = (nosig >> 16) & 0xff; - prolog[ 7] = (nosig >> 24) & 0xff; - prolog[ 8] = (to - from) & 0xff; /* number of columns */ - prolog[ 9] = ((to - from) >> 8) & 0xff; - prolog[10] = ((to - from) >> 16) & 0xff; - prolog[11] = ((to - from) >> 24) & 0xff; - prolog[16] = 4; /* strlen("val") + 1 */ - sprintf(prolog+20, "val"); - wfdbputprolog((char *)prolog, 24, 0); + not set explicitly below are always zero.) */ + + /* Start with 128 byte header */ + sprintf(prolog, "MATLAB 5.0"); /* First 116 bits are descriptive text */ + prolog[124] = fieldversion & 0xff; /* Bytes 125-126 indicate version, + set to 0x0100 hex = 256.*/ + prolog[125] = (fieldversion >> 8) & 0xff; + sprintf(prolog + 126, "I"); /* Characters IM to indicate little endian */ + sprintf(prolog + 127, "M"); + + /* 8 byte MASTER TAG, followed by the actual data. + First 4 is data type, next 4 is number of bytes of entire field. */ + prolog[128] = mastertype & 0xff; /* Data type is always 14 for matrix. */ + /* Number of bytes of data element + = (8 + 8) + (8 + 8) + (8 + 8) + (8 + Nvalues*bytespervalue) + = 56 + Nvalues*bytespervalue */ + prolog[132] = nbytesmaster & 0xff; + prolog[133] = (nbytesmaster >> 8) & 0xff; + prolog[134] = (nbytesmaster >> 16) & 0xff; + prolog[135] = (nbytesmaster >> 24) & 0xff; + + /* Matrix data has 4 subelements (5 if imag): + Array flags, dimensions array, array name, real part. + Each subelement has its own subtag, and subdata. */ + + /* Subelement 1: Array flags. */ + prolog[136] = (sub1type & 0xff); /* Sub tag 1: type */ + prolog[140] = 8 & 0xff; /* Sub tag 1: size */ + prolog[144] = sub1class & 0xff; /*Value class, indicating the MATLAB + data type. NOT the same as sub4type. */ + + /* Subelement 2: Rows and Cols */ + prolog[152] = sub2type & 0xff; /* Sub tag 2: type */ + prolog[156] = 8 & 0xff; /* sub tag 2: size */ + prolog[160] = nosig & 0xff; /* Number of signals. */ + prolog[161] = (nosig >> 8) & 0xff; + prolog[162] = (nosig >> 16) & 0xff; + prolog[163] = (nosig >> 24) & 0xff; + prolog[164] = (to - from) & 0xff; /* Value nrows. */ + prolog[165] = ((to - from) >> 8) & 0xff; + prolog[166] = ((to - from) >> 16) & 0xff; + prolog[167] = ((to - from) >> 24) & 0xff; + + /* Subelement 3: Array Name */ + prolog[168] = sub3type & 0xff; + prolog[172] = 3 & 0xff; + sprintf(prolog + 176, "val"); + + /* Subelement 4: Data itself */ + prolog[184] = sub4type & 0xff; + prolog[188] = nbytesofdata & 0xff; + prolog[189] = (nbytesofdata >> 8) & 0xff; + prolog[190] = (nbytesofdata >> 16) & 0xff; + prolog[191] = (nbytesofdata >> 24) & 0xff; + + /* Total size of everything before actual data: + 128 byte header + + 8 byte master tag + + 56 byte Subelements (48 byte default + 8 byte name) + = 192. */ + wfdbputprolog((char *)prolog, 192, 0); /* Copy the selected data into the .mat file. */ for (t = from; t < to && stat >= 0; t++) { stat = getvec(vi); for (i = 0; i < nosig; i++) - vo[i] = vi[sig[i]]; + vo[i] = vi[sig[i]] - si[sig[i]].adczero; if (putvec(vo) != nosig) break; } @@ -349,6 +473,13 @@ } (void)putinfo(p); + /* Determine offset between sample values and the raw byte/word + values as interpreted by Matlab/Octave. */ + if (wfdbtype == 80) + offset = 128; + else + offset = 0; + /* Summarize the contents of the .mat file. */ printf("%s\n", p); printf("val has %d row%s (signal%s) and %ld column%s (sample%s/signal)\n", @@ -360,9 +491,10 @@ printf("Row\tSignal\tGain\tBase\tUnits\n"); for (i = 0; i < nosig; i++) printf("%d\t%s\t%.12g\t%d\t%s\n", i+1, so[i].desc, so[i].gain, - so[i].baseline, so[i].units); + so[i].baseline + offset, so[i].units); printf("\nTo convert from raw units to the physical units shown\n" - "above, subtract 'base' and divide by 'gain'.\n"); + "above, call the 'rdmat.m' function from the wfdb-matlab\n" + "toolbox: https://physionet.org/physiotools/matlab/wfdb-app-matlab/\n"); SFREE(p); wfdbquit(); diff -Naur '--exclude=Makefile' wfdb-10.5.24/data/Makefile.tpl wfdb-10.6.0/data/Makefile.tpl --- wfdb-10.5.24/data/Makefile.tpl 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/data/Makefile.tpl 2017-03-09 18:13:19.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 23 May 2000 -# Last revised: 23 February 2003 +# Last revised: 8 March 2017 # This section of the Makefile should not need to be changed. DBFILES = 100a.atr 100s.atr 100s.dat *.hea *list wfdbcal @@ -7,14 +7,14 @@ all: @echo Nothing to be made in `pwd`. -install: $(DBDIR) $(DBDIR)/pipe $(DBDIR)/tape - cp $(DBFILES) $(DBDIR) - cp pipe/* $(DBDIR)/pipe - cp tape/* $(DBDIR)/tape - -cd $(DBDIR); $(SETPERMISSIONS) $(DBFILES) - -cd $(DBDIR); ln -sf wfdbcal dbcal - -cd $(DBDIR)/pipe; $(SETPERMISSIONS) * - -cd $(DBDIR)/tape; $(SETPERMISSIONS) * +install: $(DESTDIR)$(DBDIR) $(DESTDIR)$(DBDIR)/pipe $(DESTDIR)$(DBDIR)/tape + cp $(DBFILES) $(DESTDIR)$(DBDIR) + cp pipe/* $(DESTDIR)$(DBDIR)/pipe + cp tape/* $(DESTDIR)$(DBDIR)/tape + -cd $(DESTDIR)$(DBDIR); $(SETPERMISSIONS) $(DBFILES) + -cd $(DESTDIR)$(DBDIR); ln -sf wfdbcal dbcal + -cd $(DESTDIR)$(DBDIR)/pipe; $(SETPERMISSIONS) * + -cd $(DESTDIR)$(DBDIR)/tape; $(SETPERMISSIONS) * # 'make collect': retrieve the installed files collect: @@ -23,14 +23,19 @@ cd tape; ../../conf/collect.sh $(DBDIR)/tape * uninstall: - ../uninstall.sh $(DBDIR) $(DBFILES) dbcal - -$(DBDIR): - mkdir $(DBDIR); $(SETDPERMISSIONS) $(DBDIR) -$(DBDIR)/pipe: - mkdir $(DBDIR)/pipe; $(SETDPERMISSIONS) $(DBDIR)/pipe -$(DBDIR)/tape: - mkdir $(DBDIR)/tape; $(SETDPERMISSIONS) $(DBDIR)/tape + cd pipe; ../../uninstall.sh $(DESTDIR)$(DBDIR)/pipe * + cd tape; ../../uninstall.sh $(DESTDIR)$(DBDIR)/tape * + ../uninstall.sh $(DESTDIR)$(DBDIR) $(DBFILES) dbcal + +$(DESTDIR)$(DBDIR): + mkdir -p $(DESTDIR)$(DBDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(DBDIR) +$(DESTDIR)$(DBDIR)/pipe: $(DESTDIR)$(DBDIR) + mkdir -p $(DESTDIR)$(DBDIR)/pipe + $(SETDPERMISSIONS) $(DESTDIR)$(DBDIR)/pipe +$(DESTDIR)$(DBDIR)/tape: $(DESTDIR)$(DBDIR) + mkdir -p $(DESTDIR)$(DBDIR)/tape + $(SETDPERMISSIONS) $(DESTDIR)$(DBDIR)/tape listing: $(PRINT) README Makefile makefile.dos diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/Makefile.tpl wfdb-10.6.0/doc/Makefile.tpl --- wfdb-10.5.24/doc/Makefile.tpl 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/doc/Makefile.tpl 2017-10-27 11:13:00.000000000 -0400 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 12 March 2014 +# Last revised: 25 October 2017 # Change the settings below as appropriate for your setup. # Set COLORS to 'color' if you have a color printer and would like to print @@ -98,8 +98,6 @@ # It should not be necessary to modify anything below this line. # ----------------------------------------------------------------------------- -.IGNORE: - all: @echo "Type 'make install' to install the man pages." @echo "Type 'make uninstall' to remove previously installed man pages." diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/wag-src/Makefile.tpl wfdb-10.6.0/doc/wag-src/Makefile.tpl --- wfdb-10.5.24/doc/wag-src/Makefile.tpl 2015-05-28 15:55:13.000000000 -0400 +++ wfdb-10.6.0/doc/wag-src/Makefile.tpl 2017-12-07 14:13:40.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 8 May 2015 +# Last revised: 7 December 2017 # Change the settings below as appropriate for your setup. # D2PARGS is a list of options for dvips. Uncomment one of these to set the @@ -20,16 +20,16 @@ # section 1 (commands), section 3 (libraries), section 5 (formats), and # section 7 (conventions and miscellany) go. You may wish to use # $(MANDIR)/manl for all of these; if so, uncomment the next four lines. -# MAN1 = $(MANDIR)/manl -# MAN3 = $(MANDIR)/manl -# MAN5 = $(MANDIR)/manl -# MAN7 = $(MANDIR)/manl +# MAN1 = $(DESTDIR)$(MANDIR)/manl +# MAN3 = $(DESTDIR)$(MANDIR)/manl +# MAN5 = $(DESTDIR)$(MANDIR)/manl +# MAN7 = $(DESTDIR)$(MANDIR)/manl # Uncomment the next four lines to put the man pages in with the standard # ones. -MAN1 = $(MANDIR)/man1 -MAN3 = $(MANDIR)/man3 -MAN5 = $(MANDIR)/man5 -MAN7 = $(MANDIR)/man7 +MAN1 = $(DESTDIR)$(MANDIR)/man1 +MAN3 = $(DESTDIR)$(MANDIR)/man3 +MAN5 = $(DESTDIR)$(MANDIR)/man5 +MAN7 = $(DESTDIR)$(MANDIR)/man7 # If you want to put the man pages somewhere else, edit 'maninst.sh' first. # PSPRINT is the name of the program that prints PostScript files. If your @@ -67,8 +67,6 @@ # It should not be necessary to modify anything below this line. # ----------------------------------------------------------------------------- -.IGNORE: - all: wag.html wag.pdf cp -p wag.pdf ../wag @@ -80,7 +78,7 @@ uninstall: ../../uninstall.sh $(MAN1) *.1 ad2m.1 ahaconvert.1 ahaecg2mit.1 \ ann2rr.1 m2a.1 md2a.1 hrlomb.1 hrmem.1 hrplot.1 plot3d.1 cshsetwfdb.1 \ - rr2ann.1 + rr2ann.1 gqpost.1 mit2edf.1 mit2wav.1 pNNx.1 ../../uninstall.sh $(MAN3) *.3 ../../uninstall.sh $(MAN5) *.5 ../../uninstall.sh $(MAN7) *.7 @@ -101,9 +99,11 @@ ./manhtml.sh ../wag *.1 *.3 *.5 *.7 cp -p install0.tex install.tex cp -p eval0.tex eval.tex - latex2html -dir ../wag -local_icons -prefix in \ + latex2html -init_file ./.latex2html-init \ + -dir ../wag -local_icons -prefix in \ -up_url="wag.htm" -up_title="WFDB Applications Guide" install - latex2html -dir ../wag -local_icons -prefix ev \ + latex2html -init_file ./.latex2html-init \ + -dir ../wag -local_icons -prefix ev \ -up_url="wag.htm" -up_title="WFDB Applications Guide" eval rm -f install.tex eval.tex cd ../wag; rm -f index.html WARNINGS *.aux *.log *.tex @@ -130,6 +130,7 @@ cd $(MAN1); $(LN) a2m.1 md2a.1 cd $(MAN1); $(LN) ann2rr.1 rr2ann.1 cd $(MAN1); $(LN) edf2mit.1 mit2edf.1 + cd $(MAN1); $(LN) gqrs.1 gqpost.1 cd $(MAN1); $(LN) hrfft.1 hrlomb.1 cd $(MAN1); $(LN) hrfft.1 hrmem.1 cd $(MAN1); $(LN) hrfft.1 hrplot.1 @@ -169,6 +170,12 @@ sed "s/VERSION/$(VERSION)/" >wag4.tex pdflatex '\nonstopmode\input{wag4}' +getpagenos: getpagenos.c + $(BUILD_CC) -o getpagenos -O getpagenos.c + +maketoclines: maketoclines.c + $(BUILD_CC) -o maketoclines -O maketoclines.c + # 'make clean': remove intermediate and backup files clean: rm -f *.aux *.dvi *.log *.ps *.toc intro.htm faq.htm wag*pdf wagcover \ diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/wag-src/manhtml.sh wfdb-10.6.0/doc/wag-src/manhtml.sh --- wfdb-10.5.24/doc/wag-src/manhtml.sh 2015-05-28 15:55:14.000000000 -0400 +++ wfdb-10.6.0/doc/wag-src/manhtml.sh 2017-10-27 11:13:00.000000000 -0400 @@ -1,10 +1,12 @@ #!/bin/sh # file: manhtml G. Moody 18 October 1996 -# Last revised: 18 December 2001 +# Last revised: 25 October 2017 # # This script uses `rman' to convert man pages to HTML pages, with # hyperlinked cross-references. +set -e + case $# in 0|1) echo usage: $0 html-dir manpage-filename; exit ;; esac diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/wag-src/wave.1 wfdb-10.6.0/doc/wag-src/wave.1 --- wfdb-10.5.24/doc/wag-src/wave.1 2015-05-28 15:55:14.000000000 -0400 +++ wfdb-10.6.0/doc/wag-src/wave.1 2017-08-15 13:58:25.000000000 -0400 @@ -342,9 +342,36 @@ \fBWave.View.AmplitudeScale:2\fR to the X11 resource database. .TP \fBWave.View.TimeScale\fR (\fB-Vt\fR) -Set the time scale (0: 50 mm/min; 1: 125 mm/min; 2: 250 mm/min; 3: 500 mm/min; -4: 12.5 mm/sec; 5: 25 mm/sec (default); 6: 50 mm/sec; 7: 125 mm/sec; -8: 250 mm/sec). +Set the time scale: +.TS +l l. +\fB-Vt 0\fR 0.25 mm/hour +\fB-Vt 1\fR 1 mm/hour +\fB-Vt 2\fR 5 mm/hour +\fB-Vt 3\fR 0.25 mm/min +\fB-Vt 4\fR 1 mm/min +\fB-Vt 5\fR 5 mm/min +\fB-Vt 6\fR 25 mm/min +\fB-Vt 7\fR 50 mm/min +\fB-Vt 8\fR 125 mm/min +\fB-Vt 9\fR 250 mm/min +\fB-Vt 10\fR 500 mm/min +\fB-Vt 11\fR 12.5 mm/sec +\fB-Vt 12\fR 25 mm/sec (default) +\fB-Vt 13\fR 50 mm/sec +\fB-Vt 14\fR 125 mm/sec +\fB-Vt 15\fR 250 mm/sec +\fB-Vt 16\fR 500 mm/sec +\fB-Vt 17\fR 1000 mm/sec +\fB-Vt 18\fR 2000 mm/sec +\fB-Vt 19\fR 5000 mm/sec +\fB-Vt 20\fR 10 mm/ms +\fB-Vt 21\fR 20 mm/ms +\fB-Vt 22\fR 50 mm/ms +\fB-Vt 23\fR 100 mm/ms +\fB-Vt 24\fR 200 mm/ms +\fB-Vt 25\fR 500 mm/ms +.TE .TP \fBWave.View.AmplitudeScale\fR (\fB-Vv\fR) Set the amplitude scale (0: 1 mm/mV; 1: 2.5 mm/mV; 2: 5 mm/mV; 3: 10 mm/mV diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/wag-src/wfdb.3 wfdb-10.6.0/doc/wag-src/wfdb.3 --- wfdb-10.5.24/doc/wag-src/wfdb.3 2015-05-28 15:55:14.000000000 -0400 +++ wfdb-10.6.0/doc/wag-src/wfdb.3 2017-11-03 15:35:06.000000000 -0400 @@ -1,4 +1,4 @@ -.TH WFDB 3 "1 July 2010" "WFDB software 10.5.4" "WFDB Applications Guide" +.TH WFDB 3 "3 November 2017" "WFDB software 10.6.0" "WFDB Applications Guide" .SH NAME wfdb \- Waveform Database library .SH SYNOPSIS @@ -36,6 +36,10 @@ .br int getgvmode(void) .br +WFDB_Frequency getiafreq(WFDB_Annotator \fIa\fP) +.br +WFDB_Frequency getiaorigfreq(WFDB_Annotator \fIa\fP) +.br WFDB_Frequency getifreq(void) .br int getseginfo(WFDB_Seginfo **segments) @@ -102,6 +106,8 @@ .br void setcfreq(WFDB_Frequency \fIcounter_frequency\fP) .br +void setiafreq(WFDB_Annotator \fIa\fP, WFDB_Frequency \fIannotation_clock_frequency\fP) +.br int setifreq(WFDB_Frequency \fIgetvec_frequency\fP) .br void setwfdb(char *\fIdatabase_path_string\fP) diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/wag-src/wfdb2mat.1 wfdb-10.6.0/doc/wag-src/wfdb2mat.1 --- wfdb-10.5.24/doc/wag-src/wfdb2mat.1 2015-05-28 15:55:14.000000000 -0400 +++ wfdb-10.6.0/doc/wag-src/wfdb2mat.1 2016-11-02 18:17:24.000000000 -0400 @@ -2,7 +2,7 @@ .SH NAME wfdb2mat \- convert WFDB-compatible signal file to Matlab .mat file .SH SYNOPSIS -\fBwfdb2mat -i\fR \fIrecord\fR [ \fIoptions\fR ... ] +\fBwfdb2mat -r\fR \fIrecord\fR [ \fIoptions\fR ... ] .SH DESCRIPTION .PP This program converts the signals of any PhysioBank record (or one in diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/wag-src/wfdbf.3 wfdb-10.6.0/doc/wag-src/wfdbf.3 --- wfdb-10.5.24/doc/wag-src/wfdbf.3 2015-05-28 15:55:14.000000000 -0400 +++ wfdb-10.6.0/doc/wag-src/wfdbf.3 2017-11-03 15:35:06.000000000 -0400 @@ -1,14 +1,14 @@ -.TH WFDBF 3 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" +.TH WFDBF 3 "3 November 2017" "WFDB 10.6.0" "WFDB Applications Guide" .SH NAME wfdbf \- Waveform Database library wrappers for Fortran .SH SYNOPSIS implicit integer(a-z) .br -real aduphys, getbasecount, getcfreq, getifreq, sampfreq +real aduphys, getbasecount, getcfreq, getifreq, sampfreq, getafreq, getiafreq, getiaorigfreq .br -character aux(256), desc(80), filetype(32), fname(40), name(20), pathname(80), record(16), string(32), units(20) +character aux(256), desc(80), filetype(32), fname(40), name(20), pathname(80), record(16), string(32), units(20), prolog(1000), version(80), options(80) .br -integer a, adcres, adczero, ampl, anntyp, baseline, bsize, caltype, chan, cksum, date, dummy, fmt, group, initval, microvolts, mode, nann, nsamp, nsig, num, s, spf, stat, subtyp, time, v(32), value +integer a, adcres, adczero, ampl, anntyp, baseline, bsize, caltype, chan, cksum, date, dummy, fmt, group, initval, microvolts, mode, nann, nsamp, nsig, num, s, spf, stat, subtyp, time, v(32), value, bytes .br real gain, frequency, high, low, scale .PP @@ -28,8 +28,12 @@ .br wfdbinit(record, nann, nsig) .br +findsig(desc) +.br setgvmode(mode) .br +getgvmode(dummy) +.br getspf(dummy) .br getvec(v) @@ -48,6 +52,8 @@ .br isgsettime(group, time) .br +tnextvec(s, time) +.br iannsettime(time) .br ecgstr(code, string) @@ -66,6 +72,16 @@ .br setanndesc(code, string) .br +setafreq(frequency) +.br +getafreq(dummy) +.br +setiafreq(a, frequency) +.br +getiafreq(a) +.br +getiaorigfreq(a) +.br iannclose(a) .br oannclose(a) @@ -88,6 +104,10 @@ .br physadu(s, value) .br +sample(s, time) +.br +sample_valid(dummy) +.br calopen(fname) .br getcal(desc, units, low, high, scale, caltype) @@ -102,18 +122,26 @@ .br putinfo(string) .br +setinfo(record) +.br +wfdb_freeinfo(dummy) +.br newheader(record) .br setheader(record, nsig) .br wfdbgetskew(s) .br +wfdbsetiskew(s, value) +.br wfdbsetskew(s, value) .br wfdbgetstart(s) .br wfdbsetstart(s, value) .br +wfdbputprolog(prolog, bytes, s) +.br wfdbquit(dummy) .br sampfreq(record) @@ -144,6 +172,8 @@ .br getwfdb(string) .br +resetwfdb(dummy) +.br setibsize(value) .br setobsize(value) @@ -152,6 +182,18 @@ .br wfdbflush(dummy) .br +wfdbmemerr(mode) +.br +wfdbversion(version) +.br +wfdbldflags(options) +.br +wfdbcflags(options) +.br +wfdbdefwfdb(string) +.br +wfdbdefwfdbcal(fname) +.br isann(anntyp) .br isqrs(anntyp) diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/wpg-src/Makefile.tpl wfdb-10.6.0/doc/wpg-src/Makefile.tpl --- wfdb-10.5.24/doc/wpg-src/Makefile.tpl 2015-05-28 15:55:14.000000000 -0400 +++ wfdb-10.6.0/doc/wpg-src/Makefile.tpl 2017-10-27 11:13:00.000000000 -0400 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 13 March 2014 +# Last revised: 25 October 2017 # Change the settings below as appropriate for your setup. # D2PARGS is a list of options for dvips. Uncomment one of these to set the @@ -32,7 +32,7 @@ # them. If you have GNU 'makeinfo' and 'install-info' (preferred), # uncomment the next two lines. MAKEINFO = makeinfo --force --no-warn -INSTALLINFO = /usr/sbin/install-info --info-dir=$(INFODIR) $(INFODIR)/wpg +INSTALLINFO = install-info --info-dir=$(DESTDIR)$(INFODIR) $(DESTDIR)$(INFODIR)/wpg # Otherwise, you can use GNU emacs to do the formatting, and standard utilities # to install the info files, by uncommenting the next two lines. @@ -60,8 +60,6 @@ # It should not be necessary to modify anything below this line. # ----------------------------------------------------------------------------- -.IGNORE: - all: wpg.html wpg.pdf $(MAKE) INFODIR=../wpg/info INSTALLINFO=: wpg.info cp -p wpg.pdf ../wpg @@ -104,17 +102,17 @@ # 'make wpg.info': format the WFDB Programmer's Guide as info files wpg.info: wpg.tex $(MAKEINFO) wpg.tex - test -d $(INFODIR) || \ - ( mkdir -p $(INFODIR); $(SETDPERMISSIONS) $(INFODIR) ) - cp wpg wpg-* $(INFODIR) - $(SETPERMISSIONS) $(INFODIR)/wpg* + test -d $(DESTDIR)$(INFODIR) || \ + ( mkdir -p $(DESTDIR)$(INFODIR); $(SETDPERMISSIONS) $(DESTDIR)$(INFODIR) ) + cp wpg wpg-* $(DESTDIR)$(INFODIR) + $(SETPERMISSIONS) $(DESTDIR)$(INFODIR)/wpg* rm -f wpg wpg-* - $(INSTALLINFO) + PATH=$$PATH:/usr/sbin; $(INSTALLINFO) # 'make install-wpg.info': install info entry (if install-info is unavailable) install-wpg.info: wpg.info - test -s $(INFODIR)/dir || cp dir.top $(INFODIR)/dir - grep -s wpg $(INFODIR)/dir >/dev/null || cat dir.wpg >>$(INFODIR)/dir + test -s $(DESTDIR)$(INFODIR)/dir || cp dir.top $(DESTDIR)$(INFODIR)/dir + grep -s wpg $(DESTDIR)$(INFODIR)/dir >/dev/null || cat dir.wpg >>$(DESTDIR)$(INFODIR)/dir # 'make wpg.info.tar.gz': create a tarball of info files wpg.info.tar.gz: wpg.tex diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/wpg-src/wpg0.tex wfdb-10.6.0/doc/wpg-src/wpg0.tex --- wfdb-10.5.24/doc/wpg-src/wpg0.tex 2015-05-28 15:55:15.000000000 -0400 +++ wfdb-10.6.0/doc/wpg-src/wpg0.tex 2018-01-26 16:43:40.000000000 -0500 @@ -632,25 +632,21 @@ @cindex NETFILES @cindex curl @cindex libcurl -@cindex libwww -@cindex W3C libwww If the WFDB library was installed with NETFILES support, it will make use of -functions contained in the @code{libcurl} or @code{libwww} libraries. If you -have dynamically linkable versions of the @code{libcurl} or @code{libwww} -libraries, as under GNU/Linux, these will be loaded automatically when you run -@code{psamples}. If you have only static versions of these libraries, however, -it is necessary to provide additional arguments in the @code{cc} command line -in order to compile successfully. One way to do this is to follow the model -used to compile the standard WFDB applications supplied with the WFDB library; -see @file{Makefile} in the @file{app} directory of the WFDB software package -source tree. - -If you are using WFDB version 10.2.6 or a later version and @file{gcc} -or a compatible compiler, the @file{wfdb-config} utility is available -to help construct commands for compiling programs that use the WFDB -library (and the @code{libcurl} or @code{libwww} libraries, if available). -Use it like this: +functions contained in the @code{libcurl} library. If you have a dynamically +linkable version of the @code{libcurl} library, as under GNU/Linux, these will +be loaded automatically when you run @code{psamples}. If you have only static +versions of these libraries, however, it is necessary to provide additional +arguments in the @code{cc} command line in order to compile successfully. One +way to do this is to follow the model used to compile the standard WFDB +applications supplied with the WFDB library; see @file{Makefile} in the +@file{app} directory of the WFDB software package source tree. + +If you are using WFDB version 10.2.6 or a later version and @file{gcc} or a +compatible compiler, the @file{wfdb-config} utility is available to help +construct commands for compiling programs that use the WFDB library (and the +@code{libcurl} library, if available). Use it like this: @example gcc `wfdb-config --cflags` -o psamples psamples.c `wfdb-config --libs` @@ -660,7 +656,7 @@ Note that this command contains backticks (`), not apostrophes ('). @file{wfdb-config} is particularly useful if the WFDB library or its @file{*.h} files are installed in non-standard locations, or if -you have only static @code{libcurl} or @code{libwww} libraries. +you have only a static @code{libcurl} library. Under MS-Windows, @file{gcc} is included in the freely available Cygwin software development system (@uref{http://@-www@-.cygwin@-.com/}), and also in @@ -1103,15 +1099,13 @@ @cindex NETFILES @cindex curl @cindex libcurl -@cindex libwww -@cindex W3C libwww The WFDB path may contain @uref{http://} and @code{ftp://} URL prefixes (other schema, such as @code{file://} and @code{https://}, may also be supported if -they are supported by your version of @code{libcurl} or @code{libwww}). If -NETFILES support is not compiled into the WFDB library, any WFDB path -components containing @file{://} are ignored. (These features were first -introduced in WFDB library version 10.1.0.) +they are supported by your version of @code{libcurl}). If NETFILES support is +not compiled into the WFDB library, any WFDB path components containing +@file{://} are ignored. (These features were first introduced in WFDB library +version 10.1.0.) @cindex indirect WFDB path @cindex file containing WFDB path @@ -1748,6 +1742,12 @@ record and how invalid samples are represented. * getgvmode:: Determining the getvec operating mode. * getspf:: Determining the number of samples per frame. +* setiafreq:: Setting the time resolution of input + annotations. +* getiafreq:: Determining the time resolution of input + annotations. +* getiaorigfreq:: Determining the underlying time resolution + of an annotation file. * setafreq:: Setting the time resolution for output annotations. * getafreq:: Determining the time resolution for output @@ -1772,9 +1772,8 @@ This function sets the current input sampling frequency (in samples per second per signal). It should be invoked after opening the input signals (using @code{isigopen} or @code{wfdbinit}), and before using any -of @code{getvec}, @code{getann}, @code{putann}, @code{isigsettime}, -@code{isgsettime}, @code{timstr}, @code{mstimstr}, @code{strtim}, -or @code{annopen}. +of @code{getvec}, @code{putann}, @code{isigsettime}, @code{isgsettime}, +@code{timstr}, @code{mstimstr}, or @code{strtim}. @emph{Note that the operation of @code{getframe} is unaffected by @code{setifreq}.} @@ -1933,7 +1932,7 @@ @file{}. @c @group -@node getspf, setafreq, getgvmode, special I/O modes +@node getspf, setiafreq, getgvmode, special I/O modes @unnumberedsubsec getspf @findex getspf (9.6) @cindex interpolation @@ -1960,7 +1959,85 @@ samples per signal per frame (hence @code{sampfreq(NULL)/getspf()} is the number of frames per second). -@node setafreq, getafreq, getspf, special I/O modes +@node setiafreq, getiafreq, getspf, special I/O modes +@unnumberedsubsec setiafreq +@findex setiafreq (10.6.0) +@cindex interpolation +@cindex decimation +@cindex resampling +@cindex multi-frequency records (reading) + +@example +void setiafreq(WFDB_Annotator @var{an}, WFDB_Frequency @var{frequency}) +@end example +@noindent + +@noindent +This function sets the time resolution (number of ticks per second) used by +@code{getann} and @code{ungetann} for the given input annotator. By default, +the time resolution equals the input sampling frequency (@pxref{getifreq}) at +the time @code{annopen} is called. After calling this function, the @code{time} +fields of subsequent annotations will be scaled according to the new time +resolution. + +@node getiafreq, getiaorigfreq, setiafreq, special I/O modes +@unnumberedsubsec getiafreq +@findex getiafreq (10.6.0) +@cindex interpolation +@cindex decimation +@cindex resampling +@cindex multi-frequency records (reading) + +@example +WFDB_Frequency getiafreq(WFDB_Annotator @var{an}) +@end example +@noindent +@strong{Return:} +@table @asis +@item @t{(WFDB_Frequency)>0.} +Success: the annotation time resolution in Hz +@item @t{(WFDB_Frequency)-2.} +Failure: incorrect annotator number specified +@end table + +@noindent +This function returns the current time resolution of the given input annotator. +The time resolution equals the input sampling frequency by default, but may be +changed (@pxref{setiafreq}). + +@node getiaorigfreq, setafreq, getiafreq, special I/O modes +@unnumberedsubsec getiaorigfreq +@findex getiaorigfreq (10.6.0) +@cindex interpolation +@cindex decimation +@cindex resampling +@cindex multi-frequency records (reading) + +@example +WFDB_Frequency getiaorigfreq(WFDB_Annotator @var{an}) +@end example +@noindent +@strong{Return:} +@table @asis +@item @t{(WFDB_Frequency)>0.} +Success: the annotation time resolution in Hz +@item @t{(WFDB_Frequency)0.} +Failure: the annotation time resolution is not defined +@item @t{(WFDB_Frequency)-2.} +Failure: incorrect annotator number specified +@end table + +@noindent +This function returns the original time resolution for the given input +annotator, if it was specified by the application that created the annotation +file (@pxref{setafreq}). + +@noindent +If the application that created the annotation file did not specify a time +resolution, @code{getiaorigfreq} returns zero. (In this case, the time +resolution is assumed to equal the record's frame frequency.) + +@node setafreq, getafreq, getiaorigfreq, special I/O modes @unnumberedsubsec setafreq @findex setafreq (10.4.5) @cindex interpolation @@ -5937,22 +6014,15 @@ @cindex WFDB path @cindex curl @cindex libcurl -@cindex libwww -@cindex W3C libwww If the symbol @code{WFDB_NETFILES} is defined at the time the WFDB library is compiled, then input files located on remote web (HTTP) and FTP servers can be -read directly. This capability was originally implemented using the World Wide -Web Consortium's @code{libwww} library (which is available on many of the -platforms supported by the WFDB library). In WFDB library version 10.3.16 and -later, this capability can alternatively be provided by the @code{libcurl} -library, which is smaller, faster, and more robust than @code{libwww}, and is -actively supported and its creators on all of the popular platforms and many -others as well. NETFILES support, if available, is transparent to WFDB -applications. To make use of this feature, simply link to the NETFILES-enabled -WFDB library (the necessary @code{libcurl} or @code{libwww} functions will be -loaded automatically), and incorporate one or more URL prefixes in the WFDB -path. +read directly. This capability is implemented using the @code{libcurl} library +(which is available on many of the platforms supported by the WFDB library). +NETFILES support, if available, is transparent to WFDB applications. To make +use of this feature, simply link to the NETFILES-enabled WFDB library (the +necessary @code{libcurl} functions will be loaded automatically), and +incorporate one or more URL prefixes in the WFDB path. @cindex WFDB path @cindex PhysioBank @@ -5970,17 +6040,16 @@ by passing @code{slpdb/slp37} as the @var{record} argument to @code{wfdbinit} (or @code{isigopen}, @code{annopen}, etc.). -Current implementations of @code{libcurl} and @code{libwww} permit input from -@code{http://} URLs in much the same way that local files are read, provided -that the remote web server supports HTTP 1.1 range requests (most, including -PhysioNet's, do). This means that it is not necessary to download an entire -file in order to examine part of it, and you may notice little or no speed -difference between local file and network file input for many applications. If -the remote server does not support range requests, however, or if input is from -an @code{ftp://} URL, the current implementations download the entire file to -memory, so you may notice a significant startup delay if the file is long and -your network connection is slow, or if the file does not fit into physical -memory. +The current implementation of @code{libcurl} permits input from @code{http://} +URLs in much the same way that local files are read, provided that the remote +web server supports HTTP 1.1 range requests (most, including PhysioNet's, do). +This means that it is not necessary to download an entire file in order to +examine part of it, and you may notice little or no speed difference between +local file and network file input for many applications. If the remote server +does not support range requests, however, or if input is from an @code{ftp://} +URL, the current implementations download the entire file to memory, so you may +notice a significant startup delay if the file is long and your network +connection is slow, or if the file does not fit into physical memory. Currently, NETFILES support is limited to input files; as always, any output files created by the WFDB library are written into the current directory, @@ -7788,16 +7857,13 @@ @cindex NETFILES (defined) @cindex curl @cindex libcurl -@cindex libwww -@cindex W3C libwww WFDB files made available by an FTP or HTTP (web) server; readable by applications linked with a NETFILES-enabled WFDB library. A NETFILES-enabled WFDB library can be created by compiling the WFDB library sources with the symbol @code{WFDB_NETFILES} defined (to anything; its value is not important, only that it is defined) and then linking -them with the @code{libwww} library available from the World Wide Web -Consortium (@uref{http://www.w3.org/Library/}) or the @code{libcurl} -library available from @uref{http://curl.haxx.se/}. +them with the @code{libcurl} library available from +@uref{http://curl.haxx.se/}. @item 9-track tape @cindex nine-track tape (defined) @@ -8037,18 +8103,15 @@ @cindex curl @cindex libcurl -@cindex libwww -@cindex W3C libwww @enumerate @item @emph{Install any prerequisites needed for your platform.} These include @code{gcc} (the GNU Compiler Collection), related software development tools -such as @code{make}, a supported HTTP client library (either @code{libcurl} or -@code{libwww}; this can be omitted if NETFILES support is not desired), the -XView libraries (needed for WAVE only), and X11 (needed by XView). All of these -components are free (open-source) software available for all popular platforms, -including GNU/Linux, Mac OS X, MS Windows, and Unix. The quick start guides -list recommended packages and where to find them. +such as @code{make}, the @code{libcurl} library (if NETFILES support is +desired), the XView libraries (needed for WAVE only), and X11 (needed by +XView). All of these components are free (open-source) software available for +all popular platforms, including GNU/Linux, Mac OS X, MS Windows, and Unix. The +quick start guides list recommended packages and where to find them. @item @emph{Download and unpack the WFDB Software Package.} Versions for all @@ -8590,8 +8653,6 @@ @table @emph @cindex MIT DB @cindex waveform editor -@cindex libwww -@cindex W3C libwww @cindex XView toolkit @item WFDB Programmer's Guide (this guide) @itemx WFDB Applications Guide @@ -8604,7 +8665,6 @@ @item Long-Term ST Database @itemx Other reference databases of physiologic signals @itemx WFDB Software Package -@itemx W3C libwww sources @itemx XView toolkit (needed for WAVE) @sp 1 @display @@ -8784,8 +8844,8 @@ @end display The @code{libcurl} library is a modern and enhanced replacement for the -@code{libwww} libraries (see below). Only one of @code{libcurl} and -@code{libwww} is needed for NETFILES support. +@code{libwww} libraries (see below). It provides the low-level functions needed +to support the WFDB library's (optional) NETFILES capability. @cindex libwww @cindex W3C libwww @@ -8796,10 +8856,10 @@ WWW: @uref{http://www.w3.org/Library/} @end display -The @code{libwww} libraries, created and maintained by the World Wide -Web Consortium, provide the low-level functions needed to support -the WFDB library's (optional) NETFILES capability. The @code{libwww} -libraries are also available from PhysioNet. +The @code{libwww} libraries, created and maintained by the World Wide Web +Consortium, were used in the original implementation of NETFILES. Since these +libraries are no longer maintained, the WFDB library now uses @code{libcurl} +instead. @cindex X11 @cindex X Window System @@ -9049,8 +9109,120 @@ WFDB Software Package distribution, for information on any more recent changes that may not be described here. +@unnumberedsec WFDB 10.6 + +@unnumberedsubsec Changes in version 10.6.0 (26 January 2018) + +The new functions @code{getiafreq()} and @code{setiafreq()} allow the +application to change the time scale for input annotations, as +@code{setifreq()} does for input signals. The new function +@code{getiaorigfreq()} returns the ``native'' time resolution of the input +file. + +New macros, defined in @file{wfdb.h}, can be used to determine the limits of +the numeric types used by the WFDB library. For example, +@code{WFDB_SAMPLE_MAX} is the maximum value of a @code{WFDB_Sample} variable. + +@file{wfdb.h} now includes prototypes for the internal functions +@code{wfdb_me_fatal()} and @code{wfdb_error()}, which are used by the +@code{MEMERR} macro. + +Support for using @code{libwww} to read remote files has been removed. +@code{libwww} support was introduced with version 10.0.1 in 2000, and was still +supported as an alternative after @code{libcurl} support was added in version +10.3.16. However, @code{libwww} has not been actively developed for many +years; we don't recommend its use anymore, and removing support is necessary in +order to simplify and add new features to WFDB in the future. + +The WFDB library now supports reading variable-layout, @emph{multi-frequency} +records, provided that each signal's sampling frequency is constant across the +entire record. Although previous versions of the library were able to read +such records in some cases, the behavior of @code{getvec()} and +@code{isigsettime()} was buggy and inconsistent. + +When reading a variable-layout multi-segment record, values returned by +@code{getvec()}, @code{getframe()}, or @code{sample()} are rounded to the +nearest integer. If that value is outside the range of a @code{WFDB_Sample} +variable, the value @code{WFDB_SAMPLE_MIN} or @code{WFDB_SAMPLE_MAX} is +returned. + +When reading a signal from an EDF file in which the minimum representable value +is greater than zero (corresponding to a negative baseline), the +@code{baseline} returned by @code{isigopen()} is correctly rounded to the +nearest integer. In previous versions, the baseline was off by 1, causing +applications to calculate an incorrect physical value. + +When reading a signal file in format 311, the file may end with two samples +encoded as three bytes (so the total number of samples is @math{3n+2}, and the +total number of bytes is @math{4n+3}.) Files created by the WFDB library +itself do not use this format (an extra zero sample will be added in this case, +for backwards compatibility), but such files may be created by other +applications. + +@code{isigsettime()} works correctly when reading a multi-segment record with +multiple signal files per segment. + +@code{setifreq()} works correctly if there are no input signals open. + +@code{tnextvec()} returns -1 if it reaches the end of the record without +finding a valid sample. Previously, in the case of a fixed-layout record, it +would return zero in this case. + +@code{getann()} correctly handles annotation files with huge @code{time} values +(where the unscaled value exceeds the range of a @code{WFDB_Time} variable.) +If the @emph{scaled} value exceeds that range, it is replaced with +@code{WFDB_TIME_MIN} or @code{WFDB_TIME_MAX}. @code{getann()} will also +correctly round the @code{time} value if it is negative, and will correctly +handle non-NOTE annotations at time @emph{zero}. + +If an input annotation file has no explicit time resolution, but the +application calls @code{setifreq()} before @code{annopen()}, the input +annotations will be rescaled accordingly. (In previous versions of the +library, this would only work for annotation files with an explicit time +resolution.) + +When writing signals in format 212, 310, or 311, if the total number of samples +is not a multiple of 2 or 3, @code{wfdbquit()} will correctly write out the +remaining samples, adding padding if necessary. @code{wfdbflush()} will do +likewise, provided that the output is a regular file and there is no mandatory +block size. + +When writing an annotation file, the time resolution and annotation type +definitions will not be written until the first time @code{putann()} is called +for that annotator. As a result, it is possible to call @code{setafreq()}, +@code{setannstr()}, or @code{setanndesc()}, after calling @code{annopen()} and +before the first @code{putann()}. + +@code{putann()} correctly handles consecutive annotations that are more than +2,147,483,647 samples apart. + +The Fortran wrapper functions have been updated for compatibility with modern +Fortran compilers on 64-bit systems. + +Password-protected remote files can now be accessed when WFDB_PAGESIZE is set +to zero. + @unnumberedsec WFDB 10.5 +@unnumberedsubsec Changes in version 10.5.24 (28 May 2015) + +The environment variable @code{WFDBPASSWORD} is used for user/password +information, in place of the former (inflexible and insecurely +implemented) @code{PNWUSER} and @code{PNWPASS} variables. + +The environment variable @code{CURL_CA_BUNDLE} defines the set of +certificate authorities that are trusted to issue certificates for web +servers, if any @code{https://} entries are used in the WFDB path. + +If the environment variable @code{WFDB_NET_DEBUG} is set, then +whenever the WFDB library requests or receives data from a remote +server, details of the operation will be written to the standard error +output. + +On most platforms, the library is now installed in +@file{/usr/local/lib} by default, rather than @file{/usr/local/lib64} +(as in 10.5.23) or @file{/usr/lib64} (as in previous versions.) + @unnumberedsubsec Changes in version 10.5.23 (13 March 2014) Changes in @file{configure}, @file{Makefile.tpl}, @file{conf/linux.def}, and @@ -9163,7 +9335,7 @@ has been opened). Virginia Faro-Maza identified and corrected a bug in WFDB library function -@code{iannsettime()}, in file{lib/annot.c}, that caused some annotations to be +@code{iannsettime()}, in @file{lib/annot.c}, that caused some annotations to be missed when two or more annotation files are open simultaneously. WFDB library function @code{isigopen()}, in @file{lib/signal.c}, was reverted diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/wug-src/Makefile.tpl wfdb-10.6.0/doc/wug-src/Makefile.tpl --- wfdb-10.5.24/doc/wug-src/Makefile.tpl 2015-05-28 15:55:15.000000000 -0400 +++ wfdb-10.6.0/doc/wug-src/Makefile.tpl 2017-10-27 11:13:00.000000000 -0400 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 8 May 2015 +# Last revised: 25 October 2017 # Change the settings below as appropriate for your setup. # Set COLORS to 'color' if you have a color printer and would like to print @@ -41,8 +41,6 @@ # It should not be necessary to modify anything below this line. # ----------------------------------------------------------------------------- -.IGNORE: - all: wug.html wug.pdf cp -p wug.pdf ../wug @@ -71,7 +69,8 @@ cp -p ../misc/icons/* wave/png/* ../../examples/stdev.c \ wave/misc/example.xws ../wug wave/scripts/wugfigures -color # get a set of figures - latex2html -dir ../wug -local_icons \ + latex2html -init_file ./.latex2html-init \ + -dir ../wug -local_icons \ -up_url="../manuals.shtml" -up_title="Books about PhysioToolkit" wug cp wave/scripts/dossify-html wave/scripts/fixlinks ../wug cd ../wug; ./dossify-html *.html diff -Naur '--exclude=Makefile' wfdb-10.5.24/doc/wug-src/wug0.tex wfdb-10.6.0/doc/wug-src/wug0.tex --- wfdb-10.5.24/doc/wug-src/wug0.tex 2015-05-28 15:55:15.000000000 -0400 +++ wfdb-10.6.0/doc/wug-src/wug0.tex 2017-08-15 14:01:28.000000000 -0400 @@ -6677,10 +6677,13 @@ \begin{description} \index{time scale}\index{scales!time} \item[{\tt -Vt} {\it n}] -Set the time scale (0: 0.25 mm/min, 1: 1 mm/min, 2: 5 mm/min, 3: 25 -mm/min, 4: 50 mm/min, 5: 125 mm/min, 6: 250 mm/min, 7: 500 mm/min, -8: 12.5 mm/sec, 9: 25 mm/sec (default), 10: 50 mm/sec, 11: 125 mm/sec, -12: 250 mm/sec). +Set the time scale (0: 0.25 mm/hour, 1: 1 mm/hour, 2: 5 mm/hour, 3: +0.25 mm/min, 4: 1 mm/min, 5: 5 mm/min, 6: 25 mm/min, 7: 50 mm/min, 8: +125 mm/min, 9: 250 mm/min, 10: 500 mm/min, 11: 12.5 mm/sec, 12: 25 +mm/sec (default), 13: 50 mm/sec, 14: 125 mm/sec, 15: 250 mm/sec, 16: +500 mm/sec, 17: 1000 mm/sec, 18: 2000 mm/sec, 19: 5000 mm/sec, 20: 10 +mm/ms, 21: 20 mm/ms, 22: 50 mm/ms, 23: 100 mm/ms, 24: 200 mm/ms, 25: +500 mm/ms). \index{amplitude scale}\index{scales!amplitude} \item[{\tt -Vv} {\it n}] diff -Naur '--exclude=Makefile' wfdb-10.5.24/fortran/Makefile.tpl wfdb-10.6.0/fortran/Makefile.tpl --- wfdb-10.5.24/fortran/Makefile.tpl 2015-05-28 15:55:15.000000000 -0400 +++ wfdb-10.6.0/fortran/Makefile.tpl 2017-03-09 18:13:19.000000000 -0500 @@ -15,14 +15,14 @@ # 'make install' copies the wrapper sources into the directory where the # WFDB headers are also installed. install: - ../install.sh $(INCDIR)/wfdb wfdbf.c - $(SETPERMISSIONS) $(INCDIR)/wfdb/wfdbf.c + ../install.sh $(DESTDIR)$(INCDIR)/wfdb wfdbf.c + $(SETPERMISSIONS) $(DESTDIR)$(INCDIR)/wfdb/wfdbf.c collect: ../conf/collect.sh $(INCDIR)/wfdb wfdbf.c uninstall: - ../uninstall.sh $(INCDIR)/wfdb wfdbf.c + ../uninstall.sh $(DESTDIR)$(INCDIR)/wfdb wfdbf.c clean: rm -f example example.c *.o *~ diff -Naur '--exclude=Makefile' wfdb-10.5.24/fortran/wfdbf.c wfdb-10.6.0/fortran/wfdbf.c --- wfdb-10.5.24/fortran/wfdbf.c 2015-05-28 15:55:15.000000000 -0400 +++ wfdb-10.6.0/fortran/wfdbf.c 2017-12-07 14:10:30.000000000 -0500 @@ -1,5 +1,5 @@ /* file: wfdbf.c G. Moody 23 August 1995 - Last revised: 21 July 2013 wfdblib 10.5.19 + Last revised: 7 December 2017 wfdblib 10.6.0 _______________________________________________________________________________ wfdbf: Fortran wrappers for the WFDB library functions @@ -32,7 +32,7 @@ Include the statements implicit integer(a-z) - real aduphys, getbasecount, getcfreq, sampfreq + double precision aduphys, getbasecount, getcfreq, sampfreq (or the equivalent for your dialect of Fortran) in your Fortran program to ensure that these functions (except for the four listed in the second statement) will be understood to return integer*4 values (equivalent to C @@ -64,11 +64,15 @@ # include #endif -/* If a WFDB_Sample is the same size as a long (true except for MS-DOS PCs and - a few less common systems), considerable efficiency gains are possible. - Otherwise, define REPACK below to compile the code needed to repack arrays - of DB_Samples into long arrays. */ -/* #define REPACK */ +/* Define the C types equivalent to the corresponding Fortran types. + The below definitions should be correct for modern systems; some + older Fortran compilers may use different types. */ +#ifndef INTEGER +#define INTEGER int +#endif +#ifndef DOUBLE_PRECISION +#define DOUBLE_PRECISION double +#endif /* If Fortran strings are terminated by spaces rather than by null characters, define FIXSTRINGS. */ @@ -121,7 +125,7 @@ needed in the C library. */ -long setanninfo_(long int *a, char *name, long int *stat) +INTEGER setanninfo_(INTEGER *a, char *name, INTEGER *stat) { if (0 <= *a && *a < WFDB_MAXANN*2) { ainfo[*a].name = fcstring(name); @@ -132,7 +136,7 @@ return (-1L); } -long getsiginfo_(long int *s, char *fname, char *desc, char *units, double *gain, long int *initval, long int *group, long int *fmt, long int *spf, long int *bsize, long int *adcres, long int *adczero, long int *baseline, long int *nsamp, long int *cksum) +INTEGER getsiginfo_(INTEGER *s, char *fname, char *desc, char *units, DOUBLE_PRECISION *gain, INTEGER *initval, INTEGER *group, INTEGER *fmt, INTEGER *spf, INTEGER *bsize, INTEGER *adcres, INTEGER *adczero, INTEGER *baseline, INTEGER *nsamp, INTEGER *cksum) { if (0 <= *s && *s < WFDB_MAXSIG) { fname = sinfo[*s].fname; @@ -155,7 +159,7 @@ return (-1L); } -long setsiginfo_(long int *s, char *fname, char *desc, char *units, double *gain, long int *initval, long int *group, long int *fmt, long int *spf, long int *bsize, long int *adcres, long int *adczero, long int *baseline, long int *nsamp, long int *cksum) +INTEGER setsiginfo_(INTEGER *s, char *fname, char *desc, char *units, DOUBLE_PRECISION *gain, INTEGER *initval, INTEGER *group, INTEGER *fmt, INTEGER *spf, INTEGER *bsize, INTEGER *adcres, INTEGER *adczero, INTEGER *baseline, INTEGER *nsamp, INTEGER *cksum) { if (0 <= *s && *s < WFDB_MAXSIG) { sinfo[*s].fname = fname; @@ -180,115 +184,118 @@ /* Before using annopen_, set up the annotation information structures using setanninfo_. */ -long annopen_(char *record, long int *nann) +INTEGER annopen_(char *record, INTEGER *nann) { return (annopen(fcstring(record), ainfo, (unsigned int)(*nann))); } /* After using isigopen_ or osigopen_, use getsiginfo_ to obtain the contents of the signal information structures if necessary. */ -long isigopen_(char *record, long int *nsig) +INTEGER isigopen_(char *record, INTEGER *nsig) { return (isigopen(fcstring(record), sinfo, (unsigned int)(*nsig))); } -long osigopen_(char *record, long int *nsig) +INTEGER osigopen_(char *record, INTEGER *nsig) { return (osigopen(fcstring(record), sinfo, (unsigned int)(*nsig))); } /* Before using osigfopen_, use setsiginfo_ to set the contents of the signal information structures. */ -long osigfopen_(long int *nsig) +INTEGER osigfopen_(INTEGER *nsig) { return (osigfopen(sinfo, (unsigned int)(*nsig))); } /* Before using wfdbinit_, use setanninfo_ and setsiginfo_ to set the contents of the annotation and signal information structures. */ -long wfdbinit_(char *record, long int *nann, long int *nsig) +INTEGER wfdbinit_(char *record, INTEGER *nann, INTEGER *nsig) { return (wfdbinit(fcstring(record), ainfo, (unsigned int)(*nann), sinfo, (unsigned int)(*nsig))); } -long findsig_(char *signame) +INTEGER findsig_(char *signame) { return (findsig(fcstring(signame))); } -long getspf_(long int *dummy) +INTEGER getspf_(INTEGER *dummy) { return (getspf()); } -long setgvmode_(long int *mode) +INTEGER setgvmode_(INTEGER *mode) { setgvmode((int)(*mode)); return (0L); } -long getgvmode_(long int *dummy) +INTEGER getgvmode_(INTEGER *dummy) { return (getgvmode()); } -long setifreq_(double *freq) +INTEGER setifreq_(DOUBLE_PRECISION *freq) { return (setifreq((WFDB_Frequency)*freq)); } -double getifreq_(long int *dummy) +DOUBLE_PRECISION getifreq_(INTEGER *dummy) { return (getifreq()); } -long getvec_(long int *long_vector) +INTEGER getvec_(INTEGER *long_vector) { -#ifndef REPACK - return (getvec((WFDB_Sample *)long_vector)); -#else - WFDB_Sample v[WFDB_MAXSIG]; - int i, j; - - i = getvec(v); - for (j = 0; j < i; j++) - long_vector[i] = v[i]; - return (i); -#endif + if (sizeof(WFDB_Sample) == sizeof(INTEGER)) { + return (getvec((WFDB_Sample *)long_vector)); + } + else { + WFDB_Sample v[WFDB_MAXSIG]; + int i, j; + + i = getvec(v); + for (j = 0; j < i; j++) + long_vector[i] = v[i]; + return (i); + } } -long getframe_(long int *long_vector) +INTEGER getframe_(INTEGER *long_vector) { -#ifndef REPACK - return (getframe((WFDB_Sample *)long_vector)); -#else - WFDB_Sample v[WFDB_MAXSIG*WFDB_MAXSPF]; - int i, j, k; - - i = getframe(v); - for (j = 0; j < i; j += k) - for (k = 0; k < sinfo[i].spf; k++) - long_vector[j+k] = v[j+k]; - return (i); -#endif + if (sizeof(WFDB_Sample) == sizeof(INTEGER)) { + return (getframe((WFDB_Sample *)long_vector)); + } + else { + WFDB_Sample v[WFDB_MAXSIG*WFDB_MAXSPF]; + int i, j, k; + + i = getframe(v); + for (j = 0; j < i; j += k) + for (k = 0; k < sinfo[i].spf; k++) + long_vector[j+k] = v[j+k]; + return (i); + } } -long putvec_(long int *long_vector) +INTEGER putvec_(INTEGER *long_vector) { -#ifndef REPACK - return (putvec((WFDB_Sample *)long_vector)); -#else - WFDB_Sample v[WFDB_MAXSIG*WFDB_MAXSPF]; - int i; - - for (i = 0; i < WFDB_MAXSIG*WFDB_MAXSPF; i++) - v[i] = long_vector[i]; - return (putvec(v)); -#endif + if (sizeof(WFDB_Sample) == sizeof(INTEGER)) { + return (putvec((WFDB_Sample *)long_vector)); + } + else { + WFDB_Sample v[WFDB_MAXSIG*WFDB_MAXSPF]; + int i; + + for (i = 0; i < WFDB_MAXSIG*WFDB_MAXSPF; i++) + v[i] = long_vector[i]; + return (putvec(v)); + } } -long getann_(long int *annotator, long int *time, long int *anntyp, long int *subtyp, long int *chan, long int *num, char *aux) +INTEGER getann_(INTEGER *annotator, INTEGER *time, INTEGER *anntyp, INTEGER *subtyp, INTEGER *chan, INTEGER *num, char *aux) { static WFDB_Annotation iann; int i, j; @@ -305,7 +312,7 @@ return (i); } -long ungetann_(long int *annotator, long int *time, long int *anntyp, long int *subtyp, long int *chan, long int *num, char *aux) +INTEGER ungetann_(INTEGER *annotator, INTEGER *time, INTEGER *anntyp, INTEGER *subtyp, INTEGER *chan, INTEGER *num, char *aux) { static WFDB_Annotation oann; int i, j; @@ -319,7 +326,7 @@ return (ungetann((WFDB_Annotator)(*annotator), &oann)); } -long putann_(long int *annotator, long int *time, long int *anntyp, long int *subtyp, long int *chan, long int *num, char *aux) +INTEGER putann_(INTEGER *annotator, INTEGER *time, INTEGER *anntyp, INTEGER *subtyp, INTEGER *chan, INTEGER *num, char *aux) { static WFDB_Annotation oann; int i, j; @@ -342,90 +349,106 @@ return (i); } -long isigsettime_(long int *time) +INTEGER isigsettime_(INTEGER *time) { return (isigsettime((WFDB_Time)(*time))); } -long isgsettime_(long int *group, long int *time) +INTEGER isgsettime_(INTEGER *group, INTEGER *time) { return (isgsettime((WFDB_Group)(*group), (WFDB_Time)(*time))); } -long tnextvec_(long int *signal, long int *time) +INTEGER tnextvec_(INTEGER *signal, INTEGER *time) { return (tnextvec((WFDB_Signal)(*signal), (WFDB_Time)(*time))); } -long iannsettime_(long int *time) +INTEGER iannsettime_(INTEGER *time) { return (iannsettime((WFDB_Time)(*time))); } -long ecgstr_(long int *code, char *string) +INTEGER ecgstr_(INTEGER *code, char *string) { strcpy(string, ecgstr((int)(*code))); cfstring(string); return (0L); } -long strecg_(char *string) +INTEGER strecg_(char *string) { return (strecg(fcstring(string))); } -long setecgstr_(long int *code, char *string) +INTEGER setecgstr_(INTEGER *code, char *string) { return (setecgstr((int)(*code), fcstring(string))); } -long annstr_(long int *code, char *string) +INTEGER annstr_(INTEGER *code, char *string) { strcpy(string, annstr((int)(*code))); cfstring(string); return (0L); } -long strann_(char *string) +INTEGER strann_(char *string) { return (strann(fcstring(string))); } -long setannstr_(long int *code, char *string) +INTEGER setannstr_(INTEGER *code, char *string) { return (setannstr((int)(*code), fcstring(string))); } -long anndesc_(long int *code, char *string) +INTEGER anndesc_(INTEGER *code, char *string) { strcpy(string, anndesc((int)(*code))); cfstring(string); return (0L); } -long setanndesc_(long int *code, char *string) +INTEGER setanndesc_(INTEGER *code, char *string) { return (setanndesc((int)(*code), fcstring(string))); } -long setafreq_(double *freq) +INTEGER setafreq_(DOUBLE_PRECISION *freq) { setafreq(*freq); return (0L); } -double getafreq_(long int *dummy) +DOUBLE_PRECISION getafreq_(INTEGER *dummy) { return (getafreq()); } -long iannclose_(long int *annotator) +INTEGER setiafreq_(INTEGER *annotator, DOUBLE_PRECISION *freq) +{ + setiafreq(*annotator, *freq); + return (0L); +} + +DOUBLE_PRECISION getiafreq_(INTEGER *annotator) +{ + return (getiafreq(*annotator)); +} + +DOUBLE_PRECISION getiaorigfreq_(INTEGER *annotator) +{ + return (getiaorigfreq(*annotator)); +} + +INTEGER iannclose_(INTEGER *annotator) { iannclose((WFDB_Annotator)(*annotator)); return (0L); } -long oannclose_(long int *annotator) +INTEGER oannclose_(INTEGER *annotator) { oannclose((WFDB_Annotator)(*annotator)); return (0L); @@ -434,132 +457,132 @@ /* The functions below can be used in place of the macros defined in . */ -long isann_(long int *anntyp) +INTEGER isann_(INTEGER *anntyp) { return (wfdb_isann((int)*anntyp)); } -long isqrs_(long int *anntyp) +INTEGER isqrs_(INTEGER *anntyp) { return (wfdb_isqrs((int)*anntyp)); } -long setisqrs_(long int *anntyp, long int *value) +INTEGER setisqrs_(INTEGER *anntyp, INTEGER *value) { wfdb_setisqrs((int)*anntyp, (int)*value); return (0L); } -long map1_(long int *anntyp) +INTEGER map1_(INTEGER *anntyp) { return (wfdb_map1((int)*anntyp)); } -long setmap1_(long int *anntyp, long int *value) +INTEGER setmap1_(INTEGER *anntyp, INTEGER *value) { wfdb_setmap1((int)*anntyp, (int)*value); return (0L); } -long map2_(long int *anntyp) +INTEGER map2_(INTEGER *anntyp) { return (wfdb_map2((int)*anntyp)); } -long setmap2_(long int *anntyp, long int *value) +INTEGER setmap2_(INTEGER *anntyp, INTEGER *value) { wfdb_setmap2((int)*anntyp, (int)*value); return (0L); } -long ammap_(long int *anntyp) +INTEGER ammap_(INTEGER *anntyp) { return (wfdb_ammap((int)*anntyp)); } -long mamap_(long int *anntyp, long int *subtyp) +INTEGER mamap_(INTEGER *anntyp, INTEGER *subtyp) { return (wfdb_mamap((int)*anntyp, (int)*subtyp)); } -long annpos_(long int *anntyp) +INTEGER annpos_(INTEGER *anntyp) { return (wfdb_annpos((int)*anntyp)); } -long setannpos_(long int *anntyp, long int *value) +INTEGER setannpos_(INTEGER *anntyp, INTEGER *value) { wfdb_setannpos((int)*anntyp, (int)*value); return (0L); } -long timstr_(long int *time, char *string) +INTEGER timstr_(INTEGER *time, char *string) { strcpy(string, timstr((WFDB_Time)(*time))); cfstring(string); return (0L); } -long mstimstr_(long int *time, char *string) +INTEGER mstimstr_(INTEGER *time, char *string) { strcpy(string, mstimstr((WFDB_Time)(*time))); cfstring(string); return (0L); } -long strtim_(char *string) +INTEGER strtim_(char *string) { return (strtim(fcstring(string))); } -long datstr_(long int *date, char *string) +INTEGER datstr_(INTEGER *date, char *string) { strcpy(string, datstr((WFDB_Date)(*date))); cfstring(string); return (0L); } -long strdat_(char *string) +INTEGER strdat_(char *string) { return (strdat(fcstring(string))); } -long adumuv_(long int *signal, long int *ampl) +INTEGER adumuv_(INTEGER *signal, INTEGER *ampl) { return (adumuv((WFDB_Signal)(*signal), (WFDB_Sample)(*ampl))); } -long muvadu_(long int *signal, long int *microvolts) +INTEGER muvadu_(INTEGER *signal, INTEGER *microvolts) { return (muvadu((WFDB_Signal)(*signal), (int)(*microvolts))); } -double aduphys_(long int *signal, long int *ampl) +DOUBLE_PRECISION aduphys_(INTEGER *signal, INTEGER *ampl) { return (aduphys((WFDB_Signal)(*signal), (WFDB_Sample)(*ampl))); } -long physadu_(long int *signal, double *v) +INTEGER physadu_(INTEGER *signal, DOUBLE_PRECISION *v) { return (physadu((WFDB_Signal)(*signal), *v)); } -long sample_(long int *signal, long int *t) +INTEGER sample_(INTEGER *signal, INTEGER *t) { return (sample((WFDB_Signal)(*signal), (WFDB_Time)(*t))); } -long sample_valid_(long int *dummy) +INTEGER sample_valid_(INTEGER *dummy) { return (sample_valid()); } -long calopen_(char *calibration_filename) +INTEGER calopen_(char *calibration_filename) { return (calopen(fcstring(calibration_filename))); } -long getcal_(char *description, char *units, double *low, double *high, double *scale, long int *caltype) +INTEGER getcal_(char *description, char *units, DOUBLE_PRECISION *low, DOUBLE_PRECISION *high, DOUBLE_PRECISION *scale, INTEGER *caltype) { if (getcal(fcstring(description), fcstring(units), &cinfo) == 0) { *low = cinfo.low; @@ -572,7 +595,7 @@ return (-1L); } -long putcal_(char *description, char *units, double *low, double *high, double *scale, long int *caltype) +INTEGER putcal_(char *description, char *units, DOUBLE_PRECISION *low, DOUBLE_PRECISION *high, DOUBLE_PRECISION *scale, INTEGER *caltype) { cinfo.sigtype = fcstring(description); cinfo.units = fcstring(units); @@ -583,226 +606,226 @@ return (putcal(&cinfo)); } -long newcal_(char *calibration_filename) +INTEGER newcal_(char *calibration_filename) { return (newcal(fcstring(calibration_filename))); } -long flushcal_(long int *dummy) +INTEGER flushcal_(INTEGER *dummy) { flushcal(); return (0L); } -long getinfo_(char *record, char *string) +INTEGER getinfo_(char *record, char *string) { strcpy(string, getinfo(fcstring(record))); cfstring(string); return (0L); } -long putinfo_(char *string) +INTEGER putinfo_(char *string) { return (putinfo(fcstring(string))); } -long setinfo_(char *record) +INTEGER setinfo_(char *record) { return (setinfo(fcstring(record))); } -long wfdb_freeinfo_(long int *dummy) +INTEGER wfdb_freeinfo_(INTEGER *dummy) { wfdb_freeinfo(); return (0L); } -long newheader_(char *record) +INTEGER newheader_(char *record) { return (newheader(fcstring(record))); } /* Before using setheader_, use setsiginfo to set the contents of the signal information structures. */ -long setheader_(char *record, long int *nsig) +INTEGER setheader_(char *record, INTEGER *nsig) { return (setheader(fcstring(record), sinfo, (unsigned int)(*nsig))); } /* No wrappers are provided for setmsheader or getseginfo. */ -long wfdbgetskew_(long int *s) +INTEGER wfdbgetskew_(INTEGER *s) { return (wfdbgetskew((WFDB_Signal)(*s))); } -long wfdbsetiskew_(long int *s, long int *skew) +INTEGER wfdbsetiskew_(INTEGER *s, INTEGER *skew) { wfdbsetiskew((WFDB_Signal)(*s), (int)(*skew)); return (0L); } -long wfdbsetskew_(long int *s, long int *skew) +INTEGER wfdbsetskew_(INTEGER *s, INTEGER *skew) { wfdbsetskew((WFDB_Signal)(*s), (int)(*skew)); return (0L); } -long wfdbgetstart_(long int *s) +INTEGER wfdbgetstart_(INTEGER *s) { return (wfdbgetstart((WFDB_Signal)(*s))); } -long wfdbsetstart_(long int *s, long int *bytes) +INTEGER wfdbsetstart_(INTEGER *s, INTEGER *bytes) { wfdbsetstart((WFDB_Signal)(*s), *bytes); return (0L); } -long wfdbputprolog_(char *prolog, long int *bytes, long int *signal) +INTEGER wfdbputprolog_(char *prolog, INTEGER *bytes, INTEGER *signal) { return (wfdbputprolog(fcstring(prolog), (long)*bytes,(WFDB_Signal)*signal)); } -long wfdbquit_(long int *dummy) +INTEGER wfdbquit_(INTEGER *dummy) { wfdbquit(); return (0L); } -double sampfreq_(char *record) +DOUBLE_PRECISION sampfreq_(char *record) { return (sampfreq(fcstring(record))); } -long setsampfreq_(double *frequency) +INTEGER setsampfreq_(DOUBLE_PRECISION *frequency) { return (setsampfreq((WFDB_Frequency)(*frequency))); } -double getcfreq_(long int *dummy) +DOUBLE_PRECISION getcfreq_(INTEGER *dummy) { return (getcfreq()); } -long setcfreq_(double *frequency) +INTEGER setcfreq_(DOUBLE_PRECISION *frequency) { setcfreq((WFDB_Frequency)(*frequency)); return (0L); } -double getbasecount_(long int *dummy) +DOUBLE_PRECISION getbasecount_(INTEGER *dummy) { return (getbasecount()); } -long setbasecount_(double *count) +INTEGER setbasecount_(DOUBLE_PRECISION *count) { setbasecount(*count); return (0L); } -long setbasetime_(char *string) +INTEGER setbasetime_(char *string) { return (setbasetime(fcstring(string))); } -long wfdbquiet_(long int *dummy) +INTEGER wfdbquiet_(INTEGER *dummy) { wfdbquiet(); return (0L); } -long wfdbverbose_(long int *dummy) +INTEGER wfdbverbose_(INTEGER *dummy) { wfdbverbose(); return (0L); } -long wfdberror_(char *string) +INTEGER wfdberror_(char *string) { strcpy(string, wfdberror()); cfstring(string); return (0L); } -long setwfdb_(char *string) +INTEGER setwfdb_(char *string) { setwfdb(fcstring(string)); return (0L); } -long getwfdb_(char *string) +INTEGER getwfdb_(char *string) { strcpy(string, getwfdb()); cfstring(string); return (0L); } -long resetwfdb_(long int *dummy) +INTEGER resetwfdb_(INTEGER *dummy) { resetwfdb(); return (0L); } -long setibsize_(long int *input_buffer_size) +INTEGER setibsize_(INTEGER *input_buffer_size) { return (setibsize((int)(*input_buffer_size))); } -long setobsize_(long int *output_buffer_size) +INTEGER setobsize_(INTEGER *output_buffer_size) { return (setobsize((int)(*output_buffer_size))); } -long wfdbfile_(char *file_type, char *record, char *pathname) +INTEGER wfdbfile_(char *file_type, char *record, char *pathname) { strcpy(pathname, wfdbfile(fcstring(file_type), fcstring(record))); cfstring(pathname); return (0L); } -long wfdbflush_(long int *dummy) +INTEGER wfdbflush_(INTEGER *dummy) { wfdbflush(); return (0L); } -long wfdbmemerr_(long int *exit_if_error) +INTEGER wfdbmemerr_(INTEGER *exit_if_error) { wfdbmemerr((int)(*exit_if_error)); return (0L); } -long wfdbversion_(char *version) +INTEGER wfdbversion_(char *version) { strcpy(version, wfdbversion()); cfstring(version); return (0L); } -long wfdbldflags_(char *ldflags) +INTEGER wfdbldflags_(char *ldflags) { strcpy(ldflags, wfdbldflags()); cfstring(ldflags); return (0L); } -long wfdbcflags_(char *cflags) +INTEGER wfdbcflags_(char *cflags) { strcpy(cflags, wfdbcflags()); cfstring(cflags); return (0L); } -long wfdbdefwfdb_(char *defwfdb) +INTEGER wfdbdefwfdb_(char *defwfdb) { strcpy(defwfdb, wfdbdefwfdb()); cfstring(defwfdb); return (0L); } -long wfdbdefwfdbcal_(char *defwfdbcal) +INTEGER wfdbdefwfdbcal_(char *defwfdbcal) { strcpy(defwfdbcal, wfdbdefwfdbcal()); cfstring(defwfdbcal); diff -Naur '--exclude=Makefile' wfdb-10.5.24/install-wave32 wfdb-10.6.0/install-wave32 --- wfdb-10.5.24/install-wave32 2015-05-28 15:55:15.000000000 -0400 +++ wfdb-10.6.0/install-wave32 2016-11-02 18:17:25.000000000 -0400 @@ -1,6 +1,6 @@ #! /bin/sh # file: install-wave32 G. Moody 7 October 2008 -# Last revised: 12 March 2014 +# Last revised: 15 December 2015 # Build and install WAVE on 64-bit GNU/Linux platforms # ***************************************************************************** @@ -20,6 +20,8 @@ # for details. # ***************************************************************************** +set -e + echo echo "If this script fails, read it for troubleshooting hints." @@ -32,23 +34,41 @@ fi # Install fonts and 32-bit libraries available from Fedora repositories - yum -y install libgcc.i686 glibc-devel.i686 libX11-devel.i686 \ - libXpm-devel.i686 libcurl-devel.i686 xorg-x11-fonts-misc \ + yum -y install make gcc glibc-devel \ + libgcc.i686 glibc-devel.i686 libX11-devel.i686 \ + libXpm-devel.i686 libcurl.i686 libcurl-devel.i686 \ xorg-x11-fonts-100dpi xorg-x11-fonts-ISO8859-1-100dpi \ - xorg-x11-fonts-75dpi xorg-x11-fonts-ISO8859-1-75dpi + xorg-x11-fonts-75dpi xorg-x11-fonts-ISO8859-1-75dpi \ + xorg-x11-fonts-misc # Install XView libraries and development toolkit available from PhysioNet - rpm -Uvh http://physionet.org/physiotools/xview/i386-Fedora/xview-3.2p1.4-21.1.fc8.i386.rpm \ - http://physionet.org/physiotools/xview/i386-Fedora/xview-clients-3.2p1.4-21.1.fc8.i386.rpm \ - http://physionet.org/physiotools/xview/i386-Fedora/xview-devel-3.2p1.4-21.1.fc8.i386.rpm + PACKAGES='xview-3.2p1.4-21.1.fc8.i386.rpm + xview-clients-3.2p1.4-21.1.fc8.i386.rpm + xview-devel-3.2p1.4-21.1.fc8.i386.rpm' + for pkg in $PACKAGES; do + wget -O $pkg http://physionet.org/physiotools/xview/i386-Fedora/$pkg + done + if ! sha256sum -c - </dev/null # 'make collect': retrieve the installed WFDB library and headers @@ -28,11 +32,11 @@ ../conf/collect.sh $(LIBDIR) $(WFDBLIB) $(WFDBLIB_DLLNAME) uninstall: - ../uninstall.sh $(INCDIR)/wfdb $(HFILES) - ../uninstall.sh $(INCDIR) - ../uninstall.sh $(LIBDIR) $(WFDBLIB) + ../uninstall.sh $(DESTDIR)$(INCDIR)/wfdb $(HFILES) + ../uninstall.sh $(DESTDIR)$(INCDIR) + ../uninstall.sh $(DESTDIR)$(LIBDIR) $(WFDBLIB) $(MAKE) lib-post-uninstall - ../uninstall.sh $(LIBDIR) + ../uninstall.sh $(DESTDIR)$(LIBDIR) setup: sed "s+DBDIR+$(DBDIR)+" wfdblib.h @@ -50,20 +54,22 @@ $(PRINT) README $(MFILES) $(HFILES) $(CFILES) # Rule for creating installation directories -$(INCDIR) $(INCDIR)/wfdb $(INCDIR)/ecg $(LIBDIR): +$(DESTDIR)$(INCDIR) $(DESTDIR)$(INCDIR)/wfdb $(DESTDIR)$(INCDIR)/ecg $(DESTDIR)$(LIBDIR): mkdir -p $@; $(SETDPERMISSIONS) $@ # Rules for installing the include files -$(INCDIR)/wfdb/wfdb.h: $(INCDIR)/wfdb wfdb.h - cp -p wfdb.h $(INCDIR)/wfdb; $(SETPERMISSIONS) $(INCDIR)/wfdb/wfdb.h -$(INCDIR)/wfdb/wfdblib.h: $(INCDIR)/wfdb wfdblib.h - cp -p wfdblib.h $(INCDIR)/wfdb; $(SETPERMISSIONS) $(INCDIR)/wfdb/wfdblib.h -$(INCDIR)/wfdb/ecgcodes.h: $(INCDIR)/wfdb ecgcodes.h - cp -p ecgcodes.h $(INCDIR)/wfdb - $(SETPERMISSIONS) $(INCDIR)/wfdb/ecgcodes.h -$(INCDIR)/wfdb/ecgmap.h: $(INCDIR)/wfdb ecgmap.h - cp -p ecgmap.h $(INCDIR)/wfdb - $(SETPERMISSIONS) $(INCDIR)/wfdb/ecgmap.h +$(DESTDIR)$(INCDIR)/wfdb/wfdb.h: $(DESTDIR)$(INCDIR)/wfdb wfdb.h + cp -p wfdb.h $(DESTDIR)$(INCDIR)/wfdb + $(SETPERMISSIONS) $(DESTDIR)$(INCDIR)/wfdb/wfdb.h +$(DESTDIR)$(INCDIR)/wfdb/wfdblib.h: $(DESTDIR)$(INCDIR)/wfdb wfdblib.h + cp -p wfdblib.h $(DESTDIR)$(INCDIR)/wfdb + $(SETPERMISSIONS) $(DESTDIR)$(INCDIR)/wfdb/wfdblib.h +$(DESTDIR)$(INCDIR)/wfdb/ecgcodes.h: $(DESTDIR)$(INCDIR)/wfdb ecgcodes.h + cp -p ecgcodes.h $(DESTDIR)$(INCDIR)/wfdb + $(SETPERMISSIONS) $(DESTDIR)$(INCDIR)/wfdb/ecgcodes.h +$(DESTDIR)$(INCDIR)/wfdb/ecgmap.h: $(DESTDIR)$(INCDIR)/wfdb ecgmap.h + cp -p ecgmap.h $(DESTDIR)$(INCDIR)/wfdb + $(SETPERMISSIONS) $(DESTDIR)$(INCDIR)/wfdb/ecgmap.h # Prerequisites for the library modules wfdbinit.o: wfdb.h wfdblib.h wfdbinit.c @@ -71,5 +77,7 @@ signal.o: wfdb.h wfdblib.h signal.c calib.o: wfdb.h wfdblib.h calib.c wfdbio.o: wfdb.h wfdblib.h wfdbio.c + lf='"$(LDFLAGS)"' ; \ + lf=`echo "$$lf" | sed 's|$(DESTDIR)$(LIBDIR)|$(LIBDIR)|g'` ; \ $(CC) $(CFLAGS) -DVERSION='"$(VERSION)"' -DCFLAGS='"-I$(INCDIR)"' \ - -DLDFLAGS='"$(LDFLAGS)"' -c wfdbio.c + -DLDFLAGS="$$lf" -c wfdbio.c diff -Naur '--exclude=Makefile' wfdb-10.5.24/lib/annot.c wfdb-10.6.0/lib/annot.c --- wfdb-10.5.24/lib/annot.c 2015-05-28 15:55:16.000000000 -0400 +++ wfdb-10.6.0/lib/annot.c 2018-01-23 18:16:22.000000000 -0500 @@ -1,5 +1,5 @@ /* file: annot.c G. Moody 13 April 1989 - Last revised: 1 January 2015 wfdblib 10.5.24 + Last revised: 23 January 2018 wfdblib 10.6.0 WFDB library functions for annotations _______________________________________________________________________________ @@ -27,6 +27,7 @@ This file contains definitions of the following functions, which are not visible outside of this file: + round_to_time (rounds a double to the nearest WFDB_Time) get_ann_table (reads tables used by annstr, strann, and anndesc) put_ann_table (writes tables used by annstr, strann, and anndesc) allociann (sets max # of simultaneously open input annotators) @@ -48,6 +49,9 @@ setanndesc [5.3] (modifies code-to-text translation table) setafreq [10.4.5] (sets time resolution for output annotation files) getafreq [10.4.5] (returns time resolution for output annotation files) + setiafreq [10.6] (sets time resolution for input annotations) + getiafreq [10.6] (returns time resolution for input annotations) + getiaorigfreq [10.6] (returns time resolution of original annotation file) iannclose [9.1] (closes an input annotation file) oannclose [9.1] (closes an output annotation file) @@ -102,6 +106,9 @@ #define DATA 01777 /* data segment of annotation word */ #define MAXRR 01777 /* longest interval which can be coded in a word */ +#define MAXSKIP 0x7fffffff /* largest interval represented by a SKIP */ +#define MINSKIP (-0x7fffffff) /* smallest interval represented by a SKIP */ + /* Pseudo-annotation codes. Legal pseudo-annotation codes are between PAMIN (defined below) and CODE (defined above). PAMIN must be greater than ACMAX << CS (see ). */ @@ -132,12 +139,18 @@ int ateof; /* EOF-reached indicator */ unsigned char auxstr[AUXBUFLEN]; /* aux string buffer */ unsigned index; /* next available position in auxstr */ - double tmul, ptmul; /* tmul * annotation time = sample count */ - WFDB_Time tt; /* annotation time (MIT format only). This + double tmul; /* tmul * annotation time = sample count */ + double tt; /* annotation time (MIT format only). This equals ann.time unless a SKIP follows ann; in such cases, it is the time of the SKIP (i.e., the time of the annotation following ann) */ + double ann_tt; /* unscaled annotation time of 'ann' */ + double pann_tt; /* unscaled annotation time of 'pann' */ + double prev_tt; /* unscaled time of the last annotation + returned by getann */ + WFDB_Time prev_time; /* sample number of the last annotation + returned by getann */ } **iad; static unsigned maxoann; /* max allowed number of output annotators */ @@ -152,17 +165,51 @@ char out_of_order; /* if >0, one or more annotations written by putann are not in the canonical (time, num, chan) order */ + char table_written; /* if >0, table has been written */ } **oad; static WFDB_Frequency oafreq; /* time resolution in ticks/sec for newly- created output annotators */ /* Local functions (for the use of other functions in this module only). */ +#include + +/* Round a double to the nearest WFDB_Time, with halfway cases always + rounded up. (For example, round_to_time(10.5) is 11, but + round_to_time(-10.5) is -10.) */ +static WFDB_Time round_to_time(double x) +{ + WFDB_Time t; + + if (x >= 0) { + if (x >= WFDB_TIME_MAX) + return (WFDB_TIME_MAX); + t = x; + if (x - t >= 0.5) + return (t + 1); + else + return (t); + } + else { + if (x <= WFDB_TIME_MIN) + return (WFDB_TIME_MIN); + t = x; + if (x - t < -0.5) + return (t - 1); + else + return (t); + } +} + static int get_ann_table(WFDB_Annotator i) { char *p1, *p2, *s1 = NULL, *s2 = NULL; int a; WFDB_Annotation annot; + WFDB_Frequency sfreq; + + iad[i]->tmul = 1.0; + iad[i]->afreq = 0.0; if (getann(i, &annot) < 0) /* prime the pump */ return (-1); @@ -171,20 +218,14 @@ if (annot.aux == NULL || *annot.aux < 1) continue; if (*(annot.aux+1) == '#') { - if (strncmp((char *)annot.aux+1, "## time resolution: ", 20) == 0) { + if (strncmp((char *)annot.aux+1, "## time resolution: ", 20) == 0) sscanf((char *)annot.aux + 20, "%lf", &(iad[i]->afreq)); - if (iad[i]->afreq) { - WFDB_Frequency sf = getifreq(); - - if (sf > 0.) - iad[i]->tmul = sf/iad[i]->afreq; - } - } continue; } - p1 = strtok((char *)annot.aux+1, " \t"); - a = strtol(p1, NULL, 10); - if (0 <= a && a <= ACMAX && (p1 = strtok((char *)NULL, " \t"))) { + p1 = strtok((char *)annot.aux+1, " \t"); + a = strtol(p1, &p2, 10); + if (0 <= a && a <= ACMAX && p2 != p1 && + (p1 = strtok((char *)NULL, " \t"))) { SSTRCPY(s1, p1); (void)setannstr(a, s1); p2 = p1 + strlen(p1) + 1; @@ -199,18 +240,10 @@ } if (annot.time != 0L || annot.anntyp != NOTE || annot.subtyp != 0 || annot.aux == NULL) { - if (iad[i]->tmul) annot.time /= iad[i]->tmul; - if (iad[i]->afreq) { - WFDB_Frequency sf = getifreq(); - - if (sf > 0.) - iad[i]->tmul = sf/iad[i]->afreq; - } - else - iad[i]->tmul = getspf(); - annot.time = (WFDB_Time)(annot.time * iad[i]->tmul + 0.5); (void)ungetann(i, &annot); } + + setiafreq(i, getifreq()); return (0); } @@ -220,8 +253,8 @@ static int put_ann_table(WFDB_Annotator i) { - int a, flag = 0; - char buf[256]; + int a, flag = 0, n; + char buf[256], *str = NULL; WFDB_Annotation annot; annot.time = 0L; @@ -242,8 +275,14 @@ buf[0] = strlen(buf+1); if (putann(i, &annot) < 0) return (-1); } - (void)sprintf(buf+1, "%d %s %s", a, annstr(a), anndesc(a)); - buf[0] = strlen(buf+1); + if (anndesc(a)) + n = wfdb_asprintf(&str, "%d %s %s", a, annstr(a), anndesc(a)); + else + n = wfdb_asprintf(&str, "%d %s", a, annstr(a)); + if (!str) return (-1); + annot.aux[0] = (n > 255 ? 255 : n); + memcpy(annot.aux + 1, str, n); + SFREE(str); if (putann(i, &annot) < 0) return (-1); flag = 2; } @@ -405,7 +444,8 @@ oa->ann.time = 0L; oa->info.stat = aiarray[i].stat; oa->out_of_order = 0; - (void)put_ann_table(noaf++); + oa->table_written = 0; + noaf++; break; } } @@ -426,15 +466,9 @@ if (ia->pann.anntyp) { /* an annotation was pushed back */ *annot = ia->pann; ia->pann.anntyp = 0; - if (ia->ptmul != ia->tmul) { - ia->tmul = (ia->afreq) ? getifreq()/ia->afreq : getspf(); - if (ia->ptmul != ia->tmul) { - annot->time = (WFDB_Time)(annot->time*ia->tmul/ia->ptmul + 0.5); - ia->ptmul = ia->tmul; - } - } - if (annot->time) - return (0); + ia->prev_time = annot->time; + ia->prev_tt = ia->pann_tt; + return (0); } if (ia->ateof) { @@ -445,6 +479,8 @@ return (-3); } *annot = ia->ann; + ia->prev_time = annot->time; + ia->prev_tt = ia->ann_tt; switch (ia->info.stat) { case WFDB_READ: /* MIT-format input file */ @@ -454,11 +490,7 @@ return (0); } ia->tt += ia->word & DATA; /* annotation time */ - if (ia->ptmul == 0.0) { - ia->ptmul = ia->tmul; - ia->tmul = (ia->afreq) ? getifreq()/ia->afreq :getspf(); - } - ia->ann.time = (WFDB_Time)(ia->tt * ia->tmul + 0.5); + ia->ann_tt = ia->tt; ia->ann.anntyp = (ia->word & CODE) >> CS; /* set annotation type */ ia->ann.subtyp = 0; /* reset subtype field */ ia->ann.aux = NULL; /* reset aux field */ @@ -493,7 +525,7 @@ } a = ia->word >> 8; /* AHA annotation code */ ia->ann.anntyp = ammap(a); /* convert to MIT annotation code */ - ia->ann.time = (WFDB_Time)wfdb_g32(ia->file); /* time of annotation */ + ia->ann_tt = (WFDB_Time)wfdb_g32(ia->file); /* time of annotation */ if (wfdb_g16(ia->file) <= 0) /* serial number (starts at 1) */ wfdb_error("getann: unexpected annot number in annotator %s\n", ia->info.name); @@ -519,6 +551,7 @@ ia->word = (unsigned)wfdb_g16(ia->file); break; } + ia->ann.time = round_to_time(ia->ann_tt * ia->tmul); if (wfdb_feof(ia->file)) ia->ateof = -1; return (0); @@ -539,7 +572,10 @@ return (-1); } iad[n]->pann = *annot; - iad[n]->ptmul = iad[n]->tmul; + if (annot->time == iad[n]->prev_time) + iad[n]->pann_tt = iad[n]->prev_tt; + else + iad[n]->pann_tt = annot->time / iad[n]->tmul; return (0); } @@ -549,7 +585,7 @@ unsigned annwd; unsigned char *ap; int i, len; - long delta; + unsigned long delta; WFDB_Time t; struct oadata *oa; @@ -558,27 +594,48 @@ return (-2); } t = annot->time; - if (oa->ann.time == (WFDB_Time)0 && oafreq != oa->afreq && oafreq > 0.) { - static WFDB_Annotation tra; - char buf[40]; - - oa->afreq = oafreq; - tra.anntyp = NOTE; - tra.aux = (unsigned char *)buf; - (void)sprintf(buf+1, "## time resolution: %.12g", oafreq); - buf[0] = strlen(buf+1); - if (putann(n, &tra) < 0) return (-1); - tra.anntyp = 0; - tra.aux = NULL; - if (putann(n, &tra) < 0) return (-1); - } - delta = t - oa->ann.time; - if (!(annot->chan > oa->ann.chan || annot->num > oa->ann.num || delta>0L || - (t == 0L && oa->ann.time == 0L))) + if (!oa->table_written) { + oa->table_written = 1; + if (put_ann_table(n) < 0) + return (-1); + } + delta = (unsigned long) t - oa->ann.time; + if (!(annot->chan > oa->ann.chan || annot->num > oa->ann.num || + t > oa->ann.time || (t == 0L && oa->ann.time == 0L))) oa->out_of_order = 1; switch (oa->info.stat) { case WFDB_WRITE: /* MIT-format output file */ default: + /* Do not allow annotations to be written at the minimum or + maximum possible time value. This prevents applications + from inadvertently clamping annotations to the WFDB_Time + range, which is almost always a mistake (for example, using + a 32-bit 'mrgann' on a record longer than 2^31 samples.) + In addition, encoding an annotation at time WFDB_TIME_MAX + on a 64-bit system would require 2^32 SKIPs (24 GB), so + it's better to catch such bugs beforehand. */ + if (t == WFDB_TIME_MIN || t == WFDB_TIME_MAX) { + wfdb_error("putann: time overflow in annotation file %d\n", n); + return (-1); + } + if (t > oa->ann.time) { + /* A SKIP can represent a forward offset of at most + 2^31-1, so if delta is larger than that, it needs to be + represented by multiple SKIPs. */ + while (delta > MAXSKIP) { + wfdb_p16(SKIP, oa->file); wfdb_p32(MAXSKIP, oa->file); + delta -= MAXSKIP; + } + } + else { + /* Likewise, a SKIP can represent a backward offset of at + most 2^31 (minus 1 to account for the special handling + of null annotations below.) */ + while (-delta > -MINSKIP) { + wfdb_p16(SKIP, oa->file); wfdb_p32(MINSKIP, oa->file); + delta -= MINSKIP; + } + } if (annot->anntyp == 0) { /* The caller intends to write a null annotation here, but putann must not write a word of zeroes that would be interpreted as @@ -586,7 +643,9 @@ just before the desired one; thus annwd (below) is never 0. */ wfdb_p16(SKIP, oa->file); wfdb_p32(delta-1, oa->file); delta = 1; } - else if (delta > MAXRR || delta < 0L) { + else if (delta > MAXRR) { + /* skip forward by more than MAXRR, or skip backward by + any distance */ wfdb_p16(SKIP, oa->file); wfdb_p32(delta, oa->file); delta = 0; } annwd = (int)delta + ((int)(annot->anntyp) << CS); @@ -909,6 +968,54 @@ return (oafreq); } +/* setiafreq: set time resolution for input annotations */ +FVOID setiafreq(WFDB_Annotator n, WFDB_Frequency f) +{ + struct iadata *ia; + WFDB_Frequency sfreq; + + if (n < niaf && (ia = iad[n]) != NULL) { + if (f > 0.0 && ia->afreq > 0.0) + ia->tmul = f / ia->afreq; + else if (f > 0.0 && (sfreq = sampfreq(NULL)) > 0.0) + ia->tmul = f * getspf() / sfreq; + else + ia->tmul = 1.0; + + ia->ann.time = round_to_time(ia->ann_tt * ia->tmul); + ia->pann.time = round_to_time(ia->pann_tt * ia->tmul); + ia->prev_time = round_to_time(ia->prev_tt * ia->tmul); + } +} + +/* getiafreq: return time resolution for input annotations */ +FFREQUENCY getiafreq(WFDB_Annotator n) +{ + struct iadata *ia; + + if (n < niaf && (ia = iad[n]) != NULL) { + if (ia->afreq > 0.0) + return (ia->afreq * ia->tmul); + else + return (sampfreq(NULL) * ia->tmul / getspf()); + } + else { + return (-2); + } +} + +/* getiaorigfreq: return the original time resolution of an input + annotation file */ +FFREQUENCY getiaorigfreq(WFDB_Annotator n) +{ + struct iadata *ia; + + if (n < niaf && (ia = iad[n]) != NULL) + return (ia->afreq); + else + return (-2); +} + /* iannclose: close input annotation file n */ FVOID iannclose(WFDB_Annotator n) { @@ -932,7 +1039,7 @@ FVOID oannclose(WFDB_Annotator n) { int i; - char cmdbuf[256]; + char *cmdbuf = NULL; struct oadata *oa; if (n < noaf && (oa = oad[n]) != NULL && oa->file != NULL) { @@ -957,15 +1064,26 @@ wfdb_error( "Rearranging annotations for output annotator %s ...", oa->info.name); - (void)sprintf(cmdbuf, "sortann -r %s -a %s", + /* The option '-r.' tells sortann to change its + WFDB path to the current directory (i.e, it + should only attempt to read the annotation file + that we just created, and should not look + elsewhere, regardless of the WFDB environment + variable.) + + Older versions of sortann interpret '-r.' as + equivalent to '-r', and will search for the + given annotation file within the WFDB path. */ + wfdb_asprintf(&cmdbuf, "sortann -r. %s -a %s", oa->rname, oa->info.name); - if (system(cmdbuf) == 0) { + if (cmdbuf && system(cmdbuf) == 0) { wfdb_error("done!\n"); oa->out_of_order = 0; } else wfdb_error( "\nAnnotations still need to be rearranged.\n"); + SFREE(cmdbuf); } } } diff -Naur '--exclude=Makefile' wfdb-10.5.24/lib/signal.c wfdb-10.6.0/lib/signal.c --- wfdb-10.5.24/lib/signal.c 2015-05-28 15:55:16.000000000 -0400 +++ wfdb-10.6.0/lib/signal.c 2018-01-23 18:16:22.000000000 -0500 @@ -1,5 +1,5 @@ /* file: signal.c G. Moody 13 April 1989 - Last revised: 18 November 2013 wfdblib 10.5.21 + Last revised: 8 January 2018 wfdblib 10.6.0 WFDB library functions for signals _______________________________________________________________________________ @@ -174,6 +174,8 @@ #include "wfdblib.h" +#include + #ifdef iAPX286 #define BROKEN_CC #endif @@ -254,7 +256,6 @@ static unsigned maxigroup; /* max number of input signal groups */ static unsigned nisig; /* number of open input signals */ static unsigned nigroup; /* number of open input signal groups */ -static unsigned maxspf; /* max allowed value for ispfmax */ static unsigned ispfmax; /* max number of samples of any open signal per input frame */ static struct isdata { /* unique for each input signal */ @@ -291,7 +292,7 @@ static int gvmode = DEFWFDBGVMODE; /* getvec mode */ static int gvc; /* getvec sample-within-frame counter */ static int isedf; /* if non-zero, record is stored as EDF/EDF+ */ -WFDB_Sample *sbuf = NULL; /* buffer used by sample() */ +static WFDB_Sample *sbuf = NULL; /* buffer used by sample() */ static int sample_vflag; /* if non-zero, last value returned by sample() was valid */ @@ -318,6 +319,11 @@ char *bp; /* pointer to next location in buf[]; */ char *be; /* pointer to output buffer endpoint */ char count; /* output counter for bit-packed signal */ + signed char seek; /* 1: seek works, -1: seek doesn't work, + 0: unknown */ + char force_flush; /* flush even if seek doesn't work */ + char nrewind; /* number of bytes to seek backwards + after flushing */ } **ogd; static WFDB_Time ostime; /* time of next output sample */ static int obsize; /* default output buffer size */ @@ -447,13 +453,14 @@ number that follows indicates the length of the gap in sample intervals. */ -static int need_sigmap, maxvsig, nvsig, tspf; +static int need_sigmap, maxvsig, nvsig, tspf, vspfmax; static struct isdata **vsd; static WFDB_Sample *ovec; static struct sigmapinfo { char *desc; double gain, scale, offset; + WFDB_Sample sample_offset; WFDB_Sample baseline; int index; int spf; @@ -463,7 +470,7 @@ { int i; - need_sigmap = nvsig = tspf = 0; + need_sigmap = nvsig = tspf = vspfmax = 0; SFREE(ovec); if (smi) { for (i = 0; i < tspf; i += smi[i].spf) @@ -517,7 +524,8 @@ static int sigmap_init(void) { - int i, j, k, kmax, s; + int i, j, k, kmax, s, ivmin, ivmax; + double ovmin, ovmax; struct sigmapinfo *ps; /* is this the layout segment? if so, set up output side of map */ @@ -527,6 +535,7 @@ /* The number of virtual signals is the number of signals defined in the layout segment. */ nvsig = nisig; + vspfmax = ispfmax; for (s = tspf = 0; s < nisig; s++) tspf += isd[s]->info.spf; SALLOC(smi, tspf, sizeof(struct sigmapinfo)); @@ -547,8 +556,10 @@ for (s = 0; s < tspf; s++) { smi[s].index = 0; smi[s].scale = 0.; - smi[s].offset = WFDB_INVALID_SAMPLE; + smi[s].offset = 0.; + smi[s].sample_offset = WFDB_INVALID_SAMPLE; } + ispfmax = vspfmax; if (isd[0]->info.fmt == 0 && nisig == 1) return (0); /* the current segment is a null record */ @@ -572,7 +583,38 @@ "sigmap_init: loss of precision in signal %d in segment %s\n", i, segp->recname); ps->offset = ps->baseline - - ps->scale * isd[i]->info.baseline; + ps->scale * isd[i]->info.baseline + 0.5; + + /* If it is possible to add an additional + offset such that all possible output values + will fit into a positive signed integer, we + can use the "fast" case in sigmap, below. */ + switch (isd[i]->info.fmt) { + case 80: ivmin = -0x80; ivmax = 0x7f; break; + case 310: + case 311: ivmin = -0x200; ivmax = 0x1ff; break; + case 212: ivmin = -0x800; ivmax = 0x7ff; break; + case 16: + case 61: + case 160: ivmin = -0x8000; ivmax = 0x7fff; break; + case 24: ivmin = -0x800000; ivmax = 0x7fffff; break; + default: + ivmin = WFDB_SAMPLE_MIN; + ivmax = WFDB_SAMPLE_MAX; + break; + } + ovmin = ivmin * ps->scale + ps->offset; + ovmax = ivmax * ps->scale + ps->offset; + if (ovmin < ovmax && + ovmin >= WFDB_SAMPLE_MIN + 1 && + ovmax <= WFDB_SAMPLE_MAX && + ovmax - ovmin + 1 < WFDB_SAMPLE_MAX) { + ps->sample_offset = ovmin - 1; + ps->offset -= ps->sample_offset; + } + else { + ps->sample_offset = 0; + } } break; } @@ -596,16 +638,43 @@ ovec[i] = vector[i]; for (i = 0; i < tspf; i++) { - if (ovec[smi[i].index] == WFDB_INVALID_SAMPLE) - vector[i] = WFDB_INVALID_SAMPLE; - else { - v = ovec[smi[i].index] * smi[i].scale + smi[i].offset; - vector[i] = (WFDB_Sample)v; -#if defined(WFDB_OVERFLOW_CHECK) - if (((v > 0.0 && v - ovec[i]) > 1.0) || ((v - ovec[i]) < -1.0)) - wfdb_error("sigmap: overflow detected\n"); -#endif - } + if (ovec[smi[i].index] == WFDB_INVALID_SAMPLE) + vector[i] = WFDB_INVALID_SAMPLE; + else { + /* Scale the input sample and round it to the nearest + integer. Halfway cases are always rounded up (10.5 is + rounded to 11, but -10.5 is rounded to -10.) Note that + smi[i].offset already includes an extra 0.5, so we + simply need to calculate the floor of v. */ + v = ovec[smi[i].index] * smi[i].scale + smi[i].offset; + if (smi[i].sample_offset) { + /* Fast case: if we can guarantee that v is always + positive and the following calculation cannot + overflow, we can avoid additional floating-point + operations. */ + vector[i] = (WFDB_Sample) v + smi[i].sample_offset; + } + else { + /* Slow case: we need to check bounds and handle + negative values. */ + if (v >= 0) { + if (v <= WFDB_SAMPLE_MAX) + vector[i] = (WFDB_Sample) v; + else + vector[i] = WFDB_SAMPLE_MAX; + } + else { + if (v >= WFDB_SAMPLE_MIN) { + vector[i] = (WFDB_Sample) v; + if (vector[i] > v) + vector[i]--; + } + else { + vector[i] = WFDB_SAMPLE_MIN; + } + } + } + } } return (tspf); } @@ -616,7 +685,7 @@ static int edfparse(WFDB_FILE *ifile) { static char buf[80], *edf_fname, *p; - double *pmax, *pmin, spr; + double *pmax, *pmin, spr, baseline; int format, i, s, nsig, offset, day, month, year, hour, minute, second; long adcrange, *dmax, *dmin, nframes; @@ -734,7 +803,11 @@ hsd[s]->info.adcres = i; if (pmax[s] != pmin[s]) { hsd[s]->info.gain = (dmax[s] - dmin[s])/(pmax[s] - pmin[s]); - hsd[s]->info.baseline = dmax[s] - pmax[s] * hsd[s]->info.gain + 0.5; + baseline = dmax[s] - pmax[s] * hsd[s]->info.gain; + if (baseline >= 0.0) + hsd[s]->info.baseline = baseline + 0.5; + else + hsd[s]->info.baseline = baseline - 0.5; } else /* gain is undefined */ hsd[s]->info.gain = hsd[s]->info.baseline = 0; @@ -786,7 +859,10 @@ static char sep[] = " \t\n\r"; /* If another input header file was opened, close it. */ - if (hheader) (void)wfdb_fclose(hheader); + if (hheader) { + (void)wfdb_fclose(hheader); + hheader = NULL; + } isedf = 0; if (strcmp(record, "~") == 0) { @@ -1248,6 +1324,13 @@ { struct osdata *os; struct ogdata *og; + WFDB_Group g; + + for (g = 0; g < nogroup; g++) + if (ogd && (og = ogd[g])) + og->force_flush = 1; + + wfdb_osflush(); if (osd) { while (maxosig) @@ -1432,6 +1515,16 @@ } } +/* f212: flush output to a format 212 signal file */ +static void f212(struct ogdata *g) +{ + /* If we have one leftover sample, write it as two bytes. */ + if (g->count == 1) { + w16(g->data, g); + g->nrewind = 2; + } +} + /* r310: read and return the next sample from a format 310 signal file (3 10-bit samples bit-packed in 4 bytes) */ static int r310(struct igdata *g) @@ -1469,6 +1562,26 @@ } } +/* f310: flush output to a format 310 signal file */ +static void f310(struct ogdata *g) +{ + switch (g->count) { + case 0: break; + /* If we have one leftover sample, write it as two bytes. */ + case 1: w16(g->data, g); + g->nrewind = 2; + break; + /* If we have two leftover samples, write them as four bytes. + In this case, the file will appear to have an extra (zero) + sample at the end. */ + case 2: + default: w16(g->data, g); + w16(g->datb, g); + g->nrewind = 4; + break; + } +} + /* r311: read and return the next sample from a format 311 signal file (3 10-bit samples bit-packed in 4 bytes; note that formats 310 and 311 differ in the layout of the bit-packed data) */ @@ -1479,11 +1592,12 @@ /* Obtain the next 10-bit value right-justified in v. */ switch (g->count++) { case 0: v = (g->data = r16(g)); break; - case 1: g->datb = r16(g); + case 1: g->datb = (r8(g) & 0xff); v = ((g->data & 0xfc00) >> 10) | ((g->datb & 0xf) << 6); break; case 2: default: g->count = 0; + g->datb |= r8(g) << 8; v = g->datb >> 4; break; } /* Sign-extend from the tenth bit. */ @@ -1507,7 +1621,29 @@ break; } } - + +/* f311: flush output to a format 311 signal file */ +static void f311(struct ogdata *g) +{ + switch (g->count) { + case 0: break; + /* If we have one leftover sample, write it as two bytes. */ + case 1: w16(g->data, g); + g->nrewind = 2; + break; + /* If we have two leftover samples, write them as four bytes + (note that the first two bytes will already have been written + by w311(), above.) The file will appear to have an extra + (zero) sample at the end. It would be possible to write only + three bytes here, but older versions of WFDB would not be + able to read the resulting file. */ + case 2: + default: w16(g->datb, g); + g->nrewind = 2; + break; + } +} + static int isgsetframe(WFDB_Group g, WFDB_Time t) { int i, trem = 0; @@ -1518,7 +1654,7 @@ /* Do nothing if there is no more than one input signal group and the input pointer is correct already. */ - if (nigroup < 2 && istime == (in_msrec ? t + segp->samp0 : t) && + if (nigroup < 2 && istime == t && gvc == ispfmax && igd[g]->start == 0) return (0); @@ -1537,6 +1673,7 @@ containing the desired sample. */ if (in_msrec) { WFDB_Seginfo *tseg = segp; + WFDB_Group h; if (t >= msnsamples) { wfdb_error("isigsettime: improper seek on signal group %d\n", g); @@ -1553,6 +1690,28 @@ segp->recname); return (-1); } + /* Following isigopen(), nigroup may have changed and + group numbers may not make any sense anymore. However, + isigsettime() will still call isgsettime() once for + each non-zero group (if the previous segment had + multiple groups) and then once for group zero. + + Calling isgsetframe() multiple times for a non-zero + group is mostly harmless, but seeking on group 0 should + only be done once. Thus, when we jump to a new + segment, implicitly seek on all non-zero groups + (regardless of g), but only seek on group 0 if g is 0. + + (Note that isgsettime() is not and has never been fully + functional for multi-segment records, because it cannot + read signals from two different segments at once.) */ + for (h = 1; h < nigroup; h++) + if (i = isgsetframe(h, t)) + return (i); + if (g == 0) + return (isgsetframe(0, t)); + else + return (0); } t -= segp->samp0; } @@ -1565,9 +1724,11 @@ switch (isd[s]->info.fmt) { case 0: if (t < nsamples) { + gvc = ispfmax; if (s == 0) istime = (in_msrec) ? t + segp->samp0 : t; isd[s]->info.nsamp = nsamples - t; - return (ig->stat = 1); + ig->stat = 1; + return (0); } else { if (s == 0) istime = (in_msrec) ? msnsamples : nsamples; @@ -1593,6 +1754,8 @@ for (i = 0; i < nn; i++) (void)r212(ig); istime++; + for (n = 0; s+n < nisig && isd[s+n]->info.group == g; n++) + isd[s+n]->info.nsamp = (WFDB_Time)0L; return (0); } b = 3*nn; d = 2; break; @@ -1609,6 +1772,8 @@ for (i = nn*trem; i > 0; i--) (void)r310(ig); istime += trem; + for (n = 0; s+n < nisig && isd[s+n]->info.group == g; n++) + isd[s+n]->info.nsamp = (WFDB_Time)0L; return (0); } b = 4*nn; d = 3; break; @@ -1625,6 +1790,8 @@ for (i = nn*trem; i > 0; i--) (void)r311(ig); istime += trem; + for (n = 0; s+n < nisig && isd[s+n]->info.group == g; n++) + isd[s+n]->info.nsamp = (WFDB_Time)0L; return (0); } b = 4*nn; d = 3; break; @@ -2031,12 +2198,12 @@ if (ispfmax < is->info.spf) ispfmax = is->info.spf; if (skewmax < is->skew) skewmax = is->skew; } - setgvmode(gvmode); /* Reset sfreq if appropriate. */ - gvc = ispfmax; /* Initialize getvec's sample-within-frame counter. */ nisig += s; /* Update the count of open input signals. */ nigroup += g; /* Update the count of open input signal groups. */ if (sigmap_init() < 0) return (-1); + setgvmode(gvmode); /* Reset sfreq if appropriate. */ + gvc = ispfmax; /* Initialize getvec's sample-within-frame counter. */ /* Determine the total number of samples per frame. */ for (si = framelen = 0; si < nisig; si++) @@ -2054,8 +2221,8 @@ } else SREALLOC(vvector, framelen, sizeof(WFDB_Sample)); + tuvlen = framelen; } - tuvlen = framelen; /* If deskewing is required, allocate the deskewing buffer (unless this is a multi-segment record and dsbuf has been allocated already). */ @@ -2391,8 +2558,10 @@ return (-1); } if (f > 0.0) { - SREALLOC(gv0, nisig, sizeof(WFDB_Sample)); - SREALLOC(gv1, nisig, sizeof(WFDB_Sample)); + if (nvsig > 0) { + SREALLOC(gv0, nvsig, sizeof(WFDB_Sample)); + SREALLOC(gv1, nvsig, 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 @@ -2573,10 +2742,18 @@ FINT isigsettime(WFDB_Time t) { WFDB_Group g; + WFDB_Time curtime; int stat = 0; /* Return immediately if no seek is needed. */ - if (t == istime || nisig == 0) return (0); + if (nisig == 0) return (0); + if (ifreq <= (WFDB_Frequency)0) { + if (sfreq == ffreq) + curtime = istime; + else + curtime = (istime - 1) * ispfmax + gvc; + if (t == curtime) return (0); + } for (g = 1; g < nigroup; g++) if ((stat = isgsettime(g, t)) < 0) break; @@ -2667,7 +2844,7 @@ wfdb_error("nextvect: illegal signal number %d\n", s); return ((WFDB_Time) -1); } - for ( ; stat=getvec(vvector) > 0; t++) + for ( ; (stat = getvec(vvector)) > 0; t++) /* Read samples until we find a valid one or reach the end of the record. */ if (vvector[s] != WFDB_INVALID_SAMPLE) { @@ -3586,7 +3763,34 @@ void wfdb_osflush(void) { WFDB_Group g; + WFDB_Signal s; struct ogdata *og; + struct osdata *os; + + if (!osd || !ogd) + return; + + for (s = 0; s < nosig; s++) { + if ((os = osd[s]) && (og = ogd[os->info.group]) && og->nrewind == 0) { + if (!og->force_flush && og->seek == 0) { + if (og->bsize == 0 && !wfdb_fseek(og->fp, 0L, SEEK_CUR)) + og->seek = 1; + else + og->seek = -1; + } + if (og->force_flush || og->seek > 0) { + /* Either we are closing the file (osigclose() was called), + or the file is seekable: write out any + partially-completed sets of bit-packed samples. */ + switch (os->info.fmt) { + case 212: f212(og); break; + case 310: f310(og); break; + case 311: f311(og); break; + default: break; + } + } + } + } for (g = 0; g < nogroup; g++) { og = ogd[g]; @@ -3595,6 +3799,13 @@ og->bp = og->buf; } (void)wfdb_fflush(og->fp); + + if (!og->force_flush && og->nrewind != 0) { + /* Rewind the file so that subsequent samples will be + written in the right place. */ + wfdb_fseek(og->fp, -((long) og->nrewind), SEEK_CUR); + og->nrewind = 0; + } } } diff -Naur '--exclude=Makefile' wfdb-10.5.24/lib/wfdb.h wfdb-10.6.0/lib/wfdb.h --- wfdb-10.5.24/lib/wfdb.h 2015-05-28 15:59:01.000000000 -0400 +++ wfdb-10.6.0/lib/wfdb.h 2018-01-26 16:46:19.000000000 -0500 @@ -1,5 +1,5 @@ /* file: wfdb.h G. Moody 13 June 1983 - Last revised: 21 May 2015 wfdblib 10.5.24 + Last revised: 8 December 2017 wfdblib 10.6.0 WFDB library type, constant, structure, and function interface definitions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) @@ -31,8 +31,8 @@ /* WFDB library version. */ #define WFDB_MAJOR 10 -#define WFDB_MINOR 5 -#define WFDB_RELEASE 24 +#define WFDB_MINOR 6 +#define WFDB_RELEASE 0 #define WFDB_NETFILES 1 /* if 1, library includes code for HTTP, FTP clients */ #define WFDB_NETFILES_LIBCURL 1 @@ -77,6 +77,27 @@ typedef unsigned int WFDB_Signal; /* signal number */ typedef unsigned int WFDB_Annotator;/* annotator number */ +/* The following macros can be used to determine the ranges of the + above data types. You will also need to include and/or + . */ +#define WFDB_SAMPLE_MIN INT_MIN +#define WFDB_SAMPLE_MAX INT_MAX +#define WFDB_TIME_MIN LONG_MIN +#define WFDB_TIME_MAX LONG_MAX +#define WFDB_DATE_MIN LONG_MIN +#define WFDB_DATE_MAX LONG_MAX +#define WFDB_FREQUENCY_MAX DBL_MAX +#define WFDB_FREQUENCY_DIG DBL_DIG +#define WFDB_FREQUENCY_MAX_10_EXP DBL_MAX_10_EXP +#define WFDB_FREQUENCY_EPSILON DBL_EPSILON +#define WFDB_GAIN_MAX DBL_MAX +#define WFDB_GAIN_DIG DBL_DIG +#define WFDB_GAIN_MAX_10_EXP DBL_MAX_10_EXP +#define WFDB_GAIN_EPSILON DBL_EPSILON +#define WFDB_GROUP_MAX UINT_MAX +#define WFDB_SIGNAL_MAX UINT_MAX +#define WFDB_ANNOTATOR_MAX UINT_MAX + /* getvec and getframe return a sample with a value of WFDB_INVALID_SAMPLE when the amplitude of a signal is undefined (e.g., the input is clipped or the signal is not available) and padding is disabled (see WFDB_GVPAD, below). @@ -203,15 +224,15 @@ /* Dynamic memory allocation macros. */ #define MEMERR(P, N, S) \ - { wfdb_error("WFDB: can't allocate (%ld*%ld) bytes for %s\n", \ - (size_t)N, (size_t)S, #P); \ + { wfdb_error("WFDB: can't allocate (%lu*%lu) bytes for %s\n", \ + (unsigned long)N, (unsigned long)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); } } +#define SSTRCPY(P, Q) { const char *WFDB_tmp = (Q); if (WFDB_tmp) { \ + SALLOC(P, (size_t)strlen(WFDB_tmp)+1,1); strcpy(P, WFDB_tmp); } } /* Function types */ #ifndef _WINDLL /* for everything *except* MS Windows applications */ @@ -297,6 +318,9 @@ extern FINT setanndesc(int annotation_code, char *annotation_description); extern FVOID setafreq(WFDB_Frequency f); extern FFREQUENCY getafreq(void); +extern FVOID setiafreq(WFDB_Annotator a, WFDB_Frequency f); +extern FFREQUENCY getiafreq(WFDB_Annotator a); +extern FFREQUENCY getiaorigfreq(WFDB_Annotator a); extern FVOID iannclose(WFDB_Annotator a); extern FVOID oannclose(WFDB_Annotator a); extern FINT wfdb_isann(int code); @@ -359,6 +383,11 @@ extern FSTRING wfdbfile(char *file_type, char *record); extern FVOID wfdbflush(void); extern FVOID wfdbmemerr(int exit_on_error); +#if __GNUC__ >= 3 +__attribute__((__format__(__printf__, 1, 2))) +#endif +extern FVOID wfdb_error(const char *format_string, ...); +extern FINT wfdb_me_fatal(void); extern FCONSTSTRING wfdbversion(void); extern FCONSTSTRING wfdbldflags(void); extern FCONSTSTRING wfdbcflags(void); @@ -380,7 +409,7 @@ adumuv(), newheader(), setheader(), setmsheader(), getseginfo(), wfdbputprolog(), setsampfreq(), setbasetime(), putinfo(), setinfo(), setibsize(), setobsize(), calopen(), getcal(), putcal(), newcal(), - wfdbgetskew(), sample_valid(); + wfdbgetskew(), sample_valid(), wfdb_me_fatal(); extern FLONGINT wfdbgetstart(); extern FSAMPLE muvadu(), physadu(), sample(); extern FSTRING ecgstr(), annstr(), anndesc(), timstr(), mstimstr(), @@ -389,8 +418,10 @@ extern FDATE strdat(); extern FVOID setafreq(), setgvmode(), wfdb_freeinfo(), wfdbquit(), wfdbquiet(), wfdbverbose(), setdb(), wfdbflush(), setcfreq(), setbasecount(), flushcal(), - wfdbsetiskew(), wfdbsetskew(), wfdbsetstart(), wfdbmemerr(); -extern FFREQUENCY getafreq(), getifreq(), sampfreq(), getcfreq(); + wfdbsetiskew(), wfdbsetskew(), wfdbsetstart(), wfdbmemerr(), wfdb_error(), + setiafreq(); +extern FFREQUENCY getafreq(), getifreq(), sampfreq(), getcfreq(), getiafreq(), + getiaorigfreq(); extern FDOUBLE aduphys(), getbasecount(); #endif diff -Naur '--exclude=Makefile' wfdb-10.5.24/lib/wfdb.h0 wfdb-10.6.0/lib/wfdb.h0 --- wfdb-10.5.24/lib/wfdb.h0 2015-05-28 15:55:16.000000000 -0400 +++ wfdb-10.6.0/lib/wfdb.h0 2018-01-23 18:16:22.000000000 -0500 @@ -1,5 +1,5 @@ /* file: wfdb.h G. Moody 13 June 1983 - Last revised: 21 May 2015 wfdblib 10.5.24 + Last revised: 8 December 2017 wfdblib 10.6.0 WFDB library type, constant, structure, and function interface definitions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) @@ -77,6 +77,27 @@ typedef unsigned int WFDB_Signal; /* signal number */ typedef unsigned int WFDB_Annotator;/* annotator number */ +/* The following macros can be used to determine the ranges of the + above data types. You will also need to include and/or + . */ +#define WFDB_SAMPLE_MIN INT_MIN +#define WFDB_SAMPLE_MAX INT_MAX +#define WFDB_TIME_MIN LONG_MIN +#define WFDB_TIME_MAX LONG_MAX +#define WFDB_DATE_MIN LONG_MIN +#define WFDB_DATE_MAX LONG_MAX +#define WFDB_FREQUENCY_MAX DBL_MAX +#define WFDB_FREQUENCY_DIG DBL_DIG +#define WFDB_FREQUENCY_MAX_10_EXP DBL_MAX_10_EXP +#define WFDB_FREQUENCY_EPSILON DBL_EPSILON +#define WFDB_GAIN_MAX DBL_MAX +#define WFDB_GAIN_DIG DBL_DIG +#define WFDB_GAIN_MAX_10_EXP DBL_MAX_10_EXP +#define WFDB_GAIN_EPSILON DBL_EPSILON +#define WFDB_GROUP_MAX UINT_MAX +#define WFDB_SIGNAL_MAX UINT_MAX +#define WFDB_ANNOTATOR_MAX UINT_MAX + /* getvec and getframe return a sample with a value of WFDB_INVALID_SAMPLE when the amplitude of a signal is undefined (e.g., the input is clipped or the signal is not available) and padding is disabled (see WFDB_GVPAD, below). @@ -203,15 +224,15 @@ /* Dynamic memory allocation macros. */ #define MEMERR(P, N, S) \ - { wfdb_error("WFDB: can't allocate (%ld*%ld) bytes for %s\n", \ - (size_t)N, (size_t)S, #P); \ + { wfdb_error("WFDB: can't allocate (%lu*%lu) bytes for %s\n", \ + (unsigned long)N, (unsigned long)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); } } +#define SSTRCPY(P, Q) { const char *WFDB_tmp = (Q); if (WFDB_tmp) { \ + SALLOC(P, (size_t)strlen(WFDB_tmp)+1,1); strcpy(P, WFDB_tmp); } } /* Function types */ #ifndef _WINDLL /* for everything *except* MS Windows applications */ @@ -297,6 +318,9 @@ extern FINT setanndesc(int annotation_code, char *annotation_description); extern FVOID setafreq(WFDB_Frequency f); extern FFREQUENCY getafreq(void); +extern FVOID setiafreq(WFDB_Annotator a, WFDB_Frequency f); +extern FFREQUENCY getiafreq(WFDB_Annotator a); +extern FFREQUENCY getiaorigfreq(WFDB_Annotator a); extern FVOID iannclose(WFDB_Annotator a); extern FVOID oannclose(WFDB_Annotator a); extern FINT wfdb_isann(int code); @@ -359,6 +383,11 @@ extern FSTRING wfdbfile(char *file_type, char *record); extern FVOID wfdbflush(void); extern FVOID wfdbmemerr(int exit_on_error); +#if __GNUC__ >= 3 +__attribute__((__format__(__printf__, 1, 2))) +#endif +extern FVOID wfdb_error(const char *format_string, ...); +extern FINT wfdb_me_fatal(void); extern FCONSTSTRING wfdbversion(void); extern FCONSTSTRING wfdbldflags(void); extern FCONSTSTRING wfdbcflags(void); @@ -380,7 +409,7 @@ adumuv(), newheader(), setheader(), setmsheader(), getseginfo(), wfdbputprolog(), setsampfreq(), setbasetime(), putinfo(), setinfo(), setibsize(), setobsize(), calopen(), getcal(), putcal(), newcal(), - wfdbgetskew(), sample_valid(); + wfdbgetskew(), sample_valid(), wfdb_me_fatal(); extern FLONGINT wfdbgetstart(); extern FSAMPLE muvadu(), physadu(), sample(); extern FSTRING ecgstr(), annstr(), anndesc(), timstr(), mstimstr(), @@ -389,8 +418,10 @@ extern FDATE strdat(); extern FVOID setafreq(), setgvmode(), wfdb_freeinfo(), wfdbquit(), wfdbquiet(), wfdbverbose(), setdb(), wfdbflush(), setcfreq(), setbasecount(), flushcal(), - wfdbsetiskew(), wfdbsetskew(), wfdbsetstart(), wfdbmemerr(); -extern FFREQUENCY getafreq(), getifreq(), sampfreq(), getcfreq(); + wfdbsetiskew(), wfdbsetskew(), wfdbsetstart(), wfdbmemerr(), wfdb_error(), + setiafreq(); +extern FFREQUENCY getafreq(), getifreq(), sampfreq(), getcfreq(), getiafreq(), + getiaorigfreq(); extern FDOUBLE aduphys(), getbasecount(); #endif diff -Naur '--exclude=Makefile' wfdb-10.5.24/lib/wfdbio.c wfdb-10.6.0/lib/wfdbio.c --- wfdb-10.5.24/lib/wfdbio.c 2015-05-28 15:55:16.000000000 -0400 +++ wfdb-10.6.0/lib/wfdbio.c 2018-01-23 18:16:22.000000000 -0500 @@ -1,5 +1,5 @@ /* file: wfdbio.c G. Moody 18 November 1988 - Last revised: 22 May 2015 wfdblib 10.5.24 + Last revised: 11 December 2017 wfdblib 10.6.0 Low-level I/O functions for the WFDB library _______________________________________________________________________________ @@ -60,6 +60,8 @@ wfdb_export_config [10.3.9] (puts the WFDB path, etc. into the environment) wfdb_getiwfdb [6.2] (sets WFDB from the contents of a file) wfdb_addtopath [6.2] (adds path component of string argument to WFDB path) + wfdb_vasprintf (allocates and formats a message) + wfdb_asprintf (allocates and formats a message) wfdb_error (produces an error message) wfdb_fprintf [10.0.1] (like fprintf, but first arg is a WFDB_FILE pointer) wfdb_open (finds and opens database files) @@ -81,8 +83,8 @@ visible outside of this file): www_parse_passwords (load username/password information) www_userpwd (get username/password for a given url) - wfdb_wwwquit (shut down libcurl or libwww cleanly) - www_init (initialize libcurl or libwww) + wfdb_wwwquit (shut down libcurl cleanly) + www_init (initialize libcurl) www_get_cont_len (find length of data for a given url) www_get_url_range_chunk (get a block of data from a given url) www_get_url_chunk (get all data from a given url) @@ -110,13 +112,13 @@ stubs (placeholders) only, as noted. These functions, also defined here, are compiled only if WFDB_NETFILES is non- -zero; they permit access to remote files via http or ftp (using libcurl or -libwww) as well as to local files (using the standard C I/O functions). The -functions in this group are intended primarily for use by other WFDB library -functions, but may also be called directly by WFDB applications that need to -read remote files. Unlike other private functions in the WFDB library, the -interfaces to these are not likely to change, since they are designed to -emulate the similarly-named ANSI/ISO C standard I/O functions: +zero; they permit access to remote files via http or ftp (using libcurl) as +well as to local files (using the standard C I/O functions). The functions in +this group are intended primarily for use by other WFDB library functions, but +may also be called directly by WFDB applications that need to read remote +files. Unlike other private functions in the WFDB library, the interfaces to +these are not likely to change, since they are designed to emulate the +similarly-named ANSI/ISO C standard I/O functions: wfdb_clearerr (emulates clearerr) wfdb_feof (emulates feof) wfdb_ferror (emulates ferror) @@ -219,8 +221,7 @@ error_print = 1; } -#define MFNLEN 1024 /* max length of WFDB filename, including '\0' */ -static char wfdb_filename[MFNLEN]; +static char *wfdb_filename; /* wfdbfile returns the pathname or URL of a WFDB file. */ @@ -294,7 +295,7 @@ /* Private functions (for the use of other WFDB library functions only). */ -int wfdb_me_fatal() /* used by the MEMERR macro defined in wfdblib.h */ +FINT wfdb_me_fatal() /* used by the MEMERR macro defined in wfdblib.h */ { return (wfdb_mem_behavior); } @@ -585,29 +586,40 @@ void wfdb_export_config(void) { static int first_call = 1; + char *envstr = NULL; /* Register the cleanup function so that it is invoked on exit. */ if (first_call) { atexit(wfdb_free_config); first_call = 0; } - SALLOC(p_wfdb, 1, strlen(wfdbpath)+6); - sprintf(p_wfdb, "WFDB=%s", wfdbpath); - putenv(p_wfdb); + SALLOC(envstr, 1, strlen(wfdbpath)+6); + if (envstr) { + sprintf(envstr, "WFDB=%s", wfdbpath); + putenv(envstr); + SFREE(p_wfdb); + p_wfdb = envstr; + } if (getenv("WFDBCAL") == NULL) { SALLOC(p_wfdbcal, 1, strlen(DEFWFDBCAL)+9); - sprintf(p_wfdbcal, "WFDBCAL=%s", DEFWFDBCAL); - putenv(p_wfdbcal); + if (p_wfdbcal) { + sprintf(p_wfdbcal, "WFDBCAL=%s", DEFWFDBCAL); + putenv(p_wfdbcal); + } } if (getenv("WFDBANNSORT") == NULL) { SALLOC(p_wfdbannsort, 1, 14); - sprintf(p_wfdbannsort, "WFDBANNSORT=%d", DEFWFDBANNSORT == 0 ? 0 : 1); - putenv(p_wfdbannsort); + if (p_wfdbannsort) { + sprintf(p_wfdbannsort, "WFDBANNSORT=%d", DEFWFDBANNSORT == 0 ? 0 : 1); + putenv(p_wfdbannsort); + } } if (getenv("WFDBGVMODE") == NULL) { SALLOC(p_wfdbgvmode, 1, 13); - sprintf(p_wfdbgvmode, "WFDBGVMODE=%d", DEFWFDBGVMODE == 0 ? 0 : 1); - putenv(p_wfdbgvmode); + if (p_wfdbgvmode) { + sprintf(p_wfdbgvmode, "WFDBGVMODE=%d", DEFWFDBGVMODE == 0 ? 0 : 1); + putenv(p_wfdbgvmode); + } } } #endif @@ -692,6 +704,92 @@ return; } +#include +#ifdef va_copy +# define VA_COPY(dst, src) va_copy(dst, src) +# define VA_END2(ap) va_end(ap) +#else +# ifdef __va_copy +# define VA_COPY(dst, src) __va_copy(dst, src) +# define VA_END2(ap) va_end(ap) +# else +# define VA_COPY(dst, src) memcpy(&(dst), &(src), sizeof(va_list)) +# define VA_END2(ap) (void) (ap) +# endif +#endif + +/* wfdb_vasprintf formats a string in the same manner as vsprintf, and +allocates a new buffer that is sufficiently large to hold the result. +The original buffer, if any, is freed afterwards (meaning that, unlike +vsprintf, it is permissible to use the original buffer as a '%s' +argument.) */ +int wfdb_vasprintf(char **buffer, const char *format, va_list arguments) +{ + char *oldbuffer; + int length, bufsize; + va_list arguments2; + + /* make an initial guess at how large the buffer should be */ + bufsize = 2 * strlen(format) + 1; + + oldbuffer = *buffer; + *buffer = NULL; + + while (1) { + /* do not use SALLOC; avoid recursive calls to wfdb_error */ + if (*buffer) + free(*buffer); + *buffer = malloc(bufsize); + if (!(*buffer)) { + if (wfdb_me_fatal()) { + fprintf(stderr, "WFDB: out of memory\n"); + exit(1); + } + length = 0; + break; + } + + VA_COPY(arguments2, arguments); +#ifdef _WINDOWS + length = _vsnprintf(*buffer, bufsize, format, arguments2); +#else + length = vsnprintf(*buffer, bufsize, format, arguments2); +#endif + VA_END2(arguments2); + + /* some pre-standard versions of 'vsnprintf' return -1 if the + formatted string does not fit in the buffer; in that case, + try again with a larger buffer */ + if (length < 0) + bufsize *= 2; + /* standard 'vsnprintf' returns the actual length of the + formatted string */ + else if (length >= bufsize) + bufsize = length + 1; + else + break; + } + + if (oldbuffer) + free(oldbuffer); + return (length); +} + +/* wfdb_asprintf formats a string in the same manner as sprintf, and +allocates a new buffer that is sufficiently large to hold the +result. */ +int wfdb_asprintf(char **buffer, const char *format, ...) +{ + va_list arguments; + int length; + + va_start(arguments, format); + length = wfdb_vasprintf(buffer, format, arguments); + va_end(arguments); + + return (length); +} + /* The wfdb_error function handles error messages, normally by printing them on the standard error output. Its arguments can be any set of arguments which would be legal for printf, i.e., the first one is a format string, and any @@ -699,68 +797,53 @@ in the format string. It can be silenced by invoking wfdbquiet(), or re-enabled by invoking wfdbverbose(). -The wfdb_fprintf function handles all formatted output to files. It is used -in the same way as the standard fprintf function, except that its first -argument is a pointer to a WFDB_FILE rather than a FILE. - -There are three major versions of each of wfdb_error and wfdb_fprintf below. -The first version is compiled by ANSI C compilers. (A variant of this version -of wfdb_error can be used with Microsoft Windows; it puts the error message -into a message box, rather than using the standard error output.) The second -version is compiled by traditional UNIX C compilers (System V, Berkeley 4.x) -that are not ANSI-conforming. The third version can be compiled by many older -C compilers, if the symbol OLDC is defined; do so only if you are using a C -library which does not include a vsprintf function and a "stdarg.h" or -"varargs.h" header file. This third version uses an undocumented function -(_doprnt) which works for most if not all older UNIX C compilers, and several -others as well. - -If OLDC is not defined, the function wfdberror (without the underscore) returns -the most recent error message passed to wfdb_error (even if output was -suppressed by wfdbquiet). This feature permits programs to handle errors -somewhat more flexibly (in windowing environments, for example, where using the -standard error output may be inappropriate). */ +The function wfdberror (without the underscore) returns the most recent error +message passed to wfdb_error (even if output was suppressed by wfdbquiet). +This feature permits programs to handle errors somewhat more flexibly (in +windowing environments, for example, where using the standard error output may +be inappropriate). +*/ -#ifndef OLDC -static char error_message[256]; -#endif +static int error_flag; +static char *error_message; FSTRING wfdberror(void) { - if (*error_message == '\0') - sprintf(error_message, - "WFDB library version %d.%d.%d (%s).\n", - WFDB_MAJOR, WFDB_MINOR, WFDB_RELEASE, __DATE__); - return (error_message); + if (!error_flag) + wfdb_asprintf(&error_message, + "WFDB library version %d.%d.%d (%s).\n", + WFDB_MAJOR, WFDB_MINOR, WFDB_RELEASE, __DATE__); + if (error_message) + return (error_message); + else + return ("WFDB: cannot allocate memory for error message"); } -/* First version: for ANSI C compilers and Microsoft Windows */ -#if defined(__STDC__) || defined(_WINDOWS) -#include -#ifdef _WINDOWS -#include /* contains function prototype for MessageBox */ -#endif - -void wfdb_error(char *format, ...) +FVOID wfdb_error(const char *format, ...) { va_list arguments; + error_flag = 1; va_start(arguments, format); + wfdb_vasprintf(&error_message, format, arguments); + va_end(arguments); + #if 1 /* standard variant: use stderr output */ - (void)vsprintf(error_message, format, arguments); if (error_print) { - (void)fprintf(stderr, "%s", error_message); + (void)fprintf(stderr, "%s", wfdberror()); (void)fflush(stderr); } #else /* MS Windows variant: use message box */ - (void)wvsprintf(error_message, format, arguments); if (error_print) - MessageBox(GetFocus(), error_message, "WFDB Library Error", - MB_ICONASTERISK | MB_OK); + MessageBox(GetFocus(), wfdberror(), "WFDB Library Error", + MB_ICONASTERISK | MB_OK); #endif - va_end(arguments); } +/* The wfdb_fprintf function handles all formatted output to files. It is +used in the same way as the standard fprintf function, except that its first +argument is a pointer to a WFDB_FILE rather than a FILE. */ + #if WFDB_NETFILES static int nf_vfprintf(netfile *nf, const char *format, va_list ap) { @@ -786,73 +869,17 @@ return (ret); } -#else -#ifndef OLDC /* Second version: for traditional UNIX K&R C compilers */ -#include -void wfdb_error(va_alist) -va_dcl -{ - va_list arguments; - char *format; - - va_start(arguments); - format = va_arg(arguments, char *); - (void)vsprintf(error_message, format, arguments); - if (error_print) { - (void)fprintf(stderr, "%s", error_message); - (void)fflush(stderr); - } - va_end(arguments); -} - -int wfdb_fprintf(va_alist) -va_dcl -{ - va_list arguments; - WFDB_FILE *wp; - char *format; - static char obuf[1024]; /* careful: buffer overflows possible! */ - int ret; - - va_start(arguments); - wp = va_arg(arguments, WFDB_FILE *); - format = va_arg(arguments, char *); - (void)vsprintf(obuf, format, arguments); - ret = fprintf(wp->fp, format, obuf); - va_end(arguments); - return (ret); -} - -#else /* Third version: for many older C compilers */ -void wfdb_error(format, arguments) -char *format; -{ - if (error_print) { - (void)_doprnt(format, &arguments, stderr); - (void)fflush(stderr); - } -} - -int wfdb_fprintf(wp, format, arguments) -WFDB_FILE *wp; -char *format; -{ - return (_doprnt(format, &arguments, wp->fp)); -} -#endif -#endif - #define spr1(S, RECORD, TYPE) ((*TYPE == '\0') ? \ - (void)sprintf(S, "%s", RECORD) : \ - (void)sprintf(S, "%s.%s", RECORD, TYPE)) + wfdb_asprintf(S, "%s", RECORD) : \ + wfdb_asprintf(S, "%s.%s", RECORD, TYPE)) #ifdef FIXISOCD # define spr2(S, RECORD, TYPE) ((*TYPE == '\0') ? \ - (void)sprintf(S, "%s;1", RECORD) : \ - (void)sprintf(S, "%s.%.3s;1",RECORD,TYPE)) + wfdb_asprintf(S, "%s;1", RECORD) : \ + wfdb_asprintf(S, "%s.%.3s;1",RECORD,TYPE)) #else # define spr2(S, RECORD, TYPE) ((*TYPE == '\0') ? \ - (void)sprintf(S, "%s.", RECORD) : \ - (void)sprintf(S, "%s.%.3s", RECORD, TYPE)) + wfdb_asprintf(S, "%s.", RECORD) : \ + wfdb_asprintf(S, "%s.%.3s", RECORD, TYPE)) #endif static char irec[WFDB_MAXRNL+1]; /* current record name, set by wfdb_setirec */ @@ -915,9 +942,10 @@ WFDB_FILE *wfdb_open(const char *s, const char *record, int mode) { - char *wfdb, *p, *q, *r; + char *wfdb, *p, *q, *r, *buf = NULL; int rlen; struct wfdb_path_component *c0; + int bufsize, len, ireclen; WFDB_FILE *ifile; /* If the type (s) is empty, replace it with an empty string so that @@ -952,14 +980,18 @@ the final element (e.g., 'abc/123/' becomes 'abc/123/123'). */ rlen = strlen(record); p = (char *)(record + rlen - 1); - if (*p == '/') { + if (rlen > 1 && *p == '/') { for (q = p-1; q > record; q--) if (*q == '/') { q++; break; } - if (q < p-1) { + if (q < p) { SUALLOC(r, rlen + p-q + 1, 1); /* p-q is length of final element */ strcpy(r, record); strncpy(r + rlen, q, p-q); } + else { + SUALLOC(r, rlen + 1, 1); + strcpy(r, record); + } } else { SUALLOC(r, rlen + 1, 1); @@ -970,12 +1002,12 @@ An output file can be opened in another directory if the path to that directory is the first part of 'record'. */ if (mode == WFDB_WRITE) { - spr1(wfdb_filename, r, s); + spr1(&wfdb_filename, r, s); SFREE(r); return (wfdb_fopen(wfdb_filename, WB)); } else if (mode == WFDB_APPEND) { - spr1(wfdb_filename, r, s); + spr1(&wfdb_filename, r, s); SFREE(r); return (wfdb_fopen(wfdb_filename, AB)); } @@ -987,9 +1019,7 @@ this case, don't search the WFDB path, but add its parent directory to the path if the file can be read. */ if (strncmp(r, "http://", 7) == 0 || strncmp(r, "https://", 8) == 0) { - if (strlen(r) + strlen(s) >= MFNLEN) - return (NULL); /* name too long */ - spr1(wfdb_filename, r, s); + spr1(&wfdb_filename, r, s); if ((ifile = wfdb_fopen(wfdb_filename, RB)) != NULL) { /* Found it! Add its path info to the WFDB path. */ wfdb_addtopath(wfdb_filename); @@ -999,36 +1029,45 @@ } for (c0 = wfdb_path_list; c0; c0 = c0->next) { - static char long_filename[MFNLEN]; + char *long_filename = NULL; - p = wfdb_filename; + ireclen = strlen(irec); + bufsize = 64; + SALLOC(buf, 1, bufsize); + len = 0; wfdb = c0->prefix; - while (*wfdb && p < wfdb_filename+MFNLEN-20) { - if (*wfdb == '%') { + while (*wfdb) { + while (len + ireclen >= bufsize) { + bufsize *= 2; + SREALLOC(buf, 1, bufsize); + } + if (!buf) + break; + + if (*wfdb == '%') { /* Perform substitutions in the WFDB path where '%' is found */ wfdb++; if (*wfdb == 'r') { /* '%r' -> record name */ - (void)strcpy(p, irec); - p += strlen(p); + (void)strcpy(buf + len, irec); + len += ireclen; wfdb++; } else if ('1' <= *wfdb && *wfdb <= '9' && *(wfdb+1) == 'r') { /* '%Nr' -> first N characters of record name */ int n = *wfdb - '0'; - int len = strlen(irec); - if (len < n) n = len; - (void)strncpy(p, irec, n); - p += n; - *p = '\0'; + if (ireclen < n) n = ireclen; + (void)strncpy(buf + len, irec, n); + len += n; + buf[len] = '\0'; wfdb += 2; } else /* '%X' -> X, if X is neither 'r', nor a non-zero digit followed by 'r' */ - *p++ = *wfdb++; + buf[len++] = *wfdb++; } - else *p++ = *wfdb++; + else buf[len++] = *wfdb++; } /* Unless the WFDB component was empty, or it ended with a directory separator, append a directory separator to wfdb_filename; then @@ -1036,36 +1075,50 @@ files (URLs) are always constructed using '/' separators, even if the native directory separator is '\' (MS-DOS) or ':' (Macintosh). */ - if (p != wfdb_filename) { + if (len + 2 >= bufsize) { + bufsize = len + 2; + SREALLOC(buf, 1, bufsize); + } + if (!buf) + continue; + if (len > 0) { if (c0->type == WFDB_NET) { - if (*(p-1) != '/') *p++ = '/'; + if (buf[len-1] != '/') buf[len++] = '/'; } #ifndef MSDOS - else if (*(p-1) != DSEP) + else if (buf[len-1] != DSEP) #else - else if (*(p-1) != DSEP && *(p-1) != ':') + else if (buf[len-1] != DSEP && buf[len-1] != ':') #endif - *p++ = DSEP; + buf[len++] = DSEP; } - if (p + strlen(r) + (s ? strlen(s) : 0) > wfdb_filename + MFNLEN-5) - continue; /* name too long -- skip */ - spr1(p, r, s); + buf[len] = 0; + wfdb_asprintf(&buf, "%s%s", buf, r); + if (!buf) + continue; + + spr1(&wfdb_filename, buf, s); if ((ifile = wfdb_fopen(wfdb_filename, RB)) != NULL) { /* Found it! Add its path info to the WFDB path. */ wfdb_addtopath(wfdb_filename); + SFREE(buf); SFREE(r); return (ifile); } /* Not found -- try again, using an alternate form of the name, provided that that form is distinct. */ - strcpy(long_filename, wfdb_filename); - spr2(p, r, s); + SSTRCPY(long_filename, wfdb_filename); + spr2(&wfdb_filename, buf, s); if (strcmp(wfdb_filename, long_filename) && (ifile = wfdb_fopen(wfdb_filename, RB)) != NULL) { wfdb_addtopath(wfdb_filename); + SFREE(long_filename); + SFREE(buf); SFREE(r); return (ifile); } + SFREE(long_filename); + SFREE(buf); } /* If the file was not found in any of the directories listed in wfdb, return a null file pointer to indicate failure. */ @@ -1140,20 +1193,18 @@ /* WFDB file I/O functions The WFDB library normally reads and writes local files. If libcurl -(http://curl.haxx.se/) or libwww (http://www.w3.org/Library) is available, -the WFDB library can also read files from any accessible World Wide Web (HTTP) -or FTP server. (Writing files to a remote WWW or FTP server may be -supported in the future.) - -If you do not wish to allow access to remote files, or if neither libcurl nor -libwww is available, simply define the symbol WFDB_NETFILES as 0 when compiling -the WFDB library. If the symbol WFDB_NETFILES is zero, wfdblib.h defines -wfdb_fread as fread, wfdb_fwrite as fwrite, etc.; thus in this case, the -I/O is performed using the standard C I/O functions, and the function -definitions in the next section are not compiled. This behavior exactly -mimics that of versions of the WFDB library earlier than version 10.0.1 -(which did not support remote file access), with no additional run-time -overhead. +(http://curl.haxx.se/) is available, the WFDB library can also read files from +any accessible World Wide Web (HTTP) or FTP server. (Writing files to a remote +WWW or FTP server may be supported in the future.) + +If you do not wish to allow access to remote files, or if libcurl is not +available, simply define the symbol WFDB_NETFILES as 0 when compiling the WFDB +library. If the symbol WFDB_NETFILES is zero, wfdblib.h defines wfdb_fread as +fread, wfdb_fwrite as fwrite, etc.; thus in this case, the I/O is performed +using the standard C I/O functions, and the function definitions in the next +section are not compiled. This behavior exactly mimics that of versions of the +WFDB library earlier than version 10.0.1 (which did not support remote file +access), with no additional run-time overhead. If WFDB_NETFILES is non-zero, however, these functions are compiled. The WFDB_FILE pointers that are among the arguments to these functions point to @@ -1162,7 +1213,7 @@ All access to local files is handled by passing the 'fp' member of the WFDB_FILE object to the appropriate standard C I/O function. Access to remote files via http or ftp is handled by passing the 'netfp' member of the WFDB_FILE -object to the appropriate libcurl or libwww function(s). +object to the appropriate libcurl function(s). In order to read remote files, the WFDB environment variable should include one or more components that specify http:// or ftp:// URL prefixes. These @@ -1180,13 +1231,22 @@ #if WFDB_NETFILES +struct netfile { + char *url; + char *data; + int mode; + long base_addr; + long cont_len; + long pos; + long err; + int fd; +}; + static int nf_open_files = 0; /* number of open netfiles */ static long page_size = NF_PAGE_SIZE; /* bytes per range request (0: disable range requests) */ -static int www_done_init = FALSE; /* TRUE once libcurl or libwww is - initialized */ +static int www_done_init = FALSE; /* TRUE once libcurl is initialized */ -#if WFDB_NETFILES_LIBCURL static CURL *curl_ua = NULL; /* Construct the User-Agent string to be sent with HTTP requests. */ @@ -1196,9 +1256,8 @@ static char *s = NULL; libcurl_ver = curl_version(); - SALLOC(s, 1, 32 + strlen(libcurl_ver)); - sprintf(s, "libwfdb/%d.%d.%d (%s)", WFDB_MAJOR, WFDB_MINOR, - WFDB_RELEASE, libcurl_ver); + wfdb_asprintf(&s, "libwfdb/%d.%d.%d (%s)", WFDB_MAJOR, WFDB_MINOR, + WFDB_RELEASE, libcurl_ver); return (s); } @@ -1234,14 +1293,6 @@ #define chunk_new curl_chunk_new #define chunk_delete curl_chunk_delete #define chunk_putb curl_chunk_putb -#else -#define CHUNK HTChunk -#define chunk_size HTChunk_size -#define chunk_data HTChunk_data -#define chunk_new HTChunk_new -#define chunk_delete HTChunk_delete -#define chunk_putb HTChunk_putb -#endif static char **passwords; @@ -1315,17 +1366,10 @@ { int i; if (www_done_init) { -#if WFDB_NETFILES_LIBCURL -# ifndef _WINDOWS +#ifndef _WINDOWS curl_easy_cleanup(curl_ua); curl_ua = NULL; curl_global_cleanup(); -# endif -#else -#ifdef USEHTCACHE - HTCacheTerminate(); -#endif - HTProfile_delete(); #endif www_done_init = FALSE; for (i = 0; passwords && passwords[i]; i++) @@ -1337,12 +1381,11 @@ static void www_init(void) { if (!www_done_init) { - char *p, version[20]; + char *p; if ((p = getenv("WFDB_PAGESIZE")) && *p) page_size = strtol(p, NULL, 10); -#if WFDB_NETFILES_LIBCURL /* Initialize the curl "easy" handle. */ curl_global_init(CURL_GLOBAL_ALL); curl_ua = curl_easy_init(); @@ -1370,38 +1413,12 @@ /* Show details of URL requests if WFDB_NET_DEBUG is set */ if ((p = getenv("WFDB_NET_DEBUG")) && *p) curl_easy_setopt(curl_ua, CURLOPT_VERBOSE, 1L); -#else -#ifdef USEHTCACHE - char *cachedir = CACHEDIR; /* root of the netfile data cache */ - int cachesize = CACHESIZE; /* maximum size of the cache in MB */ - int entrysize = ENTRYSIZE; /* maximum cache entry size in MB */ - - if ((p = getenv("WFDB_CACHEDIR")) && *p) - cachedir = p; - if ((p = getenv("WFDB_CACHESIZE")) && *p) - cachesize = strtol(p, NULL, 10); - if ((p = getenv("WFDB_CACHEENTRYSIZE")) && *p) - entrysize = strtol(p, NULL, 10); -#endif - sprintf(version, "%d.%d.%d", WFDB_MAJOR, WFDB_MINOR, WFDB_RELEASE); - HTProfile_newPreemptiveClient("WFDB", version); - HTAlert_setInteractive(NO); -#ifdef USEHTCACHE - HTLib_setSecure(TRUE); - HTCacheInit(cachedir, cachesize); - HTCacheMode_setMaxCacheEntrySize(entrysize); -#endif - /* HTHost_setMaxPipelinedRequests(1); */ - HTEventInit(); /* added 19 July 2001 -- necessary for use with - WINSOCK, seems to be harmless otherwise */ -#endif atexit(wfdb_wwwquit); www_done_init = TRUE; } } -#if WFDB_NETFILES_LIBCURL /* This function is called when a header is received. ptr points to the string received; size*nmemb is the number of bytes, and stream is the pointer specified as CURLOPT_WRITEHEADER. */ @@ -1416,11 +1433,9 @@ } return size*nmemb; } -#endif static long www_get_cont_len(const char *url) { -#if WFDB_NETFILES_LIBCURL static double length; length = 0; @@ -1449,26 +1464,8 @@ return 0; return (long) length; -#else - HTRequest *request = NULL; - HTParentAnchor *a = NULL; - HTAssocList *headers = NULL; - HTAssoc *pres = NULL; - long length = 0L; - - if (url && *url && (request = HTRequest_new())) { - HTHeadAbsolute(url, request); - if ((a = HTRequest_anchor(request)) && (headers = HTAnchor_header(a))) - while ((pres = (HTAssoc *)HTAssocList_nextObject(headers))) - if (HTStrCaseMatch("Content-Length", HTAssoc_name(pres))) - length = strtol(HTAssoc_value(pres), NULL, 10); - HTRequest_delete(request); - } - return (length); -#endif } -#if WFDB_NETFILES_LIBCURL /* Create a new, empty chunk. */ static CHUNK *curl_chunk_new(long len) { @@ -1521,21 +1518,14 @@ { curl_chunk_write(data, 1, len, chunk); } -#endif static CHUNK *www_get_url_range_chunk(const char *url, long startb, long len) { -#if !WFDB_NETFILES_LIBCURL - HTRequest *request = NULL; - HTList *request_err = NULL; - HTError *err = NULL; -#endif CHUNK *chunk = NULL, *extra_chunk = NULL; char range_req_str[6*sizeof(long) + 2]; if (url && *url) { sprintf(range_req_str, "%ld-%ld", startb, startb+len-1); -#if WFDB_NETFILES_LIBCURL chunk = chunk_new(len); if (/* In this case we want to send a GET request rather than @@ -1565,25 +1555,6 @@ return NULL; } -#else - request = HTRequest_new(); - HTRequest_addRange(request, "bytes", range_req_str); - HTRequest_setOutputFormat(request, WWW_SOURCE); - HTRequest_setPreemptive(request, YES); - chunk = HTLoadToChunk(url, request); - request_err = HTRequest_error(request); - while ((err = (HTError *) HTList_nextObject(request_err)) != NULL) { - if (HTError_severity(err) == ERR_FATAL) { - wfdb_error( - "www_get_url_range_chunk: fatal error requesting %s (%s)\n", - url, range_req_str); - if (chunk) { - chunk_delete(chunk); - chunk = NULL; - } - } - } -#endif if (chunk && (chunk_size(chunk) > len)) { /* We received a larger chunk than requested. */ if (chunk_size(chunk) >= startb + len) { @@ -1615,9 +1586,6 @@ if (retry) { retry = 0; -#if !WFDB_NETFILES_LIBCURL - HTRequest_delete(request); -#endif fflush(stderr); chunk = www_get_url_range_chunk(url, startb, len); retry = 1; @@ -1637,9 +1605,6 @@ } } } -#if !WFDB_NETFILES_LIBCURL - HTRequest_delete(request); -#endif } return (chunk); } @@ -1648,7 +1613,6 @@ { CHUNK *chunk = NULL; -#if WFDB_NETFILES_LIBCURL chunk = chunk_new(1024); if (/* Send a GET request */ @@ -1656,6 +1620,9 @@ || curl_try(curl_easy_setopt(curl_ua, CURLOPT_HTTPGET, 1L)) /* URL to retrieve */ || curl_try(curl_easy_setopt(curl_ua, CURLOPT_URL, url)) + /* Set username/password */ + || curl_try(curl_easy_setopt(curl_ua, CURLOPT_USERPWD, + www_userpwd(url))) /* No range request */ || curl_try(curl_easy_setopt(curl_ua, CURLOPT_RANGE, NULL)) /* Write to the chunk specified ... */ @@ -1673,31 +1640,6 @@ return NULL; } -#else - HTRequest *request = NULL; - HTList *request_err = NULL; - HTError *err = NULL; - - if (url && *url) { - request = HTRequest_new(); - HTRequest_setOutputFormat(request, WWW_SOURCE); - HTRequest_setPreemptive(request, YES); - chunk = HTLoadToChunk(url, request); - request_err = HTRequest_error(request); - while ((err = (HTError *) HTList_nextObject(request_err)) != NULL) { - if (HTError_severity(err) == ERR_FATAL) { - /* This occurs if the remote file doesn't exist. This happens - routinely while searching the WFDB path, so it's not flagged - as a WFDB library error. */ - if (chunk) { - chunk_delete(chunk); - chunk = NULL; - } - } - } - HTRequest_delete(request); - } -#endif return (chunk); } @@ -1831,7 +1773,7 @@ /* long request (> page_size) */ if (chunk_size(chunk) != len) { wfdb_error( - "nf_get_range: requested %d bytes, received %d bytes\n", + "nf_get_range: requested %ld bytes, received %ld bytes\n", len, (long)chunk_size(chunk)); } rp = chunk_data(chunk); @@ -1985,6 +1927,20 @@ return (EOF); } +#else /* !WFDB_NETFILES */ +# define nf_feof(nf) (0) +# define nf_fgetc(nf) (EOF) +# define nf_fgets(s, size, nf) (NULL) +# define nf_fread(ptr, size, nmemb, nf) (0) +# define nf_fseek(nf, offset, whence) (-1) +# define nf_ftell(nf) (-1) +# define nf_ferror(nf) (0) +# define nf_clearerr(nf) ((void) 0) +# define nf_fflush(nf) (EOF) +# define nf_fwrite(ptr, size, nmemb, nf) (0) +# define nf_putc(c, nf) (EOF) +#endif + /* The definition of nf_vfprintf (which is a stub) has been moved; it is now just before wfdb_fprintf, which refers to it. There is no completely portable way to make a forward reference to a static (local) function. */ @@ -1992,8 +1948,9 @@ void wfdb_clearerr(WFDB_FILE *wp) { if (wp->type == WFDB_NET) - return (nf_clearerr(wp->netfp)); - return (clearerr(wp->fp)); + nf_clearerr(wp->netfp); + else + clearerr(wp->fp); } int wfdb_feof(WFDB_FILE *wp) @@ -2071,8 +2028,6 @@ return (putc(c, wp->fp)); } -#endif /* WFDB_NETFILES */ - int wfdb_fclose(WFDB_FILE *wp) { int status; diff -Naur '--exclude=Makefile' wfdb-10.5.24/lib/wfdblib.h wfdb-10.6.0/lib/wfdblib.h --- wfdb-10.5.24/lib/wfdblib.h 2015-05-28 15:58:55.000000000 -0400 +++ wfdb-10.6.0/lib/wfdblib.h 2018-01-26 16:46:19.000000000 -0500 @@ -1,5 +1,5 @@ /* file: wfdblib.h G. Moody 13 April 1989 - Last revised: 27 September 2012 wfdblib 10.5.16 + Last revised: 13 November 2017 wfdblib 10.6.0 External definitions for WFDB library private functions _______________________________________________________________________________ @@ -201,17 +201,6 @@ #endif /* Structures used by internal WFDB library functions only */ -struct netfile { - char *url; - char *data; - int mode; - long base_addr; - long cont_len; - long pos; - long err; - int fd; -}; - struct WFDB_FILE { FILE *fp; struct netfile *netfp; @@ -264,19 +253,6 @@ #define NF_CHUNK_MODE 0 /* http range requests supported */ #define NF_FULL_MODE 1 /* http range requests not supported */ -#else /* WFDB_NETFILES = 0 -- use standard I/O functions only */ - -#define wfdb_feof(wp) feof(wp->fp) -#define wfdb_ferror(wp) ferror(wp->fp) -#define wfdb_fflush(wp) ((wp == NULL) ? fflush(NULL) : fflush(wp->fp)) -#define wfdb_fgets(s, n, wp) fgets(s, n, wp->fp) -#define wfdb_fread(p, s, n, wp) fread(p, s, n, wp->fp) -#define wfdb_fseek(wp, o, w) fseek(wp->fp, o, w) -#define wfdb_ftell(wp) ftell(wp->fp) -#define wfdb_fwrite(p, s, n, wp) fwrite(p, s, n, wp->fp) -#define wfdb_getc(wp) getc(wp->fp) -#define wfdb_putc(c, wp) putc(c, wp->fp) - #endif #ifdef _WINDOWS @@ -319,13 +295,18 @@ extern void wfdb_p32(long x, WFDB_FILE *fp); extern int wfdb_parse_path(char *wfdb_path); extern void wfdb_addtopath(char *pathname); -extern void wfdb_error(char *format_string, ...); +#if __GNUC__ >= 3 +__attribute__((__format__(__printf__, 2, 3))) +#endif +extern int wfdb_asprintf(char **buffer, const char *format, ...); extern WFDB_FILE *wfdb_fopen(char *fname, const char *mode); +#if __GNUC__ >= 3 +__attribute__((__format__(__printf__, 2, 3))) +#endif extern int wfdb_fprintf(WFDB_FILE *fp, const char *format, ...); extern void wfdb_setirec(const char *record_name); extern char *wfdb_getirec(void); -#if WFDB_NETFILES extern void wfdb_clearerr(WFDB_FILE *fp); extern int wfdb_feof(WFDB_FILE *fp); extern int wfdb_ferror(WFDB_FILE *fp); @@ -337,7 +318,6 @@ extern size_t wfdb_fwrite(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); extern int wfdb_getc(WFDB_FILE *fp); extern int wfdb_putc(int c, WFDB_FILE *fp); -#endif /* These functions are defined in signal.c */ extern void wfdb_sampquit(void); @@ -361,19 +341,17 @@ wfdb_fprintf(); extern long wfdb_g32(); extern void wfdb_striphea(), wfdb_p16(), wfdb_p32(), wfdb_addtopath(), - wfdb_error(), wfdb_setirec(), wfdb_sampquit(), wfdb_sigclose(), + wfdb_setirec(), wfdb_sampquit(), wfdb_sigclose(), wfdb_osflush(), wfdb_freeinfo(), wfdb_oinfoclose(), wfdb_anclose(), wfdb_oaflush(); extern WFDB_FILE *wfdb_open(), *wfdb_fopen(); -# if WFDB_NETFILES extern char *wfdb_fgets(); extern int wfdb_feof(), wfdb_ferror(), wfdb_fflush(), wfdb_fseek(), wfdb_getc(), wfdb_putc(); extern long wfdb_ftell(); extern size_t wfdb_fread(), wfdb_fwrite(); extern void wfdb_clearerr(); -# endif /* Some non-ANSI C libraries (e.g., version 7, BSD 4.2) lack an implementation of strtok(); define NOSTRTOK to compile the portable version in wfdbio.c. */ diff -Naur '--exclude=Makefile' wfdb-10.5.24/lib/wfdblib.h0 wfdb-10.6.0/lib/wfdblib.h0 --- wfdb-10.5.24/lib/wfdblib.h0 2015-05-28 15:55:16.000000000 -0400 +++ wfdb-10.6.0/lib/wfdblib.h0 2017-11-13 18:48:18.000000000 -0500 @@ -1,5 +1,5 @@ /* file: wfdblib.h G. Moody 13 April 1989 - Last revised: 27 September 2012 wfdblib 10.5.16 + Last revised: 13 November 2017 wfdblib 10.6.0 External definitions for WFDB library private functions _______________________________________________________________________________ @@ -201,17 +201,6 @@ #endif /* Structures used by internal WFDB library functions only */ -struct netfile { - char *url; - char *data; - int mode; - long base_addr; - long cont_len; - long pos; - long err; - int fd; -}; - struct WFDB_FILE { FILE *fp; struct netfile *netfp; @@ -264,19 +253,6 @@ #define NF_CHUNK_MODE 0 /* http range requests supported */ #define NF_FULL_MODE 1 /* http range requests not supported */ -#else /* WFDB_NETFILES = 0 -- use standard I/O functions only */ - -#define wfdb_feof(wp) feof(wp->fp) -#define wfdb_ferror(wp) ferror(wp->fp) -#define wfdb_fflush(wp) ((wp == NULL) ? fflush(NULL) : fflush(wp->fp)) -#define wfdb_fgets(s, n, wp) fgets(s, n, wp->fp) -#define wfdb_fread(p, s, n, wp) fread(p, s, n, wp->fp) -#define wfdb_fseek(wp, o, w) fseek(wp->fp, o, w) -#define wfdb_ftell(wp) ftell(wp->fp) -#define wfdb_fwrite(p, s, n, wp) fwrite(p, s, n, wp->fp) -#define wfdb_getc(wp) getc(wp->fp) -#define wfdb_putc(c, wp) putc(c, wp->fp) - #endif #ifdef _WINDOWS @@ -319,13 +295,18 @@ extern void wfdb_p32(long x, WFDB_FILE *fp); extern int wfdb_parse_path(char *wfdb_path); extern void wfdb_addtopath(char *pathname); -extern void wfdb_error(char *format_string, ...); +#if __GNUC__ >= 3 +__attribute__((__format__(__printf__, 2, 3))) +#endif +extern int wfdb_asprintf(char **buffer, const char *format, ...); extern WFDB_FILE *wfdb_fopen(char *fname, const char *mode); +#if __GNUC__ >= 3 +__attribute__((__format__(__printf__, 2, 3))) +#endif extern int wfdb_fprintf(WFDB_FILE *fp, const char *format, ...); extern void wfdb_setirec(const char *record_name); extern char *wfdb_getirec(void); -#if WFDB_NETFILES extern void wfdb_clearerr(WFDB_FILE *fp); extern int wfdb_feof(WFDB_FILE *fp); extern int wfdb_ferror(WFDB_FILE *fp); @@ -337,7 +318,6 @@ extern size_t wfdb_fwrite(void *ptr, size_t size, size_t nmemb, WFDB_FILE *fp); extern int wfdb_getc(WFDB_FILE *fp); extern int wfdb_putc(int c, WFDB_FILE *fp); -#endif /* These functions are defined in signal.c */ extern void wfdb_sampquit(void); @@ -361,19 +341,17 @@ wfdb_fprintf(); extern long wfdb_g32(); extern void wfdb_striphea(), wfdb_p16(), wfdb_p32(), wfdb_addtopath(), - wfdb_error(), wfdb_setirec(), wfdb_sampquit(), wfdb_sigclose(), + wfdb_setirec(), wfdb_sampquit(), wfdb_sigclose(), wfdb_osflush(), wfdb_freeinfo(), wfdb_oinfoclose(), wfdb_anclose(), wfdb_oaflush(); extern WFDB_FILE *wfdb_open(), *wfdb_fopen(); -# if WFDB_NETFILES extern char *wfdb_fgets(); extern int wfdb_feof(), wfdb_ferror(), wfdb_fflush(), wfdb_fseek(), wfdb_getc(), wfdb_putc(); extern long wfdb_ftell(); extern size_t wfdb_fread(), wfdb_fwrite(); extern void wfdb_clearerr(); -# endif /* Some non-ANSI C libraries (e.g., version 7, BSD 4.2) lack an implementation of strtok(); define NOSTRTOK to compile the portable version in wfdbio.c. */ diff -Naur '--exclude=Makefile' wfdb-10.5.24/psd/Makefile.tpl wfdb-10.6.0/psd/Makefile.tpl --- wfdb-10.5.24/psd/Makefile.tpl 2015-05-28 15:55:16.000000000 -0400 +++ wfdb-10.6.0/psd/Makefile.tpl 2017-03-09 18:13:19.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 11 May 2006 +# Last revised: 8 March 2017 # This section of the Makefile should not need to be changed. # Programs to be compiled. @@ -13,45 +13,46 @@ $(STRIP) $(XFILES) # `make' or `make install': build and install applications -install: $(BINDIR) all scripts +install: $(DESTDIR)$(BINDIR) all scripts $(SETXPERMISSIONS) $(XFILES) - ../install.sh $(BINDIR) $(XFILES) + ../install.sh $(DESTDIR)$(BINDIR) $(XFILES) # 'make collect': retrieve the installed applications collect: ../conf/collect.sh $(BINDIR) $(XFILES) $(SCRIPTS) # `make scripts': customize and install scripts -scripts: - sed s+BINDIR+$(BINDIR)+g $(BINDIR)/hrfft - sed s+BINDIR+$(BINDIR)+g $(BINDIR)/hrlomb - sed s+BINDIR+$(BINDIR)+g $(BINDIR)/hrmem - sed s+BINDIR+$(BINDIR)+g $(BINDIR)/hrplot - cp plot2d plot3d $(BINDIR) - cd $(BINDIR); $(SETXPERMISSIONS) $(SCRIPTS) +scripts: $(DESTDIR)$(BINDIR) + sed s+BINDIR+$(BINDIR)+g $(DESTDIR)$(BINDIR)/hrfft + sed s+BINDIR+$(BINDIR)+g $(DESTDIR)$(BINDIR)/hrlomb + sed s+BINDIR+$(BINDIR)+g $(DESTDIR)$(BINDIR)/hrmem + sed s+BINDIR+$(BINDIR)+g $(DESTDIR)$(BINDIR)/hrplot + cp plot2d plot3d $(DESTDIR)$(BINDIR) + cd $(DESTDIR)$(BINDIR); $(SETXPERMISSIONS) $(SCRIPTS) uninstall: - ../uninstall.sh $(BINDIR) $(XFILES) $(SCRIPTS) + ../uninstall.sh $(DESTDIR)$(BINDIR) $(XFILES) $(SCRIPTS) coherence: coherence.c - $(CC) -o coherence -O coherence.c -lm + $(CC) $(MFLAGS) -o coherence -O coherence.c -lm fft: fft.c - $(CC) -o fft -O fft.c -lm + $(CC) $(MFLAGS) -o fft -O fft.c -lm log10: log10.c - $(CC) $(CCDEFS) -o log10 -O log10.c -lm + $(CC) $(MFLAGS) $(CCDEFS) -o log10 -O log10.c -lm lomb: lomb.c - $(CC) -o lomb -O lomb.c -lm + $(CC) $(MFLAGS) -o lomb -O lomb.c -lm memse: memse.c - $(CC) -o memse -O memse.c -lm + $(CC) $(MFLAGS) -o memse -O memse.c -lm # `make clean': remove intermediate and backup files. clean: rm -f *.o *~ $(XFILES) # Create directory for installation if necessary. -$(BINDIR): - mkdir -p $(BINDIR); $(SETDPERMISSIONS) $(BINDIR) +$(DESTDIR)$(BINDIR): + mkdir -p $(DESTDIR)$(BINDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(BINDIR) diff -Naur '--exclude=Makefile' wfdb-10.5.24/wave/Makefile.tpl wfdb-10.6.0/wave/Makefile.tpl --- wfdb-10.5.24/wave/Makefile.tpl 2015-05-28 15:55:16.000000000 -0400 +++ wfdb-10.6.0/wave/Makefile.tpl 2017-03-09 18:13:19.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 31 May 2000 -# Last revised: 21 February 2009 +# Last revised: 8 March 2017 # Change the settings below as appropriate for your setup. # Choose directories in which to install WAVE and its ancillary files by @@ -44,15 +44,17 @@ all: wave wave.hlp news.hlp # `make install': compile and install WAVE and its help files -install: $(BINDIR) $(HELPDIR)/wave $(MENUDIR) $(RESDIR) wave.hlp news.hlp +install: $(DESTDIR)$(BINDIR) $(DESTDIR)$(HELPDIR)/wave $(DESTDIR)$(MENUDIR) $(DESTDIR)$(RESDIR) wave.hlp news.hlp rm -f wave.o analyze.o xvwave.o $(MAKE) wave # make sure all compiled-in paths are up-to-date - $(STRIP) wave; $(SETXPERMISSIONS) wave; ../install.sh $(BINDIR) wave - cp $(HELPFILES) wave.hlp wave.info demo.txt $(HELPDIR)/wave - cd $(HELPDIR)/wave; $(SETPERMISSIONS) $(HELPFILES) wave.info demo.txt - -cp wavemenu.def $(MENUDIR) && \ - $(SETPERMISSIONS) $(MENUDIR)/wavemenu.def - -cp Wave.res $(RESDIR)/Wave && $(SETPERMISSIONS) $(RESDIR)/Wave + $(STRIP) wave; $(SETXPERMISSIONS) wave + ../install.sh $(DESTDIR)$(BINDIR) wave + cp $(HELPFILES) wave.hlp wave.info demo.txt $(DESTDIR)$(HELPDIR)/wave + cd $(DESTDIR)$(HELPDIR)/wave; $(SETPERMISSIONS) $(HELPFILES) wave.info demo.txt + -cp wavemenu.def $(DESTDIR)$(MENUDIR) && \ + $(SETPERMISSIONS) $(DESTDIR)$(MENUDIR)/wavemenu.def + -cp Wave.res $(DESTDIR)$(RESDIR)/Wave && \ + $(SETPERMISSIONS) $(DESTDIR)$(RESDIR)/Wave # 'make collect': retrieve the installed applications collect: @@ -62,14 +64,14 @@ ../conf/collect.sh $(RESDIR) Wave uninstall: - ../uninstall.sh $(BINDIR) wave - ../uninstall.sh $(HELPDIR)/wave $(HELPFILES) wave.hlp wave.info \ - demo.txt - rmdir $(HELPDIR) || echo "(Ignored)" - ../uninstall.sh $(MENUDIR) wavemenu.def - ../uninstall.sh $(RESDIR) Wave - ../uninstall.sh $(LIBDIR)/X11 - ../uninstall.sh $(LIBDIR) + ../uninstall.sh $(DESTDIR)$(BINDIR) wave + ../uninstall.sh $(DESTDIR)$(HELPDIR)/wave $(HELPFILES) wave.hlp \ + wave.info demo.txt + rmdir $(DESTDIR)$(HELPDIR) || echo "(Ignored)" + ../uninstall.sh $(DESTDIR)$(MENUDIR) wavemenu.def + ../uninstall.sh $(DESTDIR)$(RESDIR) Wave + ../uninstall.sh $(DESTDIR)$(LIBDIR)/X11 + ../uninstall.sh $(DESTDIR)$(LIBDIR) wave: $(OFILES) $(CC) $(WCFLAGS) -o wave $(OFILES) $(WLDFLAGS) @@ -97,7 +99,7 @@ $(CC) $(WCFLAGS) -o wave-static $(OFILES) -static $(LDFLAGS) soelim: soelim.c - $(CC) -o soelim -O soelim.c + $(BUILD_CC) -o soelim -O soelim.c wave.hlp: soelim wave.hl0 $(HELPFILES) ./soelim wave.hl0 >wave.hlp @@ -107,7 +109,7 @@ sed "s%HELPDIR%$(HELPDIR)%" >news.hlp # `make manual': print the on-line manual -manual: +manual: soelim ./soelim wave.hl0 | $(PRINT) # `make guide': print the WAVE User's Guide @@ -161,13 +163,18 @@ $(CC) -c $(WCFLAGS) -w help.c # Create directories for installation if necessary. -$(BINDIR): - mkdir -p $(BINDIR); $(SETDPERMISSIONS) $(BINDIR) -$(HELPDIR): - mkdir -p $(HELPDIR); $(SETDPERMISSIONS) $(HELPDIR) -$(HELPDIR)/wave: - mkdir -p $(HELPDIR)/wave; $(SETDPERMISSIONS) $(HELPDIR)/wave -$(MENUDIR): - mkdir -p $(MENUDIR); $(SETDPERMISSIONS) $(MENUDIR) -$(RESDIR): - mkdir -p $(RESDIR); $(SETDPERMISSIONS) $(RESDIR) +$(DESTDIR)$(BINDIR): + mkdir -p $(DESTDIR)$(BINDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(BINDIR) +$(DESTDIR)$(HELPDIR): + mkdir -p $(DESTDIR)$(HELPDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(HELPDIR) +$(DESTDIR)$(HELPDIR)/wave: + mkdir -p $(DESTDIR)$(HELPDIR)/wave + $(SETDPERMISSIONS) $(DESTDIR)$(HELPDIR)/wave +$(DESTDIR)$(MENUDIR): + mkdir -p $(DESTDIR)$(MENUDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(MENUDIR) +$(DESTDIR)$(RESDIR): + mkdir -p $(DESTDIR)$(RESDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(RESDIR) diff -Naur '--exclude=Makefile' wfdb-10.5.24/wave/Wave.res wfdb-10.6.0/wave/Wave.res --- wfdb-10.5.24/wave/Wave.res 2015-05-28 15:55:17.000000000 -0400 +++ wfdb-10.6.0/wave/Wave.res 2017-03-13 14:04:07.000000000 -0400 @@ -31,6 +31,11 @@ ! Wave.SignalWindow.font: lucidasans-bold-14 ! (or use xlsfonts to find an alternative that you like). +! The default behavior for XView menu buttons is that the left mouse button +! (designated 'select') activates the menu's default action, whereas the right +! mouse button (designated 'menu') pops up the menu. If 'SelectDisplaysMenu' +! is set to 'true', either button will open the menu. +OpenWindows.SelectDisplaysMenu: true ! ----------------------------------------------------------------------------- diff -Naur '--exclude=Makefile' wfdb-10.5.24/wave/modepan.c wfdb-10.6.0/wave/modepan.c --- wfdb-10.5.24/wave/modepan.c 2015-05-28 15:55:17.000000000 -0400 +++ wfdb-10.6.0/wave/modepan.c 2017-08-15 14:02:31.000000000 -0400 @@ -1,5 +1,5 @@ /* file: modepan.c G. Moody 30 April 1990 - Last revised: 12 May 2009 + Last revised: 15 August 2017 Mode panel functions for WAVE ------------------------------------------------------------------------------- @@ -70,7 +70,8 @@ "0.25 mm/min", "1 mm/min", "5 mm/min", "25 mm/min", "50 mm/min", "125 mm/min", "250 mm/min", "500 mm/min", "12.5 mm/sec", "25 mm/sec", "50 mm/sec", "125 mm/sec", "250 mm/sec", - "500 mm/sec", "1000 mm/sec"}; + "500 mm/sec", "1000 mm/sec", "2000 mm/sec", "5000 mm/sec", + "10 mm/ms", "20 mm/ms", "50 mm/ms", "100 mm/ms", "200 mm/ms", "500 mm/ms"}; char *vchoice[] = { "1 mm/mV", "2.5 mm/mV", "5 mm/mV", "10 mm/mV", "20 mm/mV", "40 mm/mV", "100 mm/mV" }; @@ -105,6 +106,9 @@ tchoice[0], tchoice[1], tchoice[2], tchoice[3], tchoice[4], tchoice[5], tchoice[6], tchoice[7], tchoice[8], tchoice[9], tchoice[10],tchoice[11],tchoice[12],tchoice[13],tchoice[14], + tchoice[15],tchoice[16],tchoice[17],tchoice[18],tchoice[19], + tchoice[20],tchoice[21],tchoice[22],tchoice[23],tchoice[24], + tchoice[25], NULL, PANEL_VALUE, DEF_TSA_INDEX, PANEL_DEFAULT_VALUE, DEF_TSA_INDEX, @@ -262,7 +266,7 @@ small displays, or if the frame has been resized to a small size), the calculated widths in seconds are usually integers, at worst expressible as an integral number of tenths of seconds. */ - if ((i = xv_get(ts_item, PANEL_VALUE)) >= 0 && i < 15) { + if ((i = xv_get(ts_item, PANEL_VALUE)) >= 0) { int u = ((int)(canvas_width/dmmx(1) + 1)/5); /* number of 5 mm time-grid units */ switch (tsa_index = i) { @@ -320,6 +324,30 @@ case 17: /* 1000 mm/sec */ mmpersec = 1000.; canvas_width_sec = u / 200.0; break; + case 18: /* 2000 mm/sec */ + mmpersec = 2000.; + canvas_width_sec = u / 400.0; break; + case 19: /* 5000 mm/sec */ + mmpersec = 5000.; + canvas_width_sec = u / 1000.0; break; + case 20: /* 10 mm/ms */ + mmpersec = 10000.; + canvas_width_sec = u / 2000.0; break; + case 21: /* 20 mm/ms */ + mmpersec = 20000.; + canvas_width_sec = u / 4000.0; break; + case 22: /* 50 mm/ms */ + mmpersec = 50000.; + canvas_width_sec = u / 10000.0; break; + case 23: /* 100 mm/ms */ + mmpersec = 100000.; + canvas_width_sec = u / 20000.0; break; + case 24: /* 200 mm/ms */ + mmpersec = 200000.; + canvas_width_sec = u / 40000.0; break; + case 25: /* 500 mm/ms */ + mmpersec = 500000.; + canvas_width_sec = u / 100000.0; break; } } diff -Naur '--exclude=Makefile' wfdb-10.5.24/wave/sig.c wfdb-10.6.0/wave/sig.c --- wfdb-10.5.24/wave/sig.c 2015-05-28 15:55:17.000000000 -0400 +++ wfdb-10.6.0/wave/sig.c 2017-08-14 16:02:24.000000000 -0400 @@ -1,5 +1,5 @@ /* file: sig.c G. Moody 27 April 1990 - Last revised: 2 March 2010 + Last revised: 14 August 2017 Signal display functions for WAVE ------------------------------------------------------------------------------- @@ -321,13 +321,18 @@ for (lp = first_list; lp; lp = lp->next) if (lp->start == fdl_time && lp->npoints == nsamp) return (lp); - /* Give up if a display list can't be allocated, or if we can't skip - to the requested segment, or if we can't read at least one sample. */ - if ((lp = get_display_list()) == NULL || - (fdl_time != strtim("i") && isigsettime(fdl_time) < 0) || + /* Give up if we can't skip to the requested segment, or if we + can't read at least one sample. */ + if ((fdl_time != strtim("i") && isigsettime(fdl_time) < 0) || getvec(v0) < 0) return (NULL); + /* Allocate a new display list; give up if we can't do so. Note + that once the structure has been allocated, we must fill it in + with valid data. */ + if ((lp = get_display_list()) == NULL) + return (NULL); + /* Record the starting time. */ lp->start = fdl_time; @@ -503,6 +508,8 @@ { int i, l, xoff, yoff; + if (!lp) return; + yoff = mmy(2); for (i = 0; i < nsig; i++) { if (base[i] == -9999) continue; diff -Naur '--exclude=Makefile' wfdb-10.5.24/wave/xvwave.c wfdb-10.6.0/wave/xvwave.c --- wfdb-10.5.24/wave/xvwave.c 2015-05-28 15:55:17.000000000 -0400 +++ wfdb-10.6.0/wave/xvwave.c 2017-03-09 18:13:19.000000000 -0500 @@ -1,5 +1,5 @@ /* file: xvwave.c G. Moody 27 April 1990 - Last revised: 28 October 2009 + Last revised: 15 December 2016 XView support functions for WAVE ------------------------------------------------------------------------------- @@ -33,6 +33,8 @@ #include /* for struct passwd definition */ #include /* for SIGUSR1 definition */ #include /* for getpid definition */ +#include /* for setrlimit definition */ +#include /* for FD_SETSIZE definition */ #include #include /* for Xv_singlecolor definition */ #include @@ -168,9 +170,14 @@ int *pargc; char *argv[]; { + struct rlimit limit; char dfname[256], *resdir, *tmp, *getenv(); extern int fullscreendebug; + /* work around an xview bug (debian bug #784918) */ + limit.rlim_cur = limit.rlim_max = FD_SETSIZE; + setrlimit(RLIMIT_NOFILE, &limit); + fullscreendebug = 1; /* work around bug in Xorg 1.6+ by disabling grabs */ xv_init(XV_INIT_ARGC_PTR_ARGV, pargc, argv, NULL); diff -Naur '--exclude=Makefile' wfdb-10.5.24/waverc/Makefile.tpl wfdb-10.6.0/waverc/Makefile.tpl --- wfdb-10.5.24/waverc/Makefile.tpl 2015-05-28 15:55:17.000000000 -0400 +++ wfdb-10.6.0/waverc/Makefile.tpl 2017-03-09 18:13:19.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 11 May 2006 +# Last revised: 8 March 2017 # Change the settings below as appropriate for your setup. # `make all' creates wavescript and wave-remote without installing them. @@ -8,39 +8,40 @@ # `make install' installs `url_view', `wavescript', and `wave-remote'. See # the WAVE User's Guide for instructions on setting up `wavescript' as a helper # application for your Web browser. -install: $(BINDIR) wave-remote +install: $(DESTDIR)$(BINDIR) wave-remote rm -f wavescript wavescript.exe $(MAKE) wavescript # make sure wavescript has the correct BINDIR $(STRIP) wavescript wave-remote $(SETXPERMISSIONS) url_view wavescript wave-remote - ../install.sh $(BINDIR) url_view wavescript wave-remote + ../install.sh $(DESTDIR)$(BINDIR) url_view wavescript wave-remote # 'make collect': retrieve the installed applications collect: ../conf/collect.sh $(BINDIR) url_view wavescript wave-remote uninstall: - ../uninstall.sh $(BINDIR) url_view wavescript wave-remote + ../uninstall.sh $(DESTDIR)$(BINDIR) url_view wavescript wave-remote # `wavescript' reads commands from a named file and passes them to WAVE. wavescript: wavescript.c - $(CC) -o wavescript -DBINDIR=$(BINDIR) -O wavescript.c + $(CC) $(MFLAGS) -o wavescript -DBINDIR=$(BINDIR) -O wavescript.c # `wave-remote' passes its command-line arguments as commands to WAVE. wave-remote: wave-remote.c - $(CC) -o wave-remote -O wave-remote.c + $(CC) $(MFLAGS) -o wave-remote -O wave-remote.c # `wave-remote-test' looks like WAVE to `wavescript' and `wave-remote', and # can be used to verify their proper operation. Start `wave-remote-test' # before starting `wavescript' or `wave-remote'; the commands these programs # send to WAVE should appear on the standard output of `wave-remote-test. wave-remote-test: wave-remote-test.c - $(CC) -o wave-remote-test -O wave-remote-test.c + $(CC) $(MFLAGS) -o wave-remote-test -O wave-remote-test.c # `make clean': remove intermediate and backup files clean: rm -f wavescript wave-remote wave-remote-test *~ # Create directory for installation if necessary. -$(BINDIR): - mkdir -p $(BINDIR); $(SETDPERMISSIONS) $(BINDIR) +$(DESTDIR)$(BINDIR): + mkdir -p $(DESTDIR)$(BINDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(BINDIR) diff -Naur '--exclude=Makefile' wfdb-10.5.24/xml/Makefile.tpl wfdb-10.6.0/xml/Makefile.tpl --- wfdb-10.5.24/xml/Makefile.tpl 2015-05-28 15:55:17.000000000 -0400 +++ wfdb-10.6.0/xml/Makefile.tpl 2017-03-09 18:13:19.000000000 -0500 @@ -1,4 +1,5 @@ # file: Makefile.tpl G. Moody 22 August 2010 +# Last revised: 8 March 2017 # # This section of the Makefile should not need to be changed. @@ -18,20 +19,21 @@ $(STRIP) $(XFILES) # `make' or `make install': build and install applications -install: all $(BINDIR) +install: all $(DESTDIR)$(BINDIR) $(SETXPERMISSIONS) $(XFILES) - ../install.sh $(BINDIR) $(XFILES) + ../install.sh $(DESTDIR)$(BINDIR) $(XFILES) # 'make collect': retrieve the installed applications collect: ../conf/collect.sh $(BINDIR) $(XFILES) uninstall: - ../uninstall.sh $(BINDIR) $(XFILES) + ../uninstall.sh $(DESTDIR)$(BINDIR) $(XFILES) # Create directories for installation if necessary. -$(BINDIR): - mkdir -p $(BINDIR); $(SETDPERMISSIONS) $(BINDIR) +$(DESTDIR)$(BINDIR): + mkdir -p $(DESTDIR)$(BINDIR) + $(SETDPERMISSIONS) $(DESTDIR)$(BINDIR) # `make clean': remove intermediate and backup files clean: diff -Naur '--exclude=Makefile' wfdb-10.5.24/xml/heaxml.c wfdb-10.6.0/xml/heaxml.c --- wfdb-10.5.24/xml/heaxml.c 2015-05-28 15:55:17.000000000 -0400 +++ wfdb-10.6.0/xml/heaxml.c 2017-12-11 15:55:32.000000000 -0500 @@ -1,5 +1,5 @@ /* file: heaxml.c G. Moody 28 June 2010 - Last revised: 1 July 2010 + Last revised: 11 December 2017 ------------------------------------------------------------------------------- heaxml: Convert a WFDB .hea (header) file to XML format Copyright (C) 2010 George B. Moody @@ -366,7 +366,7 @@ if (s[i].spf > 1) fprintf(ofile,"%d\n", s[i].spf); if (skew = wfdbgetskew(i)) - fprintf(ofile, "%ld\n", skew); + fprintf(ofile, "%d\n", skew); fprintf(ofile, "%d\n", s[i].bsize); fprintf(ofile, "%d\n", s[i].adcres); fprintf(ofile, "%d\n", s[i].adczero); diff -Naur '--exclude=Makefile' wfdb-10.5.24/xml/xmlann.c wfdb-10.6.0/xml/xmlann.c --- wfdb-10.5.24/xml/xmlann.c 2015-05-28 15:55:17.000000000 -0400 +++ wfdb-10.6.0/xml/xmlann.c 2017-12-11 15:55:32.000000000 -0500 @@ -1,5 +1,5 @@ /* file: xmlann.c G. Moody 22 August 2010 - + Last revised: 11 December 2017 ------------------------------------------------------------------------------- xmlann: Convert a WFDB-XML file to a WFDB-compatible annotation file Copyright (C) 2010 George B. Moody @@ -50,7 +50,7 @@ sprintf(data + strlen(data), "/%s", el); if (vflag) { - printf("\n%s", data); + printf("\n%s", (char *) data); for (i = 0; attr[i]; i += 2) printf(" %s='%s'", attr[i], attr[i + 1]); fflush(stdout); diff -Naur '--exclude=Makefile' wfdb-10.5.24/xml/xmlhea.c wfdb-10.6.0/xml/xmlhea.c --- wfdb-10.5.24/xml/xmlhea.c 2015-05-28 15:55:17.000000000 -0400 +++ wfdb-10.6.0/xml/xmlhea.c 2017-12-11 15:55:32.000000000 -0500 @@ -1,5 +1,5 @@ /* file: xmlhea.c G. Moody 20 August 2010 - Last revised: 22 August 2010 + Last revised: 11 December 2017 ------------------------------------------------------------------------------- xmlhea: Convert an XML file to a WFDB-compatible .hea (header) file Copyright (C) 2010 George B. Moody @@ -66,7 +66,7 @@ sprintf(data + strlen(data), "/%s", el); if (vflag) { - printf("\n%s", data); + printf("\n%s", (char *) data); for (i = 0; attr[i]; i += 2) printf(" %s='%s'", attr[i], attr[i + 1]); fflush(stdout); @@ -203,7 +203,7 @@ else if (strcmp("counterfrequency", el) == 0) sscanf(content, "%lf", &cps); else if (strcmp("signals", el) == 0) { - sscanf(content, "%ld", &nsig); + sscanf(content, "%d", &nsig); SUALLOC(si, sizeof(WFDB_Siginfo), nsig); SUALLOC(sa, sizeof(struct asiginfo), nsig); } @@ -224,7 +224,7 @@ segi[nseg].nsamp = length; } else if (strcmp("/wfdbrecord/segment/signals", data) == 0) - sscanf(content, "%ld", &nsig); + sscanf(content, "%d", &nsig); else if (strcmp("/info/age", dp) == 0) { SSTRCPY(age, content); @@ -265,19 +265,19 @@ } else if (strcmp("/start/year", dp) == 0) { - sscanf(content, "%ld", &year); + sscanf(content, "%d", &year); } else if (strcmp("/start/month", dp) == 0) { - sscanf(content, "%ld", &month); + sscanf(content, "%d", &month); } else if (strcmp("/start/day", dp) == 0) { - sscanf(content, "%ld", &day); + sscanf(content, "%d", &day); } else if (strcmp("/start/hour", dp) == 0) { - sscanf(content, "%ld", &hour); + sscanf(content, "%d", &hour); } else if (strcmp("/start/minute", dp) == 0) { - sscanf(content, "%ld", &minute); + sscanf(content, "%d", &minute); } else if (strcmp("/start/second", dp) == 0) { sscanf(content, "%lf", &second);