diff --git a/.gitignore b/.gitignore
index e83a4ee..0be9ac5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,6 @@
# Shared objects
*.so
*.so.*
+
+# qt-creator
+Snippets.*
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9bac400..f5f859e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,11 +1,11 @@
cmake_minimum_required(VERSION 3.9)
set(PROJ usefull_macros)
set(MINOR_VERSION "1")
-set(MID_VERSION "0")
+set(MID_VERSION "1")
set(MAJOR_VERSION "0")
-set(PROJ_VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}")
+set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}")
-project(${PROJ} VERSION ${PROJ_VERSION} LANGUAGES C)
+project(${PROJ} VERSION ${VERSION} LANGUAGES C)
# default flags
set(CMAKE_C_FLAGS "${CFLAGS} -O2")
@@ -95,7 +95,7 @@ include_directories(${${PROJ}_INCLUDE_DIRS})
link_directories(${${PROJ}_LIBRARY_DIRS})
# -D
add_definitions(-DLOCALEDIR=\"${LOCALEDIR}\"
- -DPACKAGE_VERSION=\"${PROJ_VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
+ -DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
-DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\"
-DMAJOR_VERSION=\"${MAJOR_VESION}\")
@@ -105,7 +105,7 @@ target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES})
set(PCFILE "${CMAKE_BINARY_DIR}/${PROJ}.pc")
configure_file("${PROJ}.pc.in" ${PCFILE} @ONLY)
-set_target_properties(${PROJ} PROPERTIES VERSION ${PROJ_VERSION})
+set_target_properties(${PROJ} PROPERTIES VERSION ${VERSION})
set_target_properties(${PROJ} PROPERTIES PUBLIC_HEADER ${LIBHEADER})
# Installation of the program
diff --git a/Changelog b/Changelog
new file mode 100644
index 0000000..8b3dfa6
--- /dev/null
+++ b/Changelog
@@ -0,0 +1,7 @@
+Wed Dec 23 17:22:39 MSK 2020
+
+VERSION 0.1.1:
+add tty_timeout()
+fix read_tty() for disconnect
+add logging
+add sl_libversion()
diff --git a/Snippets.config b/Snippets.config
deleted file mode 100644
index e3e2368..0000000
--- a/Snippets.config
+++ /dev/null
@@ -1,3 +0,0 @@
-// Add predefined macros for your project here. For example:
-// #define THE_ANSWER 42
-#define EBUG 1
diff --git a/Snippets.creator b/Snippets.creator
deleted file mode 100644
index e94cbbd..0000000
--- a/Snippets.creator
+++ /dev/null
@@ -1 +0,0 @@
-[General]
diff --git a/Snippets.creator.user b/Snippets.creator.user
deleted file mode 100644
index d9b768e..0000000
--- a/Snippets.creator.user
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
- EnvironmentId
- {cf63021e-ef53-49b0-b03b-2f2570cdf3b6}
-
-
- ProjectExplorer.Project.ActiveTarget
- 0
-
-
- ProjectExplorer.Project.EditorSettings
-
- true
- false
- true
-
- Cpp
-
- CppGlobal
-
-
-
- QmlJS
-
- QmlJSGlobal
-
-
- 2
- KOI8-R
- false
- 4
- false
- 80
- true
- true
- 1
- true
- false
- 1
- true
- true
- 0
- 8
- true
- 2
- true
- false
- true
- false
-
-
-
- ProjectExplorer.Project.PluginSettings
-
-
- true
-
-
-
- ProjectExplorer.Project.Target.0
-
- Desktop
- Desktop
- {91347f2c-5221-46a7-80b1-0a054ca02f79}
- 0
- 0
- 0
-
- /home/eddy/Docs/SAO/C_diff/snippets_library
-
-
-
- all
-
- false
-
-
- false
- true
- Сборка
-
- GenericProjectManager.GenericMakeStep
-
- 1
- Сборка
-
- ProjectExplorer.BuildSteps.Build
-
-
-
-
- clean
-
- false
-
-
- false
- true
- Сборка
-
- GenericProjectManager.GenericMakeStep
-
- 1
- Очистка
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- По умолчанию
- По умолчанию
- GenericProjectManager.GenericBuildConfiguration
-
- 1
-
-
- 0
- Установка
-
- ProjectExplorer.BuildSteps.Deploy
-
- 1
- Конфигурация установки
-
- ProjectExplorer.DefaultDeployConfiguration
-
- 1
-
-
- false
- false
- 1000
-
- true
- 2
-
-
- Особая программа
-
- ProjectExplorer.CustomExecutableRunConfiguration
-
- 3768
- false
- true
- false
- false
- true
-
-
-
- 1
-
-
-
- ProjectExplorer.Project.TargetCount
- 1
-
-
- ProjectExplorer.Project.Updater.FileVersion
- 20
-
-
- Version
- 20
-
-
diff --git a/Snippets.files b/Snippets.files
deleted file mode 100644
index 1595196..0000000
--- a/Snippets.files
+++ /dev/null
@@ -1,14 +0,0 @@
-CMakeLists.txt
-daemon.c
-examples/CMakeLists.txt
-examples/cmdlnopts.c
-examples/cmdlnopts.h
-examples/fifo.c
-examples/helloworld.c
-examples/options.c
-fifo_lifo.c
-parseargs.c
-term.c
-term.h
-usefull_macros.c
-usefull_macros.h
diff --git a/Snippets.includes b/Snippets.includes
deleted file mode 100644
index 63f6562..0000000
--- a/Snippets.includes
+++ /dev/null
@@ -1,2 +0,0 @@
-.
-examples
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..f11464f
--- /dev/null
+++ b/TODO
@@ -0,0 +1 @@
+Add prefixes sl_ to every function for solving further problems
diff --git a/daemon.c b/daemon.c
index 57b5139..c287ada 100644
--- a/daemon.c
+++ b/daemon.c
@@ -92,13 +92,13 @@ void check4running(char *selfname, char *pidfilename){
if(selfname){ // block self
fself = fopen(selfname, "r"); // open self binary to lock
if(!fself){
- WARN("fopen");
+ WARN("fopen()");
goto selfpid;
}
memset(&fl, 0, sizeof(struct flock));
fl.l_type = F_WRLCK;
if(fcntl(fileno(fself), F_GETLK, &fl) == -1){ // check locking
- WARN("fcntl");
+ WARN("fcntl()");
goto selfpid;
}
if(fl.l_type != F_UNLCK){ // file is locking - exit
@@ -106,7 +106,7 @@ void check4running(char *selfname, char *pidfilename){
}
fl.l_type = F_RDLCK;
if(fcntl(fileno(fself), F_SETLKW, &fl) == -1){
- WARN("fcntl");
+ WARN("fcntl()");
}
}
selfpid:
@@ -115,7 +115,7 @@ void check4running(char *selfname, char *pidfilename){
ERR(PROC_BASE);
}
if(!(name = readPSname(self))){ // error reading self name
- ERR("Can't read self name");
+ ERR(_("Can't read self name"));
}
myname = strdup(name);
if(pidfilename && stat(pidfilename, &s_buf) == 0){ // pidfile exists
diff --git a/examples/cmdlnopts.c b/examples/cmdlnopts.c
index e4db8cc..af414dc 100644
--- a/examples/cmdlnopts.c
+++ b/examples/cmdlnopts.c
@@ -51,6 +51,7 @@ static glob_pars const Gdefault = {
static myoption cmdlnopts[] = {
// common options
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
+// {"dup", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
{"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), _("serial device name")},
{"speed", NEED_ARG, NULL, 's', arg_int, APTR(&G.speed), _("serial device speed (default: 9600)")},
{"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), _("file to save logs")},
diff --git a/examples/options.c b/examples/options.c
index 35cf8c5..4ccc1d6 100644
--- a/examples/options.c
+++ b/examples/options.c
@@ -59,11 +59,11 @@ void signals(int sig){
signal(sig, SIG_IGN);
DBG("Get signal %d, quit.\n", sig);
}
- putlog("Exit with status %d", sig);
- if(GP->pidfile) // remove unnesessary PID file
+ LOGERR("Exit with status %d", sig);
+ if(GP && GP->pidfile) // remove unnesessary PID file
unlink(GP->pidfile);
restore_console();
- close_tty(&dev);
+ if(dev) close_tty(&dev);
exit(sig);
}
@@ -81,38 +81,42 @@ int main(int argc, char *argv[]){
printf("%s\n", GP->rest_pars[i]);
}
check4running(self, GP->pidfile);
+ red("%s started, snippets library version is %s\n", self, sl_libversion());
free(self);
+ setup_con();
signal(SIGTERM, signals); // kill (-15) - quit
signal(SIGHUP, SIG_IGN); // hup - ignore
signal(SIGINT, signals); // ctrl+C - quit
signal(SIGQUIT, signals); // ctrl+\ - quit
signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
- if(GP->logfile) openlogfile(GP->logfile);
- setup_con();
- putlog(("Start application..."));
+ if(GP->logfile) OPENLOG(GP->logfile, LOGLEVEL_ANY, 1);
+ LOGMSG("Start application...");
if(GP->rest_pars_num){
for(int i = 0; i < GP->rest_pars_num; ++i)
printf("Extra argument: %s\n", GP->rest_pars[i]);
}
if(GP->device){
- putlog("Try to open serial %s", GP->device);
- dev = new_tty(GP->device, GP->speed, 256);
+ LOGDBG("Try to open serial %s", GP->device);
+ dev = new_tty(GP->device, GP->speed, 4096);
if(dev) dev = tty_open(dev, GP->exclusive);
if(!dev){
- putlog("Can't open %s with speed %d. Exit.", GP->device, GP->speed);
+ LOGERR("Can't open %s with speed %d. Exit.", GP->device, GP->speed);
signals(0);
}
}
// main stuff goes here
long seed = throw_random_seed();
- green("Now I will sleep for 10 seconds. Do whatever you want. Random seed: %ld\n", seed);
+ green("Now I will sleep for 10 seconds after your last input.\n Do whatever you want. Random seed: %ld\n", seed);
+ LOGWARN("warning message example");
+ LOGWARNADD("with next string without timestamp");
double t0 = dtime();
char b[2] = {0};
while(dtime() - t0 < 10.){ // read data from port and print in into terminal
if(dev){
if(read_tty(dev)){
printf("Got %zd bytes from port: %s\n", dev->buflen, dev->buf);
+ LOGMSG("Got from serial: %s", dev->buf);
t0 = dtime();
}
int r = read_console();
@@ -120,10 +124,12 @@ int main(int argc, char *argv[]){
t0 = dtime();
b[0] = (char) r;
printf("send to tty: %d (%c)\n", r, b[0]);
+ LOGMSG("send to tty: %d (%c)\n", r, b[0]);
write_tty(dev->comfd, b, 1);
}
}
// clean everything
signals(0);
+ // never reached
return 0;
}
diff --git a/locale/ru/LC_MESSAGES/usefull_macros.mo b/locale/ru/LC_MESSAGES/usefull_macros.mo
index 2ad2e5d..9d9c048 100644
Binary files a/locale/ru/LC_MESSAGES/usefull_macros.mo and b/locale/ru/LC_MESSAGES/usefull_macros.mo differ
diff --git a/locale/ru/messages.po b/locale/ru/messages.po
index 7e0efd7..6d0a30d 100644
--- a/locale/ru/messages.po
+++ b/locale/ru/messages.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-12-09 01:49+0300\n"
+"POT-Creation-Date: 2020-12-24 12:22+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -18,138 +18,162 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
#. / \n (pid=%d), .\n
-#: /Big/Data/C_sources/snippets_library/daemon.c:70
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:70
#, c-format
msgid ""
"\n"
"Found running process (pid=%d), exit.\n"
msgstr ""
+#. error reading self name
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:118
+msgid "Can't read self name"
+msgstr ""
+
#. / PID
-#: /Big/Data/C_sources/snippets_library/daemon.c:143
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:143
msgid "Can't open PID file"
msgstr ""
#. amount of pcount and/or scount wrong
#. /
-#: /Big/Data/C_sources/snippets_library/parseargs.c:54
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:54
msgid "Wrong helpstring!"
msgstr ""
#. /
-#: /Big/Data/C_sources/snippets_library/parseargs.c:84
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:84
msgid "Integer out of range"
msgstr ""
+#. / " !"
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:151
+msgid "Can't use multiple args with arg_none!"
+msgstr ""
+
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:252
+#, c-format
+msgid "double long arguments: --%s"
+msgstr ""
+
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:258
+#, c-format
+msgid "double short arguments: -%c"
+msgstr ""
+
#. / : %s
-#: /Big/Data/C_sources/snippets_library/parseargs.c:478
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:470
#, c-format
msgid "Wrong parameter: %s"
msgstr ""
#. / %s: !
-#: /Big/Data/C_sources/snippets_library/parseargs.c:483
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:475
#, c-format
-msgid "%s: argument needed!"
+msgid "%s: need argument!"
msgstr ""
#. / \"%s\" \"%s\"
-#: /Big/Data/C_sources/snippets_library/parseargs.c:488
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:480
#, c-format
msgid "Wrong argument \"%s\" of parameter \"%s\""
msgstr ""
-#: /Big/Data/C_sources/snippets_library/term.c:92
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:92
#, c-format
msgid "Wrong speed value: %d!"
msgstr ""
#. / %s
-#: /Big/Data/C_sources/snippets_library/term.c:105
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:105
#, c-format
msgid "Can't use port %s"
msgstr ""
#. Get settings
#. /
-#: /Big/Data/C_sources/snippets_library/term.c:111
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:110
msgid "Can't get old TTY settings"
msgstr ""
#. /
-#: /Big/Data/C_sources/snippets_library/term.c:123
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:121
msgid "Can't apply new TTY settings"
msgstr ""
#. /
-#: /Big/Data/C_sources/snippets_library/term.c:129
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:128
msgid "Can't do exclusive open"
msgstr ""
#. /
-#: /Big/Data/C_sources/snippets_library/term.c:168
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:164
msgid "Port name is missing"
msgstr ""
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:170
+msgid "Need non-zero buffer for TTY device"
+msgstr ""
+
#. / /dev/random
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:184
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:185
msgid "Can't open /dev/random"
msgstr ""
#. / /dev/random
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:189
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:190
msgid "Can't read /dev/random"
msgstr ""
#. / !
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:232
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:241
msgid "No filename given!"
msgstr ""
#. / %s
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:237
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:246
#, c-format
msgid "Can't open %s for reading"
msgstr ""
#. / stat %s
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:242
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:251
#, c-format
msgid "Can't stat %s"
msgstr ""
#. / mmap
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:249
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:258
msgid "Mmap error for input"
msgstr ""
#. / mmap'
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:254
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:263
msgid "Can't close mmap'ed file"
msgstr ""
#. / munmap
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:268
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:277
msgid "Can't munmap"
msgstr ""
#. /
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:299
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:308
msgid "Can't setup console"
msgstr ""
#. /
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:374
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:383
msgid "Need filename for log file"
msgstr ""
#. / %s \n
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:378
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:387
#, c-format
msgid "Try to open log file %s in append mode\n"
msgstr ""
#. /
-#: /Big/Data/C_sources/snippets_library/usefull_macros.c:382
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:391
msgid "Can't open log file"
msgstr ""
diff --git a/locale/ru/ru.po b/locale/ru/ru.po
index 13c75b7..872b72d 100644
--- a/locale/ru/ru.po
+++ b/locale/ru/ru.po
@@ -7,7 +7,7 @@
msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
- "POT-Creation-Date: 2019-03-12 09:53+0300\n"
+ "POT-Creation-Date: 2020-12-24 12:22+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -25,34 +25,45 @@ msgstr "\n"
" (pid=%d), .\n"
#. / %s: !
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:483
-#, c-format
-msgid "%s: argument needed!"
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:475
+#, fuzzy, c-format
+msgid "%s: need argument!"
msgstr "%s: !"
+#. /
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:121
+msgid "Can't apply new TTY settings"
+msgstr " "
+
#. / mmap'
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:262
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:263
msgid "Can't close mmap'ed file"
msgstr " mmap' "
#. /
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:129
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:128
msgid "Can't do exclusive open"
msgstr " "
+#. Get settings
+#. /
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:110
+msgid "Can't get old TTY settings"
+msgstr " "
+
#. / munmap
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:276
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:277
msgid "Can't munmap"
msgstr " munmap"
#. / %s
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:245
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:246
#, c-format
msgid "Can't open %s for reading"
msgstr " %s "
#. / /dev/random
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:184
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:185
msgid "Can't open /dev/random"
msgstr " /dev/random"
@@ -62,64 +73,80 @@ msgid "Can't open PID file"
msgstr " PID "
#. /
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:390
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:391
msgid "Can't open log file"
msgstr " "
#. / /dev/random
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:189
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:190
msgid "Can't read /dev/random"
msgstr " /dev/random"
+#. error reading self name
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:118
+#, fuzzy
+msgid "Can't read self name"
+msgstr " "
+
#. /
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:307
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:308
msgid "Can't setup console"
msgstr " "
#. / stat %s
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:250
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:251
#, c-format
msgid "Can't stat %s"
msgstr " stat %s"
+#. / " !"
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:151
+msgid "Can't use multiple args with arg_none!"
+msgstr " arg_none!"
+
+#. / %s
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:105
+#, fuzzy, c-format
+msgid "Can't use port %s"
+msgstr " %s"
+
#. /
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:84
msgid "Integer out of range"
msgstr " "
#. / mmap
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:257
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:258
msgid "Mmap error for input"
msgstr " mmap"
#. /
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:382
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:383
msgid "Need filename for log file"
msgstr " "
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:176
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:170
msgid "Need non-zero buffer for TTY device"
-
msgstr " "
#. / !
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:240
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:241
msgid "No filename given!"
msgstr " !"
#. /
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:169
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:164
msgid "Port name is missing"
msgstr " "
#. / %s \n
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:386
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:387
#, c-format
msgid "Try to open log file %s in append mode\n"
msgstr " %s \n"
#. / \"%s\" \"%s\"
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:488
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:480
#, c-format
msgid "Wrong argument \"%s\" of parameter \"%s\""
msgstr " \"%s\" \"%s\""
@@ -131,7 +158,7 @@ msgid "Wrong helpstring!"
msgstr " "
#. / : %s
-#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:478
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:470
#, c-format
msgid "Wrong parameter: %s"
msgstr " : %s"
@@ -140,3 +167,13 @@ msgstr "
#, c-format
msgid "Wrong speed value: %d!"
msgstr " : %d!"
+
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:252
+#, c-format
+msgid "double long arguments: --%s"
+msgstr " : --%s"
+
+#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:258
+#, c-format
+msgid "double short arguments: -%c"
+msgstr " : -%c"
diff --git a/parseargs.c b/parseargs.c
index 41aba75..00de3ab 100644
--- a/parseargs.c
+++ b/parseargs.c
@@ -148,7 +148,7 @@ void *get_aptr(void *paptr, argtype type){
default:
case arg_none:
/// " !"
- ERRX("Can't use multiple args with arg_none!");
+ ERRX(_("Can't use multiple args with arg_none!"));
break;
case arg_int:
sz = sizeof(int);
@@ -206,18 +206,14 @@ void parseargs(int *argc, char ***argv, myoption *options){
short_options = calloc(optsize * 3 + 1, 1); // multiply by three for '::' in case of args in opts
long_options = calloc(optsize + 1, sizeof(struct option));
opts = options; loptr = long_options; soptr = short_options;
- // in debug mode check the parameters are not repeated
-#ifdef EBUG
+ // check the parameters are not repeated
char **longlist = MALLOC(char*, optsize);
char *shortlist = MALLOC(char, optsize);
-#endif
// fill short/long parameters and make a simple checking
for(i = 0; i < optsize; i++, loptr++, opts++){
// check
assert(opts->name); // check name
-#ifdef EBUG
longlist[i] = strdup(opts->name);
-#endif
if(opts->has_arg){
assert(opts->type != arg_none); // check error with arg type
assert(opts->argptr); // check pointer
@@ -232,9 +228,7 @@ void parseargs(int *argc, char ***argv, myoption *options){
loptr->val = opts->val;
// fill short options if they are:
if(!opts->flag && opts->val){
-#ifdef EBUG
shortlist[i] = (char) opts->val;
-#endif
*soptr++ = opts->val;
if(loptr->has_arg) // add ':' if option has required argument
*soptr++ = ':';
@@ -243,7 +237,6 @@ void parseargs(int *argc, char ***argv, myoption *options){
}
}
// sort all lists & check for repeating
-#ifdef EBUG
int cmpstringp(const void *p1, const void *p2){
return strcmp(* (char * const *) p1, * (char * const *) p2);
}
@@ -256,18 +249,17 @@ void parseargs(int *argc, char ***argv, myoption *options){
for(i = 1; i < optsize; ++i){
if(longlist[i]){
if(prevl){
- if(strcmp(prevl, longlist[i]) == 0) ERRX("double long arguments: --%s", prevl);
+ if(strcmp(prevl, longlist[i]) == 0) ERRX(_("double long arguments: --%s"), prevl);
}
prevl = longlist[i];
}
if(shortlist[i]){
if(prevshrt){
- if(prevshrt == shortlist[i]) ERRX("double short arguments: -%c", prevshrt);
+ if(prevshrt == shortlist[i]) ERRX(_("double short arguments: -%c"), prevshrt);
}
prevshrt = shortlist[i];
}
}
-#endif
// now we have both long_options & short_options and can parse `getopt_long`
while(1){
int opt;
@@ -480,7 +472,7 @@ bool get_suboption(char *str, mysuboption *opt){
}
if(noarg && opt[idx].has_arg == NEED_ARG){
/// %s: !
- WARNX(_("%s: argument needed!"), tok);
+ WARNX(_("%s: need argument!"), tok);
goto returning;
}
if(!opt_setarg(opt, idx, val)){
diff --git a/term.c b/term.c
index 4a045ba..f403f2c 100644
--- a/term.c
+++ b/term.c
@@ -99,13 +99,12 @@ tcflag_t conv_spd(int speed){
* @return 0 if all OK or error code
*/
static int tty_init(TTY_descr *descr){
- DBG("\nOpen port..."); // |O_NONBLOCK
+ // |O_NONBLOCK ?
if ((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){
/// %s
WARN(_("Can't use port %s"), descr->portname);
return globErr ? globErr : 1;
}
- DBG("OK\nGet current settings...");
if(tcgetattr(descr->comfd, &descr->oldtty) < 0){ // Get settings
///
WARN(_("Can't get old TTY settings"));
@@ -128,7 +127,6 @@ static int tty_init(TTY_descr *descr){
///
WARN(_("Can't do exclusive open"));
}}
- DBG("OK");
return 0;
}
@@ -139,14 +137,12 @@ void close_tty(TTY_descr **descr){
if(descr == NULL || *descr == NULL) return;
TTY_descr *d = *descr;
if(d->comfd){
- DBG("close file..");
ioctl(d->comfd, TCSANOW, &d->oldtty); // return TTY to previous state
close(d->comfd);
}
FREE(d->portname);
FREE(d->buf);
FREE(*descr);
- DBG("done!\n");
}
/**
@@ -159,7 +155,6 @@ void close_tty(TTY_descr **descr){
TTY_descr *new_tty(char *comdev, int speed, size_t bufsz){
tcflag_t spd = conv_spd(speed);
if(!spd) return NULL;
- DBG("create %s with speed %d and buffer size %zd", comdev, speed, bufsz);
TTY_descr *descr = MALLOC(TTY_descr, 1);
descr->portname = strdup(comdev);
descr->baudrate = spd;
@@ -171,7 +166,6 @@ TTY_descr *new_tty(char *comdev, int speed, size_t bufsz){
if(bufsz){
descr->buf = MALLOC(char, bufsz+1);
descr->bufsz = bufsz;
- DBG("allocate buffer with size %zd", bufsz);
return descr;
}else WARNX(_("Need non-zero buffer for TTY device"));
}
@@ -187,7 +181,6 @@ TTY_descr *new_tty(char *comdev, int speed, size_t bufsz){
* @return pointer to TTY structure if all OK
*/
TTY_descr *tty_open(TTY_descr *d, int exclusive){
- DBG("open %s with speed %d%s", d->portname, d->speed, exclusive ? "" : " (exclusive)");
if(!d || !d->portname || !d->baudrate) return NULL;
if(exclusive) d->exclusive = TRUE;
else d->exclusive = FALSE;
@@ -195,14 +188,31 @@ TTY_descr *tty_open(TTY_descr *d, int exclusive){
return d;
}
+static struct timeval tvdefault = {.tv_sec = 0, .tv_usec = 5000};
+/**
+ * @brief tty_timeout - set timeout for select() on reading
+ * @param usec - microseconds of timeout
+ * @return -1 if usec < 0, 0 if all OK
+ */
+int tty_timeout(double usec){
+ if(usec < 0.) return -1;
+ tvdefault.tv_sec = 0;
+ if(usec > 999999){
+ tvdefault.tv_sec = (__time_t)(usec / 1e6);
+ usec -= tvdefault.tv_sec * 1e6;
+ }
+ tvdefault.tv_usec = (__suseconds_t) usec;
+ return 0;
+}
+
/**
* @brief read_tty - read data from TTY with 10ms timeout
* @param buff (o) - buffer for data read
* @param length - buffer len
- * @return amount of bytes read
+ * @return amount of bytes read or -1 if disconnected
*/
-size_t read_tty(TTY_descr *d){
- if(d->comfd < 0) return 0;
+int read_tty(TTY_descr *d){
+ if(!d || d->comfd < 0) return 0;
size_t L = 0;
ssize_t l;
size_t length = d->bufsz;
@@ -214,31 +224,23 @@ size_t read_tty(TTY_descr *d){
l = 0;
FD_ZERO(&rfds);
FD_SET(d->comfd, &rfds);
- // wait for 10ms
- tv.tv_sec = 0; tv.tv_usec = 50000;
+ //memcpy(&tv, &tvdefault, sizeof(struct timeval));
+ tv = tvdefault;
retval = select(d->comfd + 1, &rfds, NULL, NULL, &tv);
- if (!retval) break;
+ if(!retval) break;
+ if(retval < 0){
+ if(errno == EINTR) continue;
+ return -1;
+ }
if(FD_ISSET(d->comfd, &rfds)){
- if((l = read(d->comfd, ptr, length)) < 1){
- break;
- }
-#ifdef EBUG
- char *s = ptr;
-#endif
+ l = read(d->comfd, ptr, length);
+ if(l < 1) return -1; // disconnected
ptr += l; L += l;
-#ifdef EBUG
- *ptr = 0;
-#endif
- //DBG("got %zd bytes: %s\nBUF[%zd](%d): %s", l, s, L, d->bufsz, d->buf);
- DBG("FD %d got %zd bytes: %s\nsym: %d, BUF[%zd](%zd): %s", d->comfd, l, s, (int)s[0], L, d->bufsz, d->buf);
length -= l;
}
}while(l && length);
d->buflen = L;
d->buf[L] = 0;
-#ifdef EBUG
- if(L) DBG("Got %zd bytes total: %s", d->buflen, d->buf);
-#endif
return (size_t)L;
}
@@ -249,7 +251,6 @@ size_t read_tty(TTY_descr *d){
* @return 0 if all OK
*/
int write_tty(int comfd, const char *buff, size_t length){
- DBG("comfd: %d, buff: \"%s\", len: %zd", comfd, buff, length);
ssize_t L = write(comfd, buff, length);
if((size_t)L != length){
/// " !"
diff --git a/usefull_macros.c b/usefull_macros.c
index f764901..7a95404 100644
--- a/usefull_macros.c
+++ b/usefull_macros.c
@@ -29,6 +29,7 @@
#include
#include
#include
+#include // flock
#include
#include
#include
@@ -46,6 +47,14 @@ void __attribute__ ((weak)) signals(int sig){
exit(sig);
}
+/**
+ * @brief sl_libversion - version
+ * @return return string with library version
+ */
+const char *sl_libversion(){
+ return PACKAGE_VERSION;
+}
+
/**
* @brief dtime - function for different purposes that need to know time intervals
* @return double value: UNIX time in seconds
@@ -366,7 +375,7 @@ int str2double(double *num, const char *str){
/******************************************************************************\
* Logging to file
- * BE CAREFULL!!! There's only one log file per process!
+ * DEPRECATED!!! DEPRECATED!!! DEPRECATED!!! DEPRECATED!!! DEPRECATED!!! DEPRECATED!!!
\******************************************************************************/
FILE *Flog = NULL; // log file descriptor
char *logname = NULL;
@@ -422,3 +431,106 @@ int putlog(const char *fmt, ...){
return i;
}
+/******************************************************************************\
+ * Logging to file
+\******************************************************************************/
+sl_log *globlog = NULL; // "global" log file (the first opened logfile)
+/**
+ * @brief sl_createlog - create log file, test file open ability
+ * @param logpath - path to log file
+ * @param level - lowest message level (e.g. LOGLEVEL_ERR won't allow to write warn/msg/dbg)
+ * @return allocated structure (should be free'd later by Cl_deletelog) or NULL
+ */
+sl_log *sl_createlog(const char *logpath, sl_loglevel level, int prefix){
+ if(level < LOGLEVEL_NONE || level > LOGLEVEL_ANY) return NULL;
+ if(!logpath) return NULL;
+ FILE *logfd = fopen(logpath, "a");
+ if(!logfd){
+ WARN("Can't open log file");
+ return NULL;
+ }
+ fclose(logfd);
+ sl_log *log = MALLOC(sl_log, 1);
+ log->logpath = strdup(logpath);
+ if(!log->logpath){
+ WARN("strdup()");
+ FREE(log);
+ return NULL;
+ }
+ log->loglevel = level;
+ log->addprefix = prefix;
+ return log;
+}
+
+void sl_deletelog(sl_log **log){
+ if(!log || !*log) return;
+ FREE((*log)->logpath);
+ FREE(*log);
+}
+
+/**
+ * @brief sl_putlog - put message to log file with/without timestamp
+ * @param timest - ==1 to put timestamp
+ * @param log - pointer to log structure
+ * @param lvl - message loglevel (if lvl > loglevel, message won't be printed)
+ * @param fmt - format and the rest part of message
+ * @return amount of symbols saved in file
+ */
+int sl_putlogt(int timest, sl_log *log, sl_loglevel lvl, const char *fmt, ...){
+ if(!log || !log->logpath) return 0;
+ if(lvl > log->loglevel) return 0;
+ int i = 0;
+ FILE *logfd = fopen(log->logpath, "a+");
+ if(!logfd) return 0;
+ int lfd = fileno(logfd);
+ // try to lock file
+ double t0 = dtime();
+ int locked = 0;
+ while(dtime() - t0 < 0.1){ // timeout for 0.1s
+ if(-1 == flock(lfd, LOCK_EX | LOCK_NB)) continue;
+ locked = 1;
+ break;
+ }
+ if(!locked) return 0; // can't lock
+ if(log->addprefix){
+ const char *p;
+ switch(lvl){
+ case LOGLEVEL_ERR:
+ p = "[ERR]";
+ break;
+ case LOGLEVEL_WARN:
+ p = "[WARN]";
+ break;
+ case LOGLEVEL_MSG:
+ p = "[MSG]";
+ break;
+ case LOGLEVEL_DBG:
+ p = "[DBG]";
+ break;
+ default:
+ p = NULL;
+ }
+ if(p) i += fprintf(logfd, "%s\t", p);
+ }
+ if(timest){
+ char strtm[128];
+ time_t t = time(NULL);
+ struct tm *curtm = localtime(&t);
+ strftime(strtm, 128, "%Y/%m/%d-%H:%M:%S", curtm);
+ i = fprintf(logfd, "%s", strtm);
+ }
+ i += fprintf(logfd, "\t");
+ va_list ar;
+ va_start(ar, fmt);
+ i += vfprintf(logfd, fmt, ar);
+ va_end(ar);
+ fseek(logfd, -1, SEEK_CUR);
+ char c;
+ ssize_t r = fread(&c, 1, 1, logfd);
+ if(1 == r){ // add '\n' if there was no newline
+ if(c != '\n') i += fprintf(logfd, "\n");
+ }
+ flock(lfd, LOCK_UN);
+ fclose(logfd);
+ return i;
+}
diff --git a/usefull_macros.h b/usefull_macros.h
index c4e3c4d..06ebf4e 100644
--- a/usefull_macros.h
+++ b/usefull_macros.h
@@ -111,6 +111,9 @@ void WEAK signals(int sig);
#define DBL_EPSILON (2.2204460492503131e-16)
#endif
+// library version
+const char *sl_libversion();
+
// double value of UNIX time
double dtime();
@@ -160,16 +163,52 @@ typedef struct {
void close_tty(TTY_descr **descr);
TTY_descr *new_tty(char *comdev, int speed, size_t bufsz);
TTY_descr *tty_open(TTY_descr *d, int exclusive);
-size_t read_tty(TTY_descr *descr);
+int read_tty(TTY_descr *descr);
+int tty_timeout(double usec);
int write_tty(int comfd, const char *buff, size_t length);
tcflag_t conv_spd(int speed);
// convert string to double with checking
int str2double(double *num, const char *str);
-// logging
-void openlogfile(char *name);
-int putlog(const char *fmt, ...);
+// logging (deprecated)
+void __attribute__ ((deprecated)) openlogfile(char *name);
+int __attribute__ ((deprecated)) putlog(const char *fmt, ...);
+
+/******************************************************************************\
+ Logging
+\******************************************************************************/
+typedef enum{
+ LOGLEVEL_NONE, // no logs
+ LOGLEVEL_ERR, // only errors
+ LOGLEVEL_WARN, // only warnings and errors
+ LOGLEVEL_MSG, // all without debug
+ LOGLEVEL_DBG, // all messages
+ LOGLEVEL_ANY // all shit
+} sl_loglevel;
+
+typedef struct{
+ char *logpath; // full path to logfile
+ sl_loglevel loglevel; // loglevel
+ int addprefix; // if !=0 add record type to each line(e.g. [ERR])
+} sl_log;
+
+extern sl_log *globlog; // "global" log file
+
+sl_log *sl_createlog(const char *logpath, sl_loglevel level, int prefix);
+void sl_deletelog(sl_log **log);
+int sl_putlogt(int timest, sl_log *log, sl_loglevel lvl, const char *fmt, ...);
+// open "global" log
+#define OPENLOG(nm, lvl, prefix) (globlog = sl_createlog(nm, lvl, prefix))
+// shortcuts for different log levels; ..ADD - add message without timestamp
+#define LOGERR(...) do{sl_putlogt(1, globlog, LOGLEVEL_ERR, __VA_ARGS__);}while(0)
+#define LOGERRADD(...) do{sl_putlogt(0, globlog, LOGLEVEL_ERR, __VA_ARGS__);}while(0)
+#define LOGWARN(...) do{sl_putlogt(1, globlog, LOGLEVEL_WARN, __VA_ARGS__);}while(0)
+#define LOGWARNADD(...) do{sl_putlogt(0, globlog, LOGLEVEL_WARN, __VA_ARGS__);}while(0)
+#define LOGMSG(...) do{sl_putlogt(1, globlog, LOGLEVEL_MSG, __VA_ARGS__);}while(0)
+#define LOGMSGADD(...) do{sl_putlogt(0, globlog, LOGLEVEL_MSG, __VA_ARGS__);}while(0)
+#define LOGDBG(...) do{sl_putlogt(1, globlog, LOGLEVEL_DBG, __VA_ARGS__);}while(0)
+#define LOGDBGADD(...) do{sl_putlogt(0, globlog, LOGLEVEL_DBG, __VA_ARGS__);}while(0)
/******************************************************************************\
The original parseargs.h
@@ -276,7 +315,6 @@ void WEAK iffound_default(pid_t pid);
void check4running(char *selfname, char *pidfilename);
// read name of process by its PID
char *readPSname(pid_t pid);
-#endif // __USEFULL_MACROS_H__
/******************************************************************************\
The original fifo_lifo.h
@@ -289,3 +327,7 @@ typedef struct buff_node{
List *list_push_tail(List **lst, void *v);
List *list_push(List **lst, void *v);
void *list_pop(List **lst);
+
+
+
+#endif // __USEFULL_MACROS_H__