merge-requests/3/merge
Teuniz 2020-12-07 09:32:41 +01:00
rodzic 55fc871ba6
commit fb9f22458b
6 zmienionych plików z 478 dodań i 350 usunięć

127
README
Wyświetl plik

@ -1,3 +1,4 @@
# DSRemote
Operate your Rigol oscilloscope from your Linux desktop.
========================================================
@ -5,31 +6,35 @@ Operate your Rigol oscilloscope from your Linux desktop.
webpage and info: https://www.teuniz.net/DSRemote/
How to compile:
---------------
Compiling and installing on Ubuntu Linux and derivatives:
---------------------------------------------------------
sudo apt-get update
sudo apt-get install g++ make git qtbase5-dev-tools qtbase5-dev qt5-default
git clone https://gitlab.com/Teuniz/DSRemote.git
cd DSRemote
qmake
make -j4
sudo make install
dsremote
- openSuse Leap 15.1
sudo zypper in patterns-devel-base-devel_basis git-core make libqt5-qtbase-devel libQt5Core-devel libQt5Concurrent-devel libQt5Gui-devel libQt5Widgets-devel libQt5Network-devel libQt5PrintSupport-devel
git clone https://gitlab.com/Teuniz/DSRemote.git
cd DSRemote
qmake-qt5
make
sudo make install
For USB connection setup use the following commands:
----------------------------------------------------
sudo groupadd usbtmc
sudo usermod -a -G usbtmc <username>
reboot
sudo groupadd usbtmc
sudo usermod -a -G usbtmc <username>
reboot
Now you can run the program by typing: dsremote
(USB connection does not work on modern USB host controllers thanks to
a bug in the scopes' firmware that Rigol does not want to fix.)
Read also the file readme_usbtcm_driver.txt
and the file notes.txt.
Supported devices
---------------
@ -46,99 +51,15 @@ Not tested yet:
* serial decoding.
DS1000Z series:
---------------
DSRemote assumes that, on your DS1054Z, all options are installed.
If that is not the case it's possible that the software does not work correctly.
On your scope, go to the menu Utility -> Options -> Installed and make sure you have the following options installed:
* DECODER RS232,I2C,SPI Official
* MEM_DEPTH 24M/12M/6M Official
* TRIGGER Timeout,Runt,Window,Delay,Setup,NthEdge,RS232,I2C,SPI Official
* RECORDER Record/Re-play Official
* BANDWIDTH 100M Official
Note:
This is a private project made available to the public. No pullrequests!
If you believe you found a bug or want to add some feature, open an issue on Gitlab or send me an email.
In case you want to add some code, send me a diff, no pull requests, they will be ignored.
Also, all requests regarding to support other platforms and/or other tools will be ignored.
Again, this a Linux & GCC & Make project. That means no Mac/windows/Clang/CMake etc.
Qt framework:
-------------
In case you want to use Qt5, the recommended way is not to use the Qt5 libraries that comes with your distro.
Instead, download and compile the Qt5 source and use that to compile DSRemote.
Here's a step by step list with instructions:
First, fulfill the requirements for Qt:
http://doc.qt.io/qt-5/linux.html
Debian/Ubuntu: sudo apt-get install build-essential libgl1-mesa-dev libcups2-dev libx11-dev
Fedora: sudo dnf groupinstall "C Development Tools and Libraries"
sudo dnf install mesa-libGL-devel cups-devel libx11-dev
openSUSE: sudo zypper install -t pattern devel_basis
sudo zypper install xorg-x11-devel cups-devel freetype-devel fontconfig-devel libxkbcommon-devel libxkbcommon-x11-devel
#############################################################################################
Compile a static version of the Qt5 libraries excluding all modules that are not needed.
This will not mess with your system libraries. The new compiled libraries will be stored
in a new and separate directory: /usr/local/Qt-5.12.4-static
It will not interfere with other Qt programs.
#############################################################################################
mkdir Qt5-source
cd Qt5-source
wget http://ftp1.nluug.nl/languages/qt/official_releases/qt/5.12/5.12.4/single/qt-everywhere-src-5.12.4.tar.xz
here is a list of download mirrors: https://download.qt.io/static/mirrorlist/
The Qt source package you are going to need is: qt-everywhere-src-5.12.4.tar.xz
tar -xvf qt-everywhere-src-5.12.4.tar.xz
cd qt-everywhere-src-5.12.4
./configure -v -prefix /usr/local/Qt-5.12.4-static -release -opensource -confirm-license -c++std c++11 -static -accessibility -fontconfig -skip qtdeclarative -skip qtconnectivity -skip qtmultimedia -qt-zlib -no-mtdev -no-journald -qt-libpng -qt-libjpeg -system-freetype -qt-harfbuzz -no-openssl -no-libproxy -no-glib -nomake examples -nomake tests -no-compile-examples -cups -no-evdev -no-dbus -no-eglfs -qreal double -no-opengl -skip qtlocation -skip qtsensors -skip qtwayland -skip qtgamepad -skip qtserialbus -skip qt3d -skip qtpurchasing -skip qtquickcontrols -skip qtquickcontrols2 -skip qtspeech -skip qtwebengine
(takes about 2 minutes)
make -j6 (change option -j according to number of available cpu cores e.g -j4 or -j8)
(takes about 11 minutes)
sudo make install
Now go to the directory that contains the DSRemote sourcecode and enter the following commands:
/usr/local/Qt-5.12.4-static/bin/qmake
make -j6 (change option -j according to number of available cpu cores e.g -j4 or -j8)
sudo make install
reboot
Now you can run the program by typing: dsremote
Congratulations!
You have compiled a static version of DSRemote that can be deployed on other systems without the need
to install the Qt libraries.
In order to reduce the size of the executable, run the following commands:
strip -s dsremote
upx dsremote
Note: This is a private project made available to the public. No pullrequests!
If you believe you found a bug or want to add some feature, open an issue on Gitlab or send me an email.
In case you want to add some code, send me a diff, no pull requests, they will be ignored.
Also, all requests regarding to support other platforms and/or other tools will be ignored.
Again, this a Linux & GCC & Make project. That means no Mac/windows/Clang/CMake etc.

138
edflib.c
Wyświetl plik

@ -42,11 +42,11 @@
#include "edflib.h"
#define EDFLIB_VERSION 116
#define EDFLIB_MAXFILES 64
#define EDFLIB_VERSION (118)
#define EDFLIB_MAXFILES (64)
#if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__)
#if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) || defined(__HAIKU__)
#define fopeno fopen
@ -79,15 +79,15 @@
/* max size of annotationtext */
#define EDFLIB_WRITE_MAX_ANNOTATION_LEN 40
#define EDFLIB_WRITE_MAX_ANNOTATION_LEN (40)
/* bytes in datarecord for EDF annotations, must be an integer multiple of three and two */
#define EDFLIB_ANNOTATION_BYTES 114
#define EDFLIB_ANNOTATION_BYTES (114)
/* for writing only */
#define EDFLIB_MAX_ANNOTATION_CHANNELS 64
#define EDFLIB_MAX_ANNOTATION_CHANNELS (64)
#define EDFLIB_ANNOT_MEMBLOCKSZ 1000
#define EDFLIB_ANNOT_MEMBLOCKSZ (1000)
struct edfparamblock{
@ -249,7 +249,7 @@ int edflib_get_handle(int file_number)
}
int edfopen_file_readonly(const char *path, struct edf_hdr_struct *edfhdr, int read_annotations)
int edfopen_file_readonly(const char *path, struct edf_hdr_struct *edfhdr, int read_annotations_mode)
{
int i, j,
channel,
@ -260,14 +260,14 @@ int edfopen_file_readonly(const char *path, struct edf_hdr_struct *edfhdr, int r
struct edfhdrblock *hdr;
if(read_annotations<0)
if(read_annotations_mode<0)
{
edfhdr->filetype = EDFLIB_INVALID_READ_ANNOTS_VALUE;
return -1;
}
if(read_annotations>2)
if(read_annotations_mode>2)
{
edfhdr->filetype = EDFLIB_INVALID_READ_ANNOTS_VALUE;
@ -408,26 +408,25 @@ int edfopen_file_readonly(const char *path, struct edf_hdr_struct *edfhdr, int r
edflib_strlcpy(edfhdr->equipment, hdr->plus_equipment, 81);
edflib_strlcpy(edfhdr->recording_additional, hdr->plus_recording_additional, 81);
if((read_annotations==EDFLIB_READ_ANNOTATIONS)||(read_annotations==EDFLIB_READ_ALL_ANNOTATIONS))
if(edflib_get_annotations(hdr, edfhdr->handle, read_annotations_mode))
{
if(edflib_get_annotations(hdr, edfhdr->handle, read_annotations))
{
edfhdr->filetype = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
edfhdr->filetype = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
fclose(file);
fclose(file);
free(hdr->edfparam);
hdr->edfparam = NULL;
free(hdr);
hdr = NULL;
hdrlist[edfhdr->handle] = NULL;
free(annotationslist[edfhdr->handle]);
annotationslist[edfhdr->handle] = NULL;
free(hdr->edfparam);
hdr->edfparam = NULL;
free(hdr);
hdr = NULL;
hdrlist[edfhdr->handle] = NULL;
free(annotationslist[edfhdr->handle]);
annotationslist[edfhdr->handle] = NULL;
return -1;
}
return -1;
}
edfhdr->starttime_subsecond = hdr->starttime_offset;
edfhdr->annotations_in_file = hdr->annots_in_file;
}
@ -528,13 +527,13 @@ int edfclose_file(int handle)
{
annot2 = write_annotationslist[handle] + k;
p = edflib_fprint_ll_number_nonlocalized(hdr->file_hdl, (hdr->datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1);
p = edflib_fprint_ll_number_nonlocalized(hdr->file_hdl, (hdr->datarecords * hdr->long_data_record_duration + hdr->starttime_offset) / EDFLIB_TIME_DIMENSION, 0, 1);
if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION)
if((hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) || (hdr->starttime_offset))
{
fputc('.', hdr->file_hdl);
p++;
p += edflib_fprint_ll_number_nonlocalized(hdr->file_hdl, (hdr->datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0);
p += edflib_fprint_ll_number_nonlocalized(hdr->file_hdl, (hdr->datarecords * hdr->long_data_record_duration + hdr->starttime_offset) % EDFLIB_TIME_DIMENSION, 7, 0);
}
fputc(20, hdr->file_hdl);
fputc(20, hdr->file_hdl);
@ -586,6 +585,8 @@ int edfclose_file(int handle)
{
annot2 = write_annotationslist[handle] + k;
annot2->onset += hdr->starttime_offset / 1000LL;
p = 0;
if(j==0) // first annotation signal
@ -595,12 +596,12 @@ int edfclose_file(int handle)
break;
}
p += edflib_snprint_ll_number_nonlocalized(str, (datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1, EDFLIB_ANNOTATION_BYTES * 2);
p += edflib_snprint_ll_number_nonlocalized(str, (datarecords * hdr->long_data_record_duration + hdr->starttime_offset) / EDFLIB_TIME_DIMENSION, 0, 1, EDFLIB_ANNOTATION_BYTES * 2);
if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION)
if((hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) || (hdr->starttime_offset))
{
str[p++] = '.';
n = edflib_snprint_ll_number_nonlocalized(str + p, (datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0, (EDFLIB_ANNOTATION_BYTES * 2) - p);
n = edflib_snprint_ll_number_nonlocalized(str + p, (datarecords * hdr->long_data_record_duration + hdr->starttime_offset) % EDFLIB_TIME_DIMENSION, 7, 0, (EDFLIB_ANNOTATION_BYTES * 2) - p);
p += n;
}
str[p++] = 20;
@ -2503,9 +2504,7 @@ static struct edfhdrblock * edflib_check_edf_file(FILE *inputfile, int *edf_erro
return NULL;
}
edfhdr->startdate_year = edflib_atof_nonlocalized(scratchpad2 + 7);
if(edfhdr->startdate_year<1970)
if(edfhdr->startdate_year != edflib_atof_nonlocalized(scratchpad2 + 7))
{
*edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS;
free(edf_hdr);
@ -2866,7 +2865,7 @@ int edflib_version(void)
}
static int edflib_get_annotations(struct edfhdrblock *edfhdr, int hdl, int read_annotations)
static int edflib_get_annotations(struct edfhdrblock *edfhdr, int hdl, int read_annotations_mode)
{
int i, j, k, p, r=0, n,
edfsignals,
@ -3055,7 +3054,7 @@ static int edflib_get_annotations(struct edfhdrblock *edfhdr, int hdl, int read_
}
else
{
if(time_tmp>=EDFLIB_TIME_DIMENSION)
if((time_tmp>=EDFLIB_TIME_DIMENSION) || (time_tmp<0LL))
{
error = 2;
goto END;
@ -3063,6 +3062,11 @@ static int edflib_get_annotations(struct edfhdrblock *edfhdr, int hdl, int read_
else
{
edfhdr->starttime_offset = time_tmp;
if(read_annotations_mode==EDFLIB_DO_NOT_READ_ANNOTATIONS)
{
error = 0;
goto END_OUT;
}
}
}
elapsedtime = time_tmp;
@ -3158,9 +3162,11 @@ static int edflib_get_annotations(struct edfhdrblock *edfhdr, int hdl, int read_
new_annotation->onset = edflib_get_long_time(time_in_txt);
new_annotation->onset -= edfhdr->starttime_offset;
edfhdr->annots_in_file++;
if(read_annotations==EDFLIB_READ_ANNOTATIONS)
if(read_annotations_mode==EDFLIB_READ_ANNOTATIONS)
{
if(!(strncmp(new_annotation->annotation, "Recording ends", 14)))
{
@ -3238,6 +3244,8 @@ static int edflib_get_annotations(struct edfhdrblock *edfhdr, int hdl, int read_
}
}
END_OUT:
free(cnv_buf);
free(scratchpad);
free(time_in_txt);
@ -3937,6 +3945,44 @@ int edf_set_micro_datarecord_duration(int handle, int duration)
}
int edf_set_subsecond_starttime(int handle, int subsecond)
{
if(handle<0)
{
return -1;
}
if(handle>=EDFLIB_MAXFILES)
{
return -1;
}
if(hdrlist[handle]==NULL)
{
return -1;
}
if(!(hdrlist[handle]->writemode))
{
return -1;
}
if(hdrlist[handle]->datarecords)
{
return -1;
}
if((subsecond < 0) || (subsecond > 9999999))
{
return -1;
}
hdrlist[handle]->starttime_offset = (long long)subsecond;
return 0;
}
int edfwrite_digital_short_samples(int handle, short *buf)
{
int i,
@ -6384,7 +6430,7 @@ int edf_set_startdatetime(int handle, int startdate_year, int startdate_month, i
return -1;
}
if((startdate_year<1970) || (startdate_year>3000) ||
if((startdate_year<1985) || (startdate_year>2084) ||
(startdate_month<1) || (startdate_month>12) ||
(startdate_day<1) || (startdate_day>31) ||
(starttime_hour<0) || (starttime_hour>23) ||
@ -6465,7 +6511,7 @@ int edfwrite_annotation_utf8(int handle, long long onset, long long duration, co
break;
}
if(list_annot->annotation[i] < 32)
if(((unsigned char *)(list_annot->annotation))[i] < 32)
{
list_annot->annotation[i] = '.';
}
@ -6688,7 +6734,7 @@ static int edflib_fprint_int_number_nonlocalized(FILE *file, int q, int minimum,
j++;
q = -q;
base = -base;
}
else
{
@ -6760,7 +6806,7 @@ static int edflib_fprint_ll_number_nonlocalized(FILE *file, long long q, int min
j++;
q = -q;
base = -base;
}
else
{
@ -6900,7 +6946,7 @@ static int edflib_snprint_ll_number_nonlocalized(char *dest, long long q, int mi
{
dest[j++] = '-';
q = -q;
base = -base;
}
else
{
@ -6981,7 +7027,7 @@ static int edflib_snprint_number_nonlocalized(char *dest, double val, int sz)
if(q < 0)
{
q = -q;
base = -base;
}
}
@ -7035,7 +7081,7 @@ static int edflib_snprint_number_nonlocalized(char *dest, double val, int sz)
if(q < 0)
{
q = -q;
base = -base;
}
if(!q)
@ -7263,11 +7309,11 @@ static int edflib_write_tal(struct edfhdrblock *hdr, FILE *file)
char str[EDFLIB_ANNOTATION_BYTES * (EDFLIB_MAX_ANNOTATION_CHANNELS + 1)];
p = edflib_snprint_ll_number_nonlocalized(str, (hdr->datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1, EDFLIB_ANNOTATION_BYTES * (EDFLIB_MAX_ANNOTATION_CHANNELS + 1));
if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION)
p = edflib_snprint_ll_number_nonlocalized(str, (hdr->datarecords * hdr->long_data_record_duration + hdr->starttime_offset) / EDFLIB_TIME_DIMENSION, 0, 1, EDFLIB_ANNOTATION_BYTES * (EDFLIB_MAX_ANNOTATION_CHANNELS + 1));
if((hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) || (hdr->starttime_offset))
{
str[p++] = '.';
p += edflib_snprint_ll_number_nonlocalized(str + p, (hdr->datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0, (EDFLIB_ANNOTATION_BYTES * (EDFLIB_MAX_ANNOTATION_CHANNELS + 1)) - p);
p += edflib_snprint_ll_number_nonlocalized(str + p, (hdr->datarecords * hdr->long_data_record_duration + hdr->starttime_offset) % EDFLIB_TIME_DIMENSION, 7, 0, (EDFLIB_ANNOTATION_BYTES * (EDFLIB_MAX_ANNOTATION_CHANNELS + 1)) - p);
}
str[p++] = 20;
str[p++] = 20;

Wyświetl plik

@ -48,51 +48,51 @@
#define EDFLIB_TIME_DIMENSION (10000000LL)
#define EDFLIB_MAXSIGNALS 640
#define EDFLIB_MAX_ANNOTATION_LEN 512
#define EDFLIB_TIME_DIMENSION (10000000LL)
#define EDFLIB_MAXSIGNALS (640)
#define EDFLIB_MAX_ANNOTATION_LEN (512)
#define EDFSEEK_SET 0
#define EDFSEEK_CUR 1
#define EDFSEEK_END 2
#define EDFSEEK_SET (0)
#define EDFSEEK_CUR (1)
#define EDFSEEK_END (2)
/* the following defines are used in the member "filetype" of the edf_hdr_struct */
/* and as return value for the function edfopen_file_readonly() */
#define EDFLIB_FILETYPE_EDF 0
#define EDFLIB_FILETYPE_EDFPLUS 1
#define EDFLIB_FILETYPE_BDF 2
#define EDFLIB_FILETYPE_BDFPLUS 3
#define EDFLIB_MALLOC_ERROR -1
#define EDFLIB_NO_SUCH_FILE_OR_DIRECTORY -2
#define EDFLIB_FILETYPE_EDF (0)
#define EDFLIB_FILETYPE_EDFPLUS (1)
#define EDFLIB_FILETYPE_BDF (2)
#define EDFLIB_FILETYPE_BDFPLUS (3)
#define EDFLIB_MALLOC_ERROR (-1)
#define EDFLIB_NO_SUCH_FILE_OR_DIRECTORY (-2)
/* when this error occurs, try to open the file with EDFbrowser,
it will give you full details about the cause of the error. */
#define EDFLIB_FILE_CONTAINS_FORMAT_ERRORS -3
#define EDFLIB_MAXFILES_REACHED -4
#define EDFLIB_FILE_READ_ERROR -5
#define EDFLIB_FILE_ALREADY_OPENED -6
#define EDFLIB_FILETYPE_ERROR -7
#define EDFLIB_FILE_WRITE_ERROR -8
#define EDFLIB_NUMBER_OF_SIGNALS_INVALID -9
#define EDFLIB_FILE_IS_DISCONTINUOUS -10
#define EDFLIB_INVALID_READ_ANNOTS_VALUE -11
#define EDFLIB_MAXFILES_REACHED (-4)
#define EDFLIB_FILE_READ_ERROR (-5)
#define EDFLIB_FILE_ALREADY_OPENED (-6)
#define EDFLIB_FILETYPE_ERROR (-7)
#define EDFLIB_FILE_WRITE_ERROR (-8)
#define EDFLIB_NUMBER_OF_SIGNALS_INVALID (-9)
#define EDFLIB_FILE_IS_DISCONTINUOUS (-10)
#define EDFLIB_INVALID_READ_ANNOTS_VALUE (-11)
/* values for annotations */
#define EDFLIB_DO_NOT_READ_ANNOTATIONS 0
#define EDFLIB_READ_ANNOTATIONS 1
#define EDFLIB_READ_ALL_ANNOTATIONS 2
#define EDFLIB_DO_NOT_READ_ANNOTATIONS (0)
#define EDFLIB_READ_ANNOTATIONS (1)
#define EDFLIB_READ_ALL_ANNOTATIONS (2)
/* the following defines are possible errors returned by the first sample write action */
#define EDFLIB_NO_SIGNALS -20
#define EDFLIB_TOO_MANY_SIGNALS -21
#define EDFLIB_NO_SAMPLES_IN_RECORD -22
#define EDFLIB_DIGMIN_IS_DIGMAX -23
#define EDFLIB_DIGMAX_LOWER_THAN_DIGMIN -24
#define EDFLIB_PHYSMIN_IS_PHYSMAX -25
#define EDFLIB_DATARECORD_SIZE_TOO_BIG -26
#define EDFLIB_NO_SIGNALS (-20)
#define EDFLIB_TOO_MANY_SIGNALS (-21)
#define EDFLIB_NO_SAMPLES_IN_RECORD (-22)
#define EDFLIB_DIGMIN_IS_DIGMAX (-23)
#define EDFLIB_DIGMAX_LOWER_THAN_DIGMIN (-24)
#define EDFLIB_PHYSMIN_IS_PHYSMAX (-25)
#define EDFLIB_DATARECORD_SIZE_TOO_BIG (-26)
@ -133,8 +133,10 @@ extern "C" {
* This is not a concern anymore so the maximum datarecord size now is limited to 10MByte for EDF(+) and 15MByte for BDF(+). This helps to accommodate for higher samplingrates
* used by modern Analog to Digital Converters.
*
* EDF header character encoding: The EDF specification says that only ASCII characters are allowed.
* EDFlib will automatically convert characters with accents, umlauts, tilde, etc. to their "normal" equivalent without the accent/umlaut/tilde/etc.
* EDF header character encoding: The EDF specification says that only (printable) ASCII characters are allowed.
* When writing the header info, EDFlib will assume you are using Latin1 encoding and it will automatically convert
* characters with accents, umlauts, tilde, etc. to their "normal" equivalent without the accent/umlaut/tilde/etc.
* in order to create a valid EDF file.
*
* The description/name of an EDF+ annotation on the other hand, is encoded in UTF-8.
*
@ -156,7 +158,7 @@ struct edf_param_struct{ /* this structure contains all the relevant EDF
struct edf_annotation_struct{ /* this structure is used for annotations */
long long onset; /* onset time of the event, expressed in units of 100 nanoSeconds and relative to the starttime in the header */
long long onset; /* onset time of the event, expressed in units of 100 nanoSeconds and relative to the start of the file */
char duration[16]; /* duration time, this is a null-terminated ASCII text-string */
char annotation[EDFLIB_MAX_ANNOTATION_LEN + 1]; /* description of the event in UTF-8, this is a null terminated string */
};
@ -419,7 +421,7 @@ int edf_set_physical_dimension(int handle, int edfsignal, const char *phys_dim);
/* Sets the physical dimension (unit) of signal edfsignal. ("uV", "BPM", "mA", "Degr.", etc.) */
/* phys_dim is a pointer to a NULL-terminated ASCII-string containing the physical dimension of the signal edfsignal */
/* Returns 0 on success, otherwise -1 */
/* This function is recommanded for every signal when you want to write a file */
/* This function is recommended for every signal when you want to write a file */
/* and can be called only after opening a file in writemode and before the first sample write action */
@ -427,7 +429,7 @@ int edf_set_startdatetime(int handle, int startdate_year, int startdate_month, i
int starttime_hour, int starttime_minute, int starttime_second);
/* Sets the startdate and starttime. */
/* year: 1970 - 3000, month: 1 - 12, day: 1 - 31 */
/* year: 1985 - 2084, month: 1 - 12, day: 1 - 31 */
/* hour: 0 - 23, minute: 0 - 59, second: 0 - 59 */
/* If not called, the library will use the system date and time at runtime */
/* Returns 0 on success, otherwise -1 */
@ -609,7 +611,7 @@ int edf_blockwrite_digital_samples(int handle, int *buf);
int edfwrite_annotation_utf8(int handle, long long onset, long long duration, const char *description);
/* writes an annotation/event to the file */
/* onset is relative to the starttime and startdate of the file */
/* onset is relative to the start of the file */
/* onset and duration are in units of 100 microSeconds! resolution is 0.0001 second! */
/* for example: 34.071 seconds must be written as 340710 */
/* if duration is unknown or not applicable: set a negative number (-1) */
@ -621,7 +623,7 @@ int edfwrite_annotation_utf8(int handle, long long onset, long long duration, co
int edfwrite_annotation_latin1(int handle, long long onset, long long duration, const char *description);
/* writes an annotation/event to the file */
/* onset is relative to the starttime and startdate of the file */
/* onset is relative to the start of the file */
/* onset and duration are in units of 100 microSeconds! resolution is 0.0001 second! */
/* for example: 34.071 seconds must be written as 340710 */
/* if duration is unknown or not applicable: set a negative number (-1) */
@ -676,6 +678,16 @@ int edf_set_number_of_annotation_signals(int handle, int annot_signals);
/* Returns 0 on success, otherwise -1 */
int edf_set_subsecond_starttime(int handle, int subsecond);
/* Sets the subsecond starttime expressed in units of 100 nanoSeconds */
/* Valid range is 0 to 9999999 inclusive. Default is 0 */
/* This function is optional and can be called only after opening a file in writemode */
/* and before the first sample write action */
/* Returns 0 on success, otherwise -1 */
/* It is strongly recommended to use a maximum resolution of no more than 100 micro-Seconds. */
/* e.g. use 1234000 to set a starttime offset of 0.1234 seconds (instead of 1234567) */
/* in other words, leave the last 3 digits at zero */
#ifdef __cplusplus
} /* extern "C" */
#endif

Wyświetl plik

@ -35,7 +35,7 @@
#define PROGRAM_NAME "DSRemote"
#define PROGRAM_VERSION "0.37_2006141810"
#define PROGRAM_VERSION "0.37_2012070931"
#define MAX_PATHLEN 1024

453
utils.c
Wyświetl plik

@ -11,8 +11,7 @@
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -243,6 +242,42 @@ void remove_leading_spaces(char *str)
}
/* removes both leading and trailing spaces */
void trim_spaces(char *str)
{
int i, diff, len;
len = strlen(str);
for(i=0; i<len; i++)
{
if(str[i] != ' ')
{
break;
}
}
if(i)
{
diff = i;
for(; i<=len; i++)
{
str[i - diff] = str[i];
}
}
len = strlen(str);
for(i=(len-1); i>=0; i--)
{
if(str[i]!=' ') break;
}
str[i+1] = 0;
}
void remove_trailing_zeros(char *str)
{
@ -717,7 +752,7 @@ int fprint_int_number_nonlocalized(FILE *file, int q, int minimum, int sign)
j++;
q = -q;
base = -base;
}
else
{
@ -789,7 +824,7 @@ int fprint_ll_number_nonlocalized(FILE *file, long long q, int minimum, int sign
j++;
q = -q;
base = -base;
}
else
{
@ -839,64 +874,64 @@ int fprint_ll_number_nonlocalized(FILE *file, long long q, int minimum, int sign
/* if sign is zero, only negative numbers will have the sign '-' character */
/* if sign is one, the sign '+' or '-' character will always be printed */
/* returns the amount of characters printed */
int sprint_int_number_nonlocalized(char *str, int q, int minimum, int sign)
{
int flag=0, z, i, j=0, base = 1000000000;
if(minimum < 0)
{
minimum = 0;
}
if(minimum > 9)
{
flag = 1;
}
if(q < 0)
{
str[j++] = '-';
q = -q;
}
else
{
if(sign)
{
str[j++] = '+';
}
}
for(i=10; i; i--)
{
if(minimum == i)
{
flag = 1;
}
z = q / base;
q %= base;
if(z || flag)
{
str[j++] = '0' + z;
flag = 1;
}
base /= 10;
}
if(!flag)
{
str[j++] = '0';
}
str[j] = 0;
return j;
}
// int sprint_int_number_nonlocalized(char *str, int q, int minimum, int sign)
// {
// int flag=0, z, i, j=0, base = 1000000000;
//
// if(minimum < 0)
// {
// minimum = 0;
// }
//
// if(minimum > 9)
// {
// flag = 1;
// }
//
// if(q < 0)
// {
// str[j++] = '-';
//
// q = -q;
// }
// else
// {
// if(sign)
// {
// str[j++] = '+';
// }
// }
//
// for(i=10; i; i--)
// {
// if(minimum == i)
// {
// flag = 1;
// }
//
// z = q / base;
//
// q %= base;
//
// if(z || flag)
// {
// str[j++] = '0' + z;
//
// flag = 1;
// }
//
// base /= 10;
// }
//
// if(!flag)
// {
// str[j++] = '0';
// }
//
// str[j] = 0;
//
// return j;
// }
/* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */
@ -923,7 +958,7 @@ int sprint_ll_number_nonlocalized(char *str, long long q, int minimum, int sign)
{
str[j++] = '-';
q = -q;
base = -base;
}
else
{
@ -965,98 +1000,98 @@ int sprint_ll_number_nonlocalized(char *str, long long q, int minimum, int sign)
}
int sprint_number_nonlocalized(char *str, double nr)
{
int flag=0, z, i, j=0, q, base = 1000000000;
double var;
q = (int)nr;
var = nr - q;
if(nr < 0.0)
{
str[j++] = '-';
if(q < 0)
{
q = -q;
}
}
for(i=10; i; i--)
{
z = q / base;
q %= base;
if(z || flag)
{
str[j++] = '0' + z;
flag = 1;
}
base /= 10;
}
if(!flag)
{
str[j++] = '0';
}
base = 100000000;
var *= (base * 10);
q = (int)var;
if(q < 0)
{
q = -q;
}
if(!q)
{
str[j] = 0;
return j;
}
str[j++] = '.';
for(i=9; i; i--)
{
z = q / base;
q %= base;
str[j++] = '0' + z;
base /= 10;
}
str[j] = 0;
j--;
for(; j>0; j--)
{
if(str[j] == '0')
{
str[j] = 0;
}
else
{
j++;
break;
}
}
return j;
}
// int sprint_number_nonlocalized(char *str, double nr)
// {
// int flag=0, z, i, j=0, q, base = 1000000000;
//
// double var;
//
// q = (int)nr;
//
// var = nr - q;
//
// if(nr < 0.0)
// {
// str[j++] = '-';
//
// if(q < 0)
// {
// q = -q;
// }
// }
//
// for(i=10; i; i--)
// {
// z = q / base;
//
// q %= base;
//
// if(z || flag)
// {
// str[j++] = '0' + z;
//
// flag = 1;
// }
//
// base /= 10;
// }
//
// if(!flag)
// {
// str[j++] = '0';
// }
//
// base = 100000000;
//
// var *= (base * 10);
//
// q = (int)var;
//
// if(q < 0)
// {
// q = -q;
// }
//
// if(!q)
// {
// str[j] = 0;
//
// return j;
// }
//
// str[j++] = '.';
//
// for(i=9; i; i--)
// {
// z = q / base;
//
// q %= base;
//
// str[j++] = '0' + z;
//
// base /= 10;
// }
//
// str[j] = 0;
//
// j--;
//
// for(; j>0; j--)
// {
// if(str[j] == '0')
// {
// str[j] = 0;
// }
// else
// {
// j++;
//
// break;
// }
// }
//
// return j;
// }
double atof_nonlocalized(const char *str)
@ -2142,7 +2177,7 @@ char * strtok_r_e(char *str, const char *delim, char **saveptr)
* plus the length of src. While this may seem somewhat confusing,
* it was done to make truncation detection simple."
*/
#if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) || defined(__FreeBSD__)
#if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) || defined(__FreeBSD__) || defined(__HAIKU__)
/* nothing here */
#else
int strlcpy(char *dst, const char *src, int sz)
@ -2172,7 +2207,7 @@ int strlcat(char *dst, const char *src, int sz)
sz -= dstlen + 1;
if(!sz) return dstlen;
if(sz < 1) return dstlen;
srclen = strlen(src);
@ -2187,7 +2222,109 @@ int strlcat(char *dst, const char *src, int sz)
#endif
void str_insert_substr(char *str, int pos, int len, const char *substr, int subpos, int sublen)
{
int i, slen;
if((pos >= len) || (pos < 0) || (len < 1) || (subpos >= sublen) || (subpos < 0) || (sublen < 1)) return;
slen = strlen(str);
if(pos > slen) return;
if(sublen > (signed)strlen(substr)) sublen = strlen(substr);
for(i=((slen+sublen)-1); i>=(pos + sublen); i--)
{
if(i < len) str[i] = str[i-sublen];
}
for(i=0; i<sublen; i++)
{
if(((pos + i) >= len) || ((subpos + i) >= sublen)) break;
str[pos + i] = substr[subpos + i];
}
if((slen + sublen) < len)
{
str[slen + sublen] = 0;
}
else
{
str[len-1] = 0;
}
}
int str_replace_substr(char *str, int len, int n, const char *dest_substr, const char *src_substr)
{
int i, pos, slen, destlen, srclen, occurrence=0, cnt=0, lendiff;
slen = strlen(str);
destlen = strlen(dest_substr);
srclen = strlen(src_substr);
lendiff = srclen - destlen;
for(pos=0; pos<slen; pos++)
{
if(!strncmp(str + pos, dest_substr, destlen))
{
if((n == occurrence) || (n == -1))
{
if(lendiff > 0)
{
for(i=((slen+lendiff)-1); i>=(pos + lendiff); i--)
{
if(i < len) str[i] = str[i-lendiff];
}
}
else if(lendiff < 0)
{
for(i=(pos + srclen); i<(slen+lendiff); i++)
{
if(i < len) str[i] = str[i-lendiff];
}
}
for(i=0; i<srclen; i++)
{
if((pos + i) >= len) break;
str[pos + i] = src_substr[i];
}
if((slen + lendiff) < len)
{
slen += lendiff;
str[slen] = 0;
pos += lendiff;
}
else
{
str[len-1] = 0;
slen = len;
break;
}
cnt++;
if(n != -1) break;
}
occurrence++;
}
}
return cnt;
}

22
utils.h
Wyświetl plik

@ -11,8 +11,7 @@
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -45,8 +44,21 @@ extern "C" {
void remove_trailing_spaces(char *);
void remove_leading_spaces(char *);
void trim_spaces(char *);
void remove_trailing_zeros(char *);
void convert_trailing_zeros_to_spaces(char *);
/* Inserts a copy of substr into str. The substring is the portion of substr that begins at */
/* the character position subpos and spans sublen characters (or until the end of substr */
/* if substr is too short). */
void str_insert_substr(char *str, int pos, int len, const char *substr, int subpos, int sublen);
/* Replaces the nth occurence of dest_substr in str with src_substr. */
/* If n = -1, all occurrences will be replaced. */
/* len is the buffer length, not the string length! */
/* Returns the number of substrings replaced. */
int str_replace_substr(char *str, int len, int n, const char *dest_substr, const char *src_substr);
void remove_extension_from_filename(char *); /* removes extension including the dot */
int get_filename_from_path(char *dest, const char *src, int size); /* size is size of destination, returns length of filename */
int get_directory_from_path(char *dest, const char *src, int size); /* size is size of destination, returns length of directory */
@ -56,7 +68,7 @@ void utf8_to_latin1(char *);
int antoi(const char *, int);
int atoi_nonlocalized(const char *);
double atof_nonlocalized(const char *);
int sprint_number_nonlocalized(char *, double);
//int sprint_number_nonlocalized(char *, double);
long long atoll_x(const char *, int);
void strntolower(char *, int);
@ -67,7 +79,7 @@ char * strtok_r_e(char *, const char *, char **);
/* if 4th argument is zero, only negative numbers will have the sign '-' character */
/* if 4th argument is one, the sign '+' or '-' character will always be printed */
/* returns the amount of characters printed */
int sprint_int_number_nonlocalized(char *, int, int, int);
//int sprint_int_number_nonlocalized(char *, int, int, int);
int sprint_ll_number_nonlocalized(char *, long long, int, int);
int fprint_int_number_nonlocalized(FILE *, int, int, int);
int fprint_ll_number_nonlocalized(FILE *, long long, int, int);
@ -108,7 +120,7 @@ int base64_dec(const void *, void *, int);
* plus the length of src. While this may seem somewhat confusing,
* it was done to make truncation detection simple."
*/
#if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) || defined(__FreeBSD__)
#if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) || defined(__FreeBSD__) || defined(__HAIKU__)
/* nothing here */
#else
int strlcpy(char *, const char *, int);