mirror of
https://github.com/eddyem/snippets_library.git
synced 2025-12-06 10:45:10 +03:00
version 0.2.1
This commit is contained in:
parent
511a83e506
commit
e77fddc3b8
@ -2,3 +2,5 @@ cmake defines:
|
|||||||
-DDEBUG=1 - debug mode
|
-DDEBUG=1 - debug mode
|
||||||
-DNOGETTEXT=1 - don't run xgettext
|
-DNOGETTEXT=1 - don't run xgettext
|
||||||
-DEXAMPLES=1 - to compile examples
|
-DEXAMPLES=1 - to compile examples
|
||||||
|
-DSL_USE_OLD_TTY - use old termios instead of termios2 (you should use this flag always if library works so)
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.9)
|
cmake_minimum_required(VERSION 3.9)
|
||||||
set(PROJ usefull_macros)
|
set(PROJ usefull_macros)
|
||||||
set(MINOR_VERSION "1")
|
set(MINOR_VERSION "1")
|
||||||
set(MID_VERSION "1")
|
set(MID_VERSION "2")
|
||||||
set(MAJOR_VERSION "0")
|
set(MAJOR_VERSION "0")
|
||||||
set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}")
|
set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}")
|
||||||
|
|
||||||
@ -51,6 +51,16 @@ message("Build type: ${CMAKE_BUILD_TYPE}")
|
|||||||
# here is one of two variants: all .c in directory or .c files in list
|
# here is one of two variants: all .c in directory or .c files in list
|
||||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SOURCES)
|
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SOURCES)
|
||||||
|
|
||||||
|
get_filename_component(term_c ${CMAKE_CURRENT_SOURCE_DIR}/term.c ABSOLUTE)
|
||||||
|
if(DEFINED USE_OLD_TTY OR DEFINED SL_USE_OLD_TTY)
|
||||||
|
get_filename_component(term_c ${CMAKE_CURRENT_SOURCE_DIR}/term2.c ABSOLUTE)
|
||||||
|
add_definitions(-DSL_USE_OLD_TTY)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message("remove ${term_c}")
|
||||||
|
list(REMOVE_ITEM SOURCES ${term_c})
|
||||||
|
|
||||||
|
|
||||||
# directory should contain dir locale/ru for gettext translations
|
# directory should contain dir locale/ru for gettext translations
|
||||||
set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru)
|
set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru)
|
||||||
if(NOT DEFINED LOCALEDIR)
|
if(NOT DEFINED LOCALEDIR)
|
||||||
@ -136,7 +146,7 @@ if(NOT DEFINED NOGETTEXT)
|
|||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${PO_FILE}
|
OUTPUT ${PO_FILE}
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} --from-code=utf-8 ${SOURCES} -c -k_ -kN_ -o ${PO_FILE}
|
COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} --from-code=koi8-r ${SOURCES} -c -k_ -kN_ -o ${PO_FILE}
|
||||||
COMMAND sed -i 's/charset=.*\\\\n/charset=koi8-r\\\\n/' ${PO_FILE}
|
COMMAND sed -i 's/charset=.*\\\\n/charset=koi8-r\\\\n/' ${PO_FILE}
|
||||||
COMMAND enconv ${PO_FILE}
|
COMMAND enconv ${PO_FILE}
|
||||||
DEPENDS ${SOURCES}
|
DEPENDS ${SOURCES}
|
||||||
|
|||||||
49
Changelog
49
Changelog
@ -5,3 +5,52 @@ add tty_timeout()
|
|||||||
fix read_tty() for disconnect
|
fix read_tty() for disconnect
|
||||||
add logging
|
add logging
|
||||||
add sl_libversion()
|
add sl_libversion()
|
||||||
|
|
||||||
|
VERSION 0.2.1:
|
||||||
|
RENAME:
|
||||||
|
initial_setup -> sl_init
|
||||||
|
dtime -> sl_dtime
|
||||||
|
my_alloc -> sl_alloc
|
||||||
|
mmapbuf -> sl_mmapuf_t
|
||||||
|
My_mmap -> sl_mmap
|
||||||
|
My_munmap -> sl_munmap
|
||||||
|
restore_console -> sl_restore_con
|
||||||
|
setup_con -> sl_setup_con
|
||||||
|
read_console -> sl_read_con
|
||||||
|
mygetchar -> sl_getchar
|
||||||
|
throw_random_seed -> sl_random_seed
|
||||||
|
get_available_mem -> sl_mem_avail
|
||||||
|
TTY_descr -> sl_tty_t
|
||||||
|
close_tty -> sl_tty_close
|
||||||
|
new_tty -> sl_tty_new
|
||||||
|
tty_open -> sl_tty_open
|
||||||
|
read_tty -> sl_tty_read
|
||||||
|
tty_timeout -> sl_tty_tmout
|
||||||
|
write_tty -> sl_tty_write
|
||||||
|
conv_spd -> sl_tty_convspd
|
||||||
|
str2double -> sl_str2d
|
||||||
|
globlog -> sl_globlog
|
||||||
|
sl_loglevel -> sl_loglevel_e
|
||||||
|
sl_log -> sl_log_t
|
||||||
|
argfn -> sl_argfn_t
|
||||||
|
argtype -> sl_argtype_e
|
||||||
|
hasarg -> sl_hasarg_e
|
||||||
|
myoption -> sl_option_t
|
||||||
|
mysuboption -> sl_suboption_t
|
||||||
|
showhelp -> sl_showhelp
|
||||||
|
parseargs -> sl_parseargs
|
||||||
|
change_helpstring -> sl_helpstring
|
||||||
|
get_suboption -> sl_get_suboption
|
||||||
|
iffound_default -> sl_iffound_deflt
|
||||||
|
check4running -> sl_check4running
|
||||||
|
readPSname -> sl_getPSname
|
||||||
|
struct buff_node -> struct sl_buff_node
|
||||||
|
List -> sl_list_t
|
||||||
|
list_push_tail -> sl_list_push_tail
|
||||||
|
list_push -> sl_list_push
|
||||||
|
list_pop -> sl_list_pop
|
||||||
|
Remove deprecated code (openlogfile, putlog)
|
||||||
|
Remove "bool" type (change to int)
|
||||||
|
FIXED bug with several only long options with same shortopt mark (like 0)
|
||||||
|
Add simple config files, so you can move some of your parameters settings to it
|
||||||
|
|
||||||
|
|||||||
1
TODO
1
TODO
@ -1,2 +1 @@
|
|||||||
BUG in commandline options: '?' don't work!
|
BUG in commandline options: '?' don't work!
|
||||||
Add prefixes sl_ to every function for solving further problems
|
|
||||||
|
|||||||
300
config.c
Normal file
300
config.c
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Snippets project.
|
||||||
|
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <float.h> // FLT_max/min
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_get_keyval - get key name and its value from string pair
|
||||||
|
* @param pair - empty string, `key = value` or just `key`
|
||||||
|
* @param key - substring with `key`
|
||||||
|
* @param value - its value or empty line
|
||||||
|
* @return 0 if no key found (or line is a comment with '#' first); 1 if only key found and 2 if found both key and value
|
||||||
|
* this function removes all leading and trailing spaces in `key` and `value`;
|
||||||
|
* also if `key` have several words only first saved, `value` can be long string with or without quotations
|
||||||
|
*/
|
||||||
|
int sl_get_keyval(const char *pair, char key[SL_KEY_LEN], char value[SL_VAL_LEN]){
|
||||||
|
DBG("got pair: '%s'", pair);
|
||||||
|
if(!pair || !*pair) return 0; // empty line
|
||||||
|
char *kstart = sl_omitspaces(pair);
|
||||||
|
if(!*kstart || *kstart == SL_COMMENT_CHAR) return 0; // only spaces
|
||||||
|
int ret = 1;
|
||||||
|
char *eq = strchr(kstart, '='), *kend = kstart + 1;
|
||||||
|
if(eq == kstart) return 0; // only = (and maybe val)
|
||||||
|
char *cmnt = strchr(kstart, SL_COMMENT_CHAR);
|
||||||
|
if(eq && cmnt && cmnt < eq) eq = NULL; // comment starting before equal sign
|
||||||
|
if(eq){ do{
|
||||||
|
DBG("got equal symbol: '%s'", eq);
|
||||||
|
char *vstart = sl_omitspaces(eq + 1);
|
||||||
|
if(!*vstart) break; // empty line or only spaces after `=`
|
||||||
|
char *vend = sl_omitspacesr(vstart);
|
||||||
|
size_t l = SL_VAL_LEN - 1; // truncate value to given length
|
||||||
|
if(l > (size_t)(vend - vstart)) l = vend - vstart;
|
||||||
|
DBG("l=%zd", l);
|
||||||
|
strncpy(value, vstart, l);
|
||||||
|
value[l] = 0;
|
||||||
|
cmnt = strchr(value, SL_COMMENT_CHAR);
|
||||||
|
if(cmnt){ // remove trailing spaces before comment
|
||||||
|
*cmnt = 0;
|
||||||
|
*sl_omitspacesr(value) = 0;
|
||||||
|
}
|
||||||
|
if(!*value) break;
|
||||||
|
DBG("Got value: '%s'", value);
|
||||||
|
ret = 2;
|
||||||
|
}while(0);
|
||||||
|
}else eq = kstart + strlen(kstart) - 1;
|
||||||
|
for(; kend < eq && !isspace(*kend); ++kend);
|
||||||
|
size_t l = SL_KEY_LEN - 1;
|
||||||
|
if(l > (size_t)(kend - kstart)) l = kend - kstart;
|
||||||
|
strncpy(key, kstart, l);
|
||||||
|
key[l] = 0;
|
||||||
|
cmnt = strchr(key, SL_COMMENT_CHAR);
|
||||||
|
if(cmnt) *cmnt = 0;
|
||||||
|
DBG("Got key: '%s'", key);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read key/value from file; return -1 when file is over
|
||||||
|
static int read_key(FILE *file, char key[SL_KEY_LEN], char value[SL_VAL_LEN]){
|
||||||
|
char *line = NULL;
|
||||||
|
size_t n = 0;
|
||||||
|
ssize_t got = getline(&line, &n, file);
|
||||||
|
if(!line) return 0;
|
||||||
|
if(got < 0){ // EOF
|
||||||
|
free(line);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int r = sl_get_keyval(line, key, value);
|
||||||
|
free(line);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// search `opt` record for given `key`
|
||||||
|
static sl_option_t *opt_search(const char *key, sl_option_t *options){
|
||||||
|
while(options->name){
|
||||||
|
if(0 == strcmp(key, options->name)) return options;
|
||||||
|
++options;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_print_opts - fills string buffer with information from opt
|
||||||
|
* @param opt - options buffer
|
||||||
|
* @param showall - TRUE to show even uninitialized options with NO_ARGS
|
||||||
|
* @return allocated string (should be free'd)
|
||||||
|
*/
|
||||||
|
char *sl_print_opts(sl_option_t *opt, int showall){
|
||||||
|
char *buf = MALLOC(char, BUFSIZ);
|
||||||
|
size_t L = BUFSIZ, l = 0;
|
||||||
|
for(; opt->name; ++opt){
|
||||||
|
DBG("check %s", opt->name);
|
||||||
|
if(!showall && opt->has_arg == NO_ARGS) continue; // show NO_ARGS only when `showall==TRUE`
|
||||||
|
if(!showall && opt->type == arg_string && !opt->argptr) continue; // empty string
|
||||||
|
if((ssize_t)L - l < SL_KEY_LEN + SL_VAL_LEN + 5){
|
||||||
|
L += BUFSIZ;
|
||||||
|
buf = realloc(buf, L);
|
||||||
|
if(!buf) ERR("realloc()");
|
||||||
|
}
|
||||||
|
l += sprintf(buf + l, "%s=", opt->name);
|
||||||
|
if(opt->flag){
|
||||||
|
DBG("got flag '%d'", *opt->flag);
|
||||||
|
l += sprintf(buf + l, "%d\n", *opt->flag);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!opt->argptr){ // ERR!
|
||||||
|
l += sprintf(buf + l, "\"(no argptr)\"\n");
|
||||||
|
WARNX("Parameter \"%s\" have no argptr!", opt->name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int z = 0;
|
||||||
|
DBG("type: %d", opt->type);
|
||||||
|
switch(opt->type){
|
||||||
|
case arg_none:
|
||||||
|
case arg_int:
|
||||||
|
DBG("int %d", *(int*) opt->argptr);
|
||||||
|
l += sprintf(buf + l, "%d", *(int*) opt->argptr);
|
||||||
|
break;
|
||||||
|
case arg_longlong:
|
||||||
|
DBG("long long %lld", *(long long*) opt->argptr);
|
||||||
|
l += sprintf(buf + l, "%lld", *(long long*) opt->argptr);
|
||||||
|
break;
|
||||||
|
case arg_float:
|
||||||
|
DBG("float %g", *(float*) opt->argptr);
|
||||||
|
l += sprintf(buf + l, "%g", *(float*) opt->argptr);
|
||||||
|
break;
|
||||||
|
case arg_double:
|
||||||
|
DBG("double %g", *(double*) opt->argptr);
|
||||||
|
l += sprintf(buf + l, "%g", *(double*) opt->argptr);
|
||||||
|
break;
|
||||||
|
case arg_string:
|
||||||
|
if(!opt->argptr || !(*(char*)opt->argptr)){
|
||||||
|
l += sprintf(buf + l, "(null)");
|
||||||
|
break;
|
||||||
|
}else if(!(**(char**)opt->argptr)){
|
||||||
|
l += sprintf(buf + l, "(empty)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBG("string %s", *(char**) opt->argptr);
|
||||||
|
z = strlen(*(char**) opt->argptr);
|
||||||
|
while(l + z > L + 3){
|
||||||
|
L += BUFSIZ;
|
||||||
|
buf = realloc(buf, L);
|
||||||
|
}
|
||||||
|
l += sprintf(buf + l, "%s", *(char**) opt->argptr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DBG("function");
|
||||||
|
l += sprintf(buf + l, "\"(unsupported)\"");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
l += sprintf(buf + l, "\n");
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_set_optval - convert `val` to `oval` parameter according to argument type
|
||||||
|
* @param oval (o) - value in int/long long/double/float
|
||||||
|
* @param opt (i) - record with options
|
||||||
|
* @param val (i) - new value
|
||||||
|
* @return FALSE if failed (or wrong data range)
|
||||||
|
*/
|
||||||
|
int sl_set_optval(sl_optval *oval, sl_option_t *opt, const char *val){
|
||||||
|
if(!oval || !opt || !val) return FALSE;
|
||||||
|
long long ll;
|
||||||
|
double d;
|
||||||
|
switch(opt->type){
|
||||||
|
case arg_none:
|
||||||
|
case arg_int:
|
||||||
|
case arg_longlong:
|
||||||
|
do{
|
||||||
|
if(!sl_str2ll(&ll, val)){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(opt->type != arg_longlong){
|
||||||
|
if(ll > INT_MAX || ll < INT_MIN){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
oval->ival = (int)ll;
|
||||||
|
}else oval->llval = ll;
|
||||||
|
return TRUE;
|
||||||
|
}while(0);
|
||||||
|
break;
|
||||||
|
case arg_double:
|
||||||
|
case arg_float:
|
||||||
|
do{
|
||||||
|
if(!sl_str2d(&d, val)){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(opt->type == arg_double){
|
||||||
|
oval->dval = d;
|
||||||
|
}else{
|
||||||
|
if(d > FLT_MAX || d < FLT_MIN){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
oval->fval = (float)d;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}while(0);
|
||||||
|
break;
|
||||||
|
case arg_string:
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARNX(_("Unsupported option type"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
WARNX(_("Wrong number format '%s'"), val);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// increment opt->argptr or set it to val
|
||||||
|
static void setoa(sl_option_t *opt, const char *val){
|
||||||
|
if(!opt || !opt->argptr || opt->type == arg_function) return;
|
||||||
|
sl_optval O;
|
||||||
|
if(!sl_set_optval(&O, opt, val)) return;
|
||||||
|
switch(opt->type){
|
||||||
|
case arg_none: // increment integer
|
||||||
|
*(int*) opt->argptr += O.ival;
|
||||||
|
break;
|
||||||
|
case arg_int:
|
||||||
|
*(int*) opt->argptr = O.ival;
|
||||||
|
break;
|
||||||
|
case arg_longlong:
|
||||||
|
*(long long*) opt->argptr = O.llval;
|
||||||
|
break;
|
||||||
|
case arg_double:
|
||||||
|
*(double*) opt->argptr = O.dval;
|
||||||
|
break;
|
||||||
|
case arg_float:
|
||||||
|
*(float*) opt->argptr = O.fval;
|
||||||
|
break;
|
||||||
|
case arg_string:
|
||||||
|
*(char**)opt->argptr = strdup(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_conf_readopts - simplest configuration:
|
||||||
|
* read file with lines "par" or "par = val" and set variables like they are options
|
||||||
|
* @param filename - configuration file name
|
||||||
|
* @param options - array with options (could be the same like for sl_parseargs)
|
||||||
|
* @return amount of data read
|
||||||
|
*/
|
||||||
|
int sl_conf_readopts(const char *filename, sl_option_t *options){
|
||||||
|
if(!filename || !options) return 0;
|
||||||
|
FILE *f = fopen(filename, "r");
|
||||||
|
if(!f){
|
||||||
|
WARN(_("Can't open %s"), filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int N = 0;
|
||||||
|
char key[SL_KEY_LEN], val[SL_VAL_LEN];
|
||||||
|
do{
|
||||||
|
int r = read_key(f, key, val);
|
||||||
|
if(r < 0) break;
|
||||||
|
if(r == 0) continue;
|
||||||
|
sl_option_t *opt = opt_search(key, options);
|
||||||
|
if(!opt){
|
||||||
|
WARNX(_("Wrong key: '%s'"), key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(opt->flag) *opt->flag = opt->val;
|
||||||
|
if(r == 1){ // only key
|
||||||
|
if(opt->has_arg != NO_ARGS && opt->has_arg != OPT_ARG){
|
||||||
|
WARNX(_("Key '%s' need value"), opt->name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(opt->argptr) setoa(opt, "1");
|
||||||
|
}else{ // key + value
|
||||||
|
if(opt->argptr) setoa(opt, val);
|
||||||
|
else WARNX(_("Key '%s' have no argptr!"), opt->name);
|
||||||
|
}
|
||||||
|
++N;
|
||||||
|
}while(1);
|
||||||
|
return N;
|
||||||
|
}
|
||||||
22
daemon.c
22
daemon.c
@ -31,13 +31,13 @@
|
|||||||
#include "usefull_macros.h"
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief readPSname - read process name from /proc/PID/cmdline
|
* @brief sl_getPSname - read process name from /proc/PID/cmdline
|
||||||
* @param pid - PID of interesting process
|
* @param pid - PID of interesting process
|
||||||
* @return filename or NULL if not found
|
* @return filename or NULL if not found
|
||||||
* don't use this function twice for different names without copying
|
* don't use this function twice for different names without copying
|
||||||
* its returning by strdup, because `name` contains in static array
|
* its returning by strdup, because `name` contains in static array
|
||||||
*/
|
*/
|
||||||
char *readPSname(pid_t pid){
|
char *sl_getPSname(pid_t pid){
|
||||||
static char name[PATH_MAX];
|
static char name[PATH_MAX];
|
||||||
char *pp = name, byte, path[PATH_MAX];
|
char *pp = name, byte, path[PATH_MAX];
|
||||||
FILE *file;
|
FILE *file;
|
||||||
@ -61,11 +61,11 @@ char *readPSname(pid_t pid){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief iffound_default - default action when running process found
|
* @brief sl_iffound_deflt - default action when running process found
|
||||||
* @param pid - another process' pid
|
* @param pid - another process' pid
|
||||||
* Redefine this function for user action
|
* Redefine this function for user action
|
||||||
*/
|
*/
|
||||||
void WEAK iffound_default(pid_t pid){
|
void WEAK sl_iffound_deflt(pid_t pid){
|
||||||
/// \nïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n
|
/// \nïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n
|
||||||
fprintf(stderr, _("\nFound running process (pid=%d), exit.\n"), pid);
|
fprintf(stderr, _("\nFound running process (pid=%d), exit.\n"), pid);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@ -81,7 +81,7 @@ void WEAK iffound_default(pid_t pid){
|
|||||||
* @param selfname - argv[0] or NULL for non-locking
|
* @param selfname - argv[0] or NULL for non-locking
|
||||||
* @param pidfilename - name of pidfile or NULL if none
|
* @param pidfilename - name of pidfile or NULL if none
|
||||||
*/
|
*/
|
||||||
void check4running(char *selfname, char *pidfilename){
|
void sl_check4running(char *selfname, char *pidfilename){
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
FILE *pidfile, *fself;
|
FILE *pidfile, *fself;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
@ -102,7 +102,7 @@ void check4running(char *selfname, char *pidfilename){
|
|||||||
goto selfpid;
|
goto selfpid;
|
||||||
}
|
}
|
||||||
if(fl.l_type != F_UNLCK){ // file is locking - exit
|
if(fl.l_type != F_UNLCK){ // file is locking - exit
|
||||||
iffound_default(fl.l_pid);
|
sl_iffound_deflt(fl.l_pid);
|
||||||
}
|
}
|
||||||
fl.l_type = F_RDLCK;
|
fl.l_type = F_RDLCK;
|
||||||
if(fcntl(fileno(fself), F_SETLKW, &fl) == -1){
|
if(fcntl(fileno(fself), F_SETLKW, &fl) == -1){
|
||||||
@ -114,7 +114,7 @@ void check4running(char *selfname, char *pidfilename){
|
|||||||
if(!(dir = opendir(PROC_BASE))){ // open /proc directory
|
if(!(dir = opendir(PROC_BASE))){ // open /proc directory
|
||||||
ERR(PROC_BASE);
|
ERR(PROC_BASE);
|
||||||
}
|
}
|
||||||
if(!(name = readPSname(self))){ // error reading self name
|
if(!(name = sl_getPSname(self))){ // error reading self name
|
||||||
ERR(_("Can't read self name"));
|
ERR(_("Can't read self name"));
|
||||||
}
|
}
|
||||||
myname = strdup(name);
|
myname = strdup(name);
|
||||||
@ -122,8 +122,8 @@ void check4running(char *selfname, char *pidfilename){
|
|||||||
pidfile = fopen(pidfilename, "r");
|
pidfile = fopen(pidfilename, "r");
|
||||||
if(pidfile){
|
if(pidfile){
|
||||||
if(fscanf(pidfile, "%d", &pid) > 0){ // read PID of (possibly) running process
|
if(fscanf(pidfile, "%d", &pid) > 0){ // read PID of (possibly) running process
|
||||||
if((name = readPSname(pid)) && strncmp(name, myname, 255) == 0)
|
if((name = sl_getPSname(pid)) && strncmp(name, myname, 255) == 0)
|
||||||
iffound_default(pid);
|
sl_iffound_deflt(pid);
|
||||||
}
|
}
|
||||||
fclose(pidfile);
|
fclose(pidfile);
|
||||||
}
|
}
|
||||||
@ -132,8 +132,8 @@ void check4running(char *selfname, char *pidfilename){
|
|||||||
while((de = readdir(dir))){ // scan /proc
|
while((de = readdir(dir))){ // scan /proc
|
||||||
if(!(pid = (pid_t)atoi(de->d_name)) || pid == self) // pass non-PID files and self
|
if(!(pid = (pid_t)atoi(de->d_name)) || pid == self) // pass non-PID files and self
|
||||||
continue;
|
continue;
|
||||||
if((name = readPSname(pid)) && strncmp(name, myname, 255) == 0)
|
if((name = sl_getPSname(pid)) && strncmp(name, myname, 255) == 0)
|
||||||
iffound_default(pid);
|
sl_iffound_deflt(pid);
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
free(myname);
|
free(myname);
|
||||||
|
|||||||
@ -9,3 +9,4 @@ link_libraries(usefull_macros)
|
|||||||
add_executable(helloworld helloworld.c)
|
add_executable(helloworld helloworld.c)
|
||||||
add_executable(options options.c cmdlnopts.c)
|
add_executable(options options.c cmdlnopts.c)
|
||||||
add_executable(fifo fifo.c)
|
add_executable(fifo fifo.c)
|
||||||
|
add_executable(conffile conffile.c)
|
||||||
|
|||||||
@ -38,6 +38,9 @@ static glob_pars G;
|
|||||||
// DEFAULTS
|
// DEFAULTS
|
||||||
// default global parameters
|
// default global parameters
|
||||||
static glob_pars const Gdefault = {
|
static glob_pars const Gdefault = {
|
||||||
|
.lo0 = INT_MIN,
|
||||||
|
.lo1 = INT_MIN,
|
||||||
|
.lo2 = INT_MIN,
|
||||||
.device = NULL,
|
.device = NULL,
|
||||||
.pidfile = DEFAULT_PIDFILE,
|
.pidfile = DEFAULT_PIDFILE,
|
||||||
.speed = 9600,
|
.speed = 9600,
|
||||||
@ -48,15 +51,21 @@ static glob_pars const Gdefault = {
|
|||||||
* Define command line options by filling structure:
|
* Define command line options by filling structure:
|
||||||
* name has_arg flag val type argptr help
|
* name has_arg flag val type argptr help
|
||||||
*/
|
*/
|
||||||
static myoption cmdlnopts[] = {
|
static sl_option_t cmdlnopts[] = {
|
||||||
// common options
|
{"lo0", NEED_ARG, NULL, 0, arg_int, APTR(&G.lo0), _("only long arg 0")},
|
||||||
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
|
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
|
||||||
// {"dup", 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")},
|
{"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), _("serial device name")},
|
||||||
|
{"lo2", NEED_ARG, NULL, 0, arg_int, APTR(&G.lo2), _("only long arg 2")},
|
||||||
{"speed", NEED_ARG, NULL, 's', arg_int, APTR(&G.speed), _("serial device speed (default: 9600)")},
|
{"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")},
|
{"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), _("file to save logs")},
|
||||||
{"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")},
|
{"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")},
|
||||||
{"exclusive",NO_ARGS, NULL, 'e', arg_int, APTR(&G.exclusive), _("open serial device exclusively")},
|
{"exclusive",NO_ARGS, NULL, 'e', arg_int, APTR(&G.exclusive), _("open serial device exclusively")},
|
||||||
|
// example of multiple options
|
||||||
|
{"Int", MULT_PAR, NULL, 'I', arg_int, APTR(&G.intarr), _("integer multiplying parameter")},
|
||||||
|
{"Dbl", MULT_PAR, NULL, 'D', arg_double, APTR(&G.dblarr), _("double multiplying parameter")},
|
||||||
|
{"Str", MULT_PAR, NULL, 'S', arg_string, APTR(&G.strarr), _("string multiplying parameter")},
|
||||||
|
{"lo1", NEED_ARG, NULL, 0, arg_int, APTR(&G.lo1), _("only long arg 1")},
|
||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,10 +84,10 @@ glob_pars *parse_args(int argc, char **argv){
|
|||||||
char helpstring[1024], *hptr = helpstring;
|
char helpstring[1024], *hptr = helpstring;
|
||||||
snprintf(hptr, hlen, "Usage: %%s [args]\n\n\tWhere args are:\n");
|
snprintf(hptr, hlen, "Usage: %%s [args]\n\n\tWhere args are:\n");
|
||||||
// format of help: "Usage: progname [args]\n"
|
// format of help: "Usage: progname [args]\n"
|
||||||
change_helpstring(helpstring);
|
sl_helpstring(helpstring);
|
||||||
// parse arguments
|
// parse arguments
|
||||||
parseargs(&argc, &argv, cmdlnopts);
|
sl_parseargs(&argc, &argv, cmdlnopts);
|
||||||
if(help) showhelp(-1, cmdlnopts);
|
if(help) sl_showhelp(-1, cmdlnopts);
|
||||||
if(argc > 0){
|
if(argc > 0){
|
||||||
G.rest_pars_num = argc;
|
G.rest_pars_num = argc;
|
||||||
G.rest_pars = MALLOC(char *, argc);
|
G.rest_pars = MALLOC(char *, argc);
|
||||||
|
|||||||
@ -31,8 +31,14 @@ typedef struct{
|
|||||||
char *pidfile; // name of PID file
|
char *pidfile; // name of PID file
|
||||||
char *logfile; // logging to this file
|
char *logfile; // logging to this file
|
||||||
int speed; // connection speed
|
int speed; // connection speed
|
||||||
int rest_pars_num; // number of rest parameters
|
|
||||||
int exclusive; // exclusive open port
|
int exclusive; // exclusive open port
|
||||||
|
int **intarr; // integer multopt
|
||||||
|
double **dblarr; // double -//-
|
||||||
|
char **strarr; // char -//-
|
||||||
|
int lo0; // only long options
|
||||||
|
int lo1;
|
||||||
|
int lo2;
|
||||||
|
int rest_pars_num; // number of rest parameters
|
||||||
char** rest_pars; // the rest parameters: array of char*
|
char** rest_pars; // the rest parameters: array of char*
|
||||||
} glob_pars;
|
} glob_pars;
|
||||||
|
|
||||||
|
|||||||
101
examples/conffile.c
Normal file
101
examples/conffile.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Snippets project.
|
||||||
|
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h> // NaN
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
char *sp1;
|
||||||
|
char *sp2;
|
||||||
|
int ip1;
|
||||||
|
int ip2;
|
||||||
|
double dp1;
|
||||||
|
double dp2;
|
||||||
|
float fp1;
|
||||||
|
float fp2;
|
||||||
|
int help;
|
||||||
|
int verbose;
|
||||||
|
char *confname;
|
||||||
|
} parameters;
|
||||||
|
|
||||||
|
static parameters G = {
|
||||||
|
.ip1 = INT_MIN,
|
||||||
|
.ip2 = INT_MIN,
|
||||||
|
.dp1 = NAN,
|
||||||
|
.dp2 = NAN,
|
||||||
|
.fp1 = NAN,
|
||||||
|
.fp2 = NAN
|
||||||
|
};
|
||||||
|
|
||||||
|
static sl_option_t cmdlnopts[] = {
|
||||||
|
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&G.help), "show this help"},
|
||||||
|
{"string1", NEED_ARG, NULL, 's', arg_string, APTR(&G.sp1), "string one"},
|
||||||
|
{"string2", NEED_ARG, NULL, 'c', arg_string, APTR(&G.sp2), "string two"},
|
||||||
|
{"int1", NEED_ARG, NULL, 'i', arg_int, APTR(&G.ip1), "integer one"},
|
||||||
|
{"int2", NEED_ARG, NULL, 'u', arg_int, APTR(&G.ip2), "integer two"},
|
||||||
|
{"double1", NEED_ARG, NULL, 'd', arg_double, APTR(&G.dp1), "double one"},
|
||||||
|
{"double2", NEED_ARG, NULL, 'o', arg_double, APTR(&G.dp2), "double two"},
|
||||||
|
{"float1", NEED_ARG, NULL, 'f', arg_float, APTR(&G.fp1), "float one"},
|
||||||
|
{"float2", NEED_ARG, NULL, 'l', arg_float, APTR(&G.fp2), "float two"},
|
||||||
|
{"config", NEED_ARG, NULL, 'C', arg_string, APTR(&G.confname),"name of configuration file"},
|
||||||
|
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&G.verbose),"verbose level (each -v adds 1)"},
|
||||||
|
end_option
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv){
|
||||||
|
sl_init();
|
||||||
|
sl_parseargs(&argc, &argv, cmdlnopts);
|
||||||
|
if(G.help) sl_showhelp(-1, cmdlnopts);
|
||||||
|
sl_loglevel_e lvl = G.verbose + LOGLEVEL_ERR;
|
||||||
|
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
||||||
|
printf("verbose level: %d\n", lvl);
|
||||||
|
if(G.sp1){
|
||||||
|
printf("Parsing of string1: ");
|
||||||
|
char key[SL_KEY_LEN], val[SL_VAL_LEN];
|
||||||
|
int k = sl_get_keyval(G.sp1, key, val);
|
||||||
|
switch(k){
|
||||||
|
case 0:
|
||||||
|
red("key not found\n");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
green("got key='%s'\n", key);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
green("got key='%s', value='%s'\n", key, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
green("Starting parameters values:\n");
|
||||||
|
char *buf = sl_print_opts(cmdlnopts, TRUE);
|
||||||
|
printf("%s\n", buf);
|
||||||
|
FREE(buf);
|
||||||
|
if(G.confname){
|
||||||
|
int o = sl_conf_readopts(G.confname, cmdlnopts);
|
||||||
|
if(o > 0){
|
||||||
|
printf("got %d options in '%s'\n", o, G.confname);
|
||||||
|
green("And after reading of conffile:\n");
|
||||||
|
buf = sl_print_opts(cmdlnopts, TRUE);
|
||||||
|
printf("%s\n", buf);
|
||||||
|
FREE(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -23,8 +23,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int main(int argc, char *argv[argc]) {
|
int main(int argc, char *argv[argc]) {
|
||||||
List *f = NULL;
|
sl_list_t *f = NULL;
|
||||||
printf("Available memory: %luMB\n", get_available_mem()/1024/1024);
|
printf("Available memory: %luMB\n", sl_mem_avail()/1024/1024);
|
||||||
//initial_setup(); - there's no need for this function if you don't use locale & don't want to have
|
//initial_setup(); - there's no need for this function if you don't use locale & don't want to have
|
||||||
// specific output in non-tty
|
// specific output in non-tty
|
||||||
if(argc == 1){
|
if(argc == 1){
|
||||||
@ -33,26 +33,26 @@ int main(int argc, char *argv[argc]) {
|
|||||||
}
|
}
|
||||||
red("\n\nLIFO example\n");
|
red("\n\nLIFO example\n");
|
||||||
for(int i = 1; i < argc; ++i){
|
for(int i = 1; i < argc; ++i){
|
||||||
if(!list_push(&f, argv[i])) ERR("Allocation error!");
|
if(!sl_list_push(&f, argv[i])) ERR("Allocation error!");
|
||||||
green("push to list ");
|
green("push to list ");
|
||||||
printf("%s\n", argv[i]);
|
printf("%s\n", argv[i]);
|
||||||
}
|
}
|
||||||
char *d;
|
char *d;
|
||||||
printf("\n");
|
printf("\n");
|
||||||
while(f){
|
while(f){
|
||||||
d = list_pop(&f);
|
d = sl_list_pop(&f);
|
||||||
green("pull: ");
|
green("pull: ");
|
||||||
printf("%s\n", d);
|
printf("%s\n", d);
|
||||||
}
|
}
|
||||||
red("\n\nFIFO example\n");
|
red("\n\nFIFO example\n");
|
||||||
for(int i = 1; i < argc; ++i){
|
for(int i = 1; i < argc; ++i){
|
||||||
if(!list_push_tail(&f, argv[i])) ERR("Allocation error!");
|
if(!sl_list_push_tail(&f, argv[i])) ERR("Allocation error!");
|
||||||
green("push to list ");
|
green("push to list ");
|
||||||
printf("%s\n", argv[i]);
|
printf("%s\n", argv[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
while(f){
|
while(f){
|
||||||
d = list_pop(&f);
|
d = sl_list_pop(&f);
|
||||||
green("pull: ");
|
green("pull: ");
|
||||||
printf("%s\n", d);
|
printf("%s\n", d);
|
||||||
// after last usage we should FREE data, but here it is parameter of main()
|
// after last usage we should FREE data, but here it is parameter of main()
|
||||||
|
|||||||
@ -23,13 +23,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
initial_setup();
|
sl_init();
|
||||||
// setup non-echo non-canonical mode
|
// setup non-echo non-canonical mode
|
||||||
setup_con();
|
sl_setup_con();
|
||||||
green("Press any key...\n");
|
green("Press any key...\n");
|
||||||
char k = mygetchar();
|
char k = sl_getchar();
|
||||||
red("You press %c\n", k);
|
red("You press %c\n", k);
|
||||||
// don't forget to restore @exit!
|
// don't forget to restore @exit!
|
||||||
restore_console();
|
sl_restore_con();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,20 +24,6 @@
|
|||||||
#include <unistd.h> // sleep
|
#include <unistd.h> // sleep
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
|
||||||
#include <termios.h> // tcsetattr
|
|
||||||
#include <unistd.h> // tcsetattr, close, read, write
|
|
||||||
#include <sys/ioctl.h> // ioctl
|
|
||||||
#include <stdio.h> // printf, getchar, fopen, perror
|
|
||||||
#include <stdlib.h> // exit
|
|
||||||
#include <sys/stat.h> // read
|
|
||||||
#include <fcntl.h> // read
|
|
||||||
#include <signal.h> // signal
|
|
||||||
#include <time.h> // time
|
|
||||||
#include <string.h> // memcpy
|
|
||||||
#include <stdint.h> // int types
|
|
||||||
#include <sys/time.h> // gettimeofday
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an example of usage:
|
* This is an example of usage:
|
||||||
* - command line arguments,
|
* - command line arguments,
|
||||||
@ -48,7 +34,7 @@
|
|||||||
* The `cmdlnopts.[hc]` are intrinsic files of this demo.
|
* The `cmdlnopts.[hc]` are intrinsic files of this demo.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static TTY_descr *dev = NULL; // shoul be global to restore if die
|
static sl_tty_t *dev = NULL; // shoul be global to restore if die
|
||||||
static glob_pars *GP = NULL; // for GP->pidfile need in `signals`
|
static glob_pars *GP = NULL; // for GP->pidfile need in `signals`
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,28 +48,26 @@ void signals(int sig){
|
|||||||
LOGERR("Exit with status %d", sig);
|
LOGERR("Exit with status %d", sig);
|
||||||
if(GP && GP->pidfile) // remove unnesessary PID file
|
if(GP && GP->pidfile) // remove unnesessary PID file
|
||||||
unlink(GP->pidfile);
|
unlink(GP->pidfile);
|
||||||
restore_console();
|
sl_restore_con();
|
||||||
if(dev) close_tty(&dev);
|
if(dev) sl_tty_close(&dev);
|
||||||
exit(sig);
|
exit(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iffound_default(pid_t pid){
|
void sl_iffound_deflt(pid_t pid){
|
||||||
ERRX("Another copy of this process found, pid=%d. Exit.", pid);
|
ERRX("Another copy of this process found, pid=%d. Exit.", pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]){
|
||||||
initial_setup();
|
sl_init();
|
||||||
char *self = strdup(argv[0]);
|
|
||||||
GP = parse_args(argc, argv);
|
GP = parse_args(argc, argv);
|
||||||
if(GP->rest_pars_num){
|
if(GP->rest_pars_num){
|
||||||
printf("%d extra options:\n", GP->rest_pars_num);
|
printf("%d extra options:\n", GP->rest_pars_num);
|
||||||
for(int i = 0; i < GP->rest_pars_num; ++i)
|
for(int i = 0; i < GP->rest_pars_num; ++i)
|
||||||
printf("%s\n", GP->rest_pars[i]);
|
printf("%s\n", GP->rest_pars[i]);
|
||||||
}
|
}
|
||||||
check4running(self, GP->pidfile);
|
sl_check4running((char*)__progname, GP->pidfile);
|
||||||
red("%s started, snippets library version is %s\n", self, sl_libversion());
|
red("%s started, snippets library version is %s\n", __progname, sl_libversion());
|
||||||
free(self);
|
sl_setup_con();
|
||||||
setup_con();
|
|
||||||
signal(SIGTERM, signals); // kill (-15) - quit
|
signal(SIGTERM, signals); // kill (-15) - quit
|
||||||
signal(SIGHUP, SIG_IGN); // hup - ignore
|
signal(SIGHUP, SIG_IGN); // hup - ignore
|
||||||
signal(SIGINT, signals); // ctrl+C - quit
|
signal(SIGINT, signals); // ctrl+C - quit
|
||||||
@ -95,10 +79,25 @@ int main(int argc, char *argv[]){
|
|||||||
for(int i = 0; i < GP->rest_pars_num; ++i)
|
for(int i = 0; i < GP->rest_pars_num; ++i)
|
||||||
printf("Extra argument: %s\n", GP->rest_pars[i]);
|
printf("Extra argument: %s\n", GP->rest_pars[i]);
|
||||||
}
|
}
|
||||||
|
if(GP->intarr){
|
||||||
|
int **p = GP->intarr;
|
||||||
|
for(int i = 0; *p; ++i) printf("Integer[%d]: %d\n", i, **p++);
|
||||||
|
}
|
||||||
|
if(GP->dblarr){
|
||||||
|
double **p = GP->dblarr;
|
||||||
|
for(int i = 0; *p; ++i) printf("Double[%d]: %g\n", i, **p++);
|
||||||
|
}
|
||||||
|
if(GP->strarr){
|
||||||
|
char **p = GP->strarr;
|
||||||
|
for(int i = 0; *p; ++i) printf("String[%d]: \"%s\"\n", i, *p++);
|
||||||
|
}
|
||||||
|
if(GP->lo0 != INT_MIN) printf("You set lo0 to %d\n", GP->lo0);
|
||||||
|
if(GP->lo1 != INT_MIN) printf("You set lo1 to %d\n", GP->lo1);
|
||||||
|
if(GP->lo2 != INT_MIN) printf("You set lo2 to %d\n", GP->lo2);
|
||||||
if(GP->device){
|
if(GP->device){
|
||||||
LOGDBG("Try to open serial %s", GP->device);
|
LOGDBG("Try to open serial %s", GP->device);
|
||||||
dev = new_tty(GP->device, GP->speed, 4096);
|
dev = sl_tty_new(GP->device, GP->speed, 4096);
|
||||||
if(dev) dev = tty_open(dev, GP->exclusive);
|
if(dev) dev = sl_tty_open(dev, GP->exclusive);
|
||||||
if(!dev){
|
if(!dev){
|
||||||
LOGERR("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);
|
signals(0);
|
||||||
@ -106,26 +105,26 @@ int main(int argc, char *argv[]){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// main stuff goes here
|
// main stuff goes here
|
||||||
long seed = throw_random_seed();
|
long seed = sl_random_seed();
|
||||||
green("Now I will sleep for 10 seconds after your last input.\n 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");
|
LOGWARN("warning message example");
|
||||||
LOGWARNADD("with next string without timestamp");
|
LOGWARNADD("with next string without timestamp");
|
||||||
double t0 = dtime();
|
double t0 = sl_dtime();
|
||||||
char b[2] = {0};
|
char b[2] = {0};
|
||||||
while(dtime() - t0 < 10.){ // read data from port and print in into terminal
|
while(sl_dtime() - t0 < 10.){ // read data from port and print in into terminal
|
||||||
if(dev){
|
if(dev){
|
||||||
if(read_tty(dev)){
|
if(sl_tty_read(dev)){
|
||||||
printf("Got %zd bytes from port: %s\n", dev->buflen, dev->buf);
|
printf("Got %zd bytes from port: %s\n", dev->buflen, dev->buf);
|
||||||
LOGMSG("Got from serial: %s", dev->buf);
|
LOGMSG("Got from serial: %s", dev->buf);
|
||||||
t0 = dtime();
|
t0 = sl_dtime();
|
||||||
}
|
}
|
||||||
int r = read_console();
|
int r = sl_read_con();
|
||||||
if(r < 1) continue;
|
if(r < 1) continue;
|
||||||
t0 = dtime();
|
t0 = sl_dtime();
|
||||||
b[0] = (char) r;
|
b[0] = (char) r;
|
||||||
printf("send to tty: %d (%c)\n", r, b[0]);
|
printf("send to tty: %d (%c)\n", r, b[0]);
|
||||||
LOGMSG("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);
|
sl_tty_write(dev->comfd, b, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// clean everything
|
// clean everything
|
||||||
|
|||||||
22
fifo_lifo.c
22
fifo_lifo.c
@ -22,15 +22,15 @@
|
|||||||
#include "usefull_macros.h"
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief list_push_tail - push data into the tail of a stack (like FIFO)
|
* @brief sl_list_push_tail - push data into the tail of a stack (like FIFO)
|
||||||
* @param lst (io) - list
|
* @param lst (io) - list
|
||||||
* @param v (i) - data to push
|
* @param v (i) - data to push
|
||||||
* @return pointer to just pused node or NULL in case of error
|
* @return pointer to just pused node or NULL in case of error
|
||||||
*/
|
*/
|
||||||
List *list_push_tail(List **lst, void *v){
|
sl_list_t *sl_list_push_tail(sl_list_t **lst, void *v){
|
||||||
List *node;
|
sl_list_t *node;
|
||||||
if(!lst) return NULL;
|
if(!lst) return NULL;
|
||||||
if((node = MALLOC(List, 1)) == NULL)
|
if((node = MALLOC(sl_list_t, 1)) == NULL)
|
||||||
return NULL; // allocation error
|
return NULL; // allocation error
|
||||||
node->data = v; // insert data
|
node->data = v; // insert data
|
||||||
if(!*lst){
|
if(!*lst){
|
||||||
@ -43,15 +43,15 @@ List *list_push_tail(List **lst, void *v){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief list_push - push data into the head of a stack (like LIFO)
|
* @brief sl_list_push - push data into the head of a stack (like LIFO)
|
||||||
* @param lst (io) - list
|
* @param lst (io) - list
|
||||||
* @param v (i) - data to push
|
* @param v (i) - data to push
|
||||||
* @return pointer to just pused node
|
* @return pointer to just pused node
|
||||||
*/
|
*/
|
||||||
List *list_push(List **lst, void *v){
|
sl_list_t *sl_list_push(sl_list_t **lst, void *v){
|
||||||
List *node;
|
sl_list_t *node;
|
||||||
if(!lst) return NULL;
|
if(!lst) return NULL;
|
||||||
if((node = MALLOC(List, 1)) == NULL)
|
if((node = MALLOC(sl_list_t, 1)) == NULL)
|
||||||
return NULL; // allocation error
|
return NULL; // allocation error
|
||||||
node->data = v; // insert data
|
node->data = v; // insert data
|
||||||
if(!*lst){
|
if(!*lst){
|
||||||
@ -66,13 +66,13 @@ List *list_push(List **lst, void *v){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief list_pop - get data from head of list. Don't forget to FREE list data after `pop`
|
* @brief sl_list_pop - get data from head of list. Don't forget to FREE list data after `pop`
|
||||||
* @param lst (io) - list
|
* @param lst (io) - list
|
||||||
* @return data from lst head
|
* @return data from lst head
|
||||||
*/
|
*/
|
||||||
void *list_pop(List **lst){
|
void *sl_list_pop(sl_list_t **lst){
|
||||||
void *ret;
|
void *ret;
|
||||||
List *node = *lst;
|
sl_list_t *node = *lst;
|
||||||
if(!lst || !*lst) return NULL;
|
if(!lst || !*lst) return NULL;
|
||||||
ret = (*lst)->data;
|
ret = (*lst)->data;
|
||||||
*lst = (*lst)->next;
|
*lst = (*lst)->next;
|
||||||
|
|||||||
Binary file not shown.
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-12-24 12:22+0300\n"
|
"POT-Creation-Date: 2024-11-15 11:38+0300\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -17,8 +17,36 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=koi8-r\n"
|
"Content-Type: text/plain; charset=koi8-r\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#. / \nОбнаружен одноименный процесс (pid=%d), выход.\n
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:225
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:70
|
msgid "Unsupported option type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:228
|
||||||
|
#, c-format
|
||||||
|
msgid "Wrong number format '%s'"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:272
|
||||||
|
#, c-format
|
||||||
|
msgid "Can't open %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:283
|
||||||
|
#, c-format
|
||||||
|
msgid "Wrong key: '%s'"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:289
|
||||||
|
#, c-format
|
||||||
|
msgid "Key '%s' need value"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:295
|
||||||
|
#, c-format
|
||||||
|
msgid "Key '%s' have no argptr!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:69
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
@ -26,154 +54,137 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. error reading self name
|
#. error reading self name
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:118
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:117
|
||||||
msgid "Can't read self name"
|
msgid "Can't read self name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу открыть PID файл
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:141
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:143
|
|
||||||
msgid "Can't open PID file"
|
msgid "Can't open PID file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. amount of pcount and/or scount wrong
|
#. amount of pcount and/or scount wrong
|
||||||
#. / Неправильный формат строки помощи
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:53
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:54
|
|
||||||
msgid "Wrong helpstring!"
|
msgid "Wrong helpstring!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Целое вне допустимого диапазона
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:82
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:84
|
|
||||||
msgid "Integer out of range"
|
msgid "Integer out of range"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / "Не могу использовать несколько параметров без аргументов!"
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:166
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:151
|
|
||||||
msgid "Can't use multiple args with arg_none!"
|
msgid "Can't use multiple args with arg_none!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:252
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:267
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "double long arguments: --%s"
|
msgid "double long arguments: --%s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:258
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:273
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "double short arguments: -%c"
|
msgid "double short arguments: -%c"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Неправильный параметр: %s
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:332
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:470
|
#, c-format
|
||||||
|
msgid "Need argument with %s type\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:486
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong parameter: %s"
|
msgid "Wrong parameter: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / %s: необходим аргумент!
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:490
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:475
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: need argument!"
|
msgid "%s: need argument!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Неправильный аргумент \"%s\" параметра \"%s\"
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:494
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:480
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong argument \"%s\" of parameter \"%s\""
|
msgid "Wrong argument \"%s\" of parameter \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:92
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:87
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong speed value: %d!"
|
msgid "Wrong USART format \"%s\"; use NPS, where N: 5..8; P: N/E/O/1/0, S: 1/2"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу использовать порт %s
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:102
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:105
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't use port %s"
|
msgid "Can't use port %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Get settings
|
#. Get settings
|
||||||
#. / Не могу получить действующие настройки порта
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:106
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:110
|
|
||||||
msgid "Can't get old TTY settings"
|
msgid "Can't get old TTY settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу сменить настройки порта
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:119
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:121
|
|
||||||
msgid "Can't apply new TTY settings"
|
msgid "Can't apply new TTY settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу сделать порт эксклюзивным
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:124
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:128
|
#, c-format
|
||||||
|
msgid "Can't set speed %d, got ispeed=%d, ospeed=%d"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:130
|
||||||
msgid "Can't do exclusive open"
|
msgid "Can't do exclusive open"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Отсутствует имя порта
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:162
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:164
|
|
||||||
msgid "Port name is missing"
|
msgid "Port name is missing"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:170
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:168
|
||||||
msgid "Need non-zero buffer for TTY device"
|
msgid "Need non-zero buffer for TTY device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу открыть /dev/random
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:194
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:185
|
|
||||||
msgid "Can't open /dev/random"
|
msgid "Can't open /dev/random"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу прочесть /dev/random
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:198
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:190
|
|
||||||
msgid "Can't read /dev/random"
|
msgid "Can't read /dev/random"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не задано имя файла!
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:248
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:241
|
|
||||||
msgid "No filename given!"
|
msgid "No filename given!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу открыть %s для чтения
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:252
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:246
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't open %s for reading"
|
msgid "Can't open %s for reading"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу выполнить stat %s
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:256
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:251
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't stat %s"
|
msgid "Can't stat %s"
|
||||||
msgstr ""
|
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:258
|
|
||||||
msgid "Mmap error for input"
|
msgid "Mmap error for input"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу закрыть mmap'нутый файл
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:266
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:263
|
|
||||||
msgid "Can't close mmap'ed file"
|
msgid "Can't close mmap'ed file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу munmap
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:279
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:277
|
|
||||||
msgid "Can't munmap"
|
msgid "Can't munmap"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу настроить консоль
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:347
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:308
|
|
||||||
msgid "Can't setup console"
|
msgid "Can't setup console"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не задано имя логфайла
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:403
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:383
|
|
||||||
msgid "Need filename for log file"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / Пробую открыть логфайл %s в режиме дополнения\n
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:387
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Try to open log file %s in append mode\n"
|
msgid "Wrong double number format '%s'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / Не могу открыть логфайл
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:416
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:391
|
#, c-format
|
||||||
msgid "Can't open log file"
|
msgid "Wrong integer number format '%s'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
155
locale/ru/ru.po
155
locale/ru/ru.po
@ -7,7 +7,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-12-24 12:22+0300\n"
|
"POT-Creation-Date: 2024-11-15 11:38+0300\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -16,164 +16,177 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
|||||||
"Content-Type: text/plain; charset=koi8-r\n"
|
"Content-Type: text/plain; charset=koi8-r\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#. / \nОбнаружен одноименный процесс (pid=%d), выход.\n
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:69
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:70
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "\n"
|
msgid "\n"
|
||||||
"Found running process (pid=%d), exit.\n"
|
"Found running process (pid=%d), exit.\n"
|
||||||
msgstr "\n"
|
msgstr "\n"
|
||||||
"ïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n"
|
"ïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n"
|
||||||
|
|
||||||
#. / %s: необходим аргумент!
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:490
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:475
|
#, c-format
|
||||||
#, fuzzy, c-format
|
|
||||||
msgid "%s: need argument!"
|
msgid "%s: need argument!"
|
||||||
msgstr "%s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ!"
|
msgstr "%s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ!"
|
||||||
|
|
||||||
#. / Не могу сменить настройки порта
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:119
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:121
|
|
||||||
msgid "Can't apply new TTY settings"
|
msgid "Can't apply new TTY settings"
|
||||||
msgstr "îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ"
|
msgstr "îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ"
|
||||||
|
|
||||||
#. / Не могу закрыть mmap'нутый файл
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:266
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:263
|
|
||||||
msgid "Can't close mmap'ed file"
|
msgid "Can't close mmap'ed file"
|
||||||
msgstr "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
|
msgstr "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
|
||||||
|
|
||||||
#. / Не могу сделать порт эксклюзивным
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:130
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:128
|
|
||||||
msgid "Can't do exclusive open"
|
msgid "Can't do exclusive open"
|
||||||
msgstr "îÅ ÍÏÇÕ ÐÅÒÅ×ÅÓÔÉ ÐÏÒÔ × ÜËÓËÌÀÚÉ×ÎÙÊ ÒÅÖÉÍ"
|
msgstr "îÅ ÍÏÇÕ ÐÅÒÅ×ÅÓÔÉ ÐÏÒÔ × ÜËÓËÌÀÚÉ×ÎÙÊ ÒÅÖÉÍ"
|
||||||
|
|
||||||
#. Get settings
|
#. Get settings
|
||||||
#. / Не могу получить действующие настройки порта
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:106
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:110
|
|
||||||
msgid "Can't get old TTY settings"
|
msgid "Can't get old TTY settings"
|
||||||
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÄÅÊÓÔ×ÕÀÝÉÅ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ"
|
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÄÅÊÓÔ×ÕÀÝÉÅ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ"
|
||||||
|
|
||||||
#. / Не могу munmap
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:279
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:277
|
|
||||||
msgid "Can't munmap"
|
msgid "Can't munmap"
|
||||||
msgstr "îÅ ÍÏÇÕ munmap"
|
msgstr "îÅ ÍÏÇÕ munmap"
|
||||||
|
|
||||||
#. / Не могу открыть %s для чтения
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:272
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:246
|
#, c-format
|
||||||
|
msgid "Can't open %s"
|
||||||
|
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:252
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't open %s for reading"
|
msgid "Can't open %s for reading"
|
||||||
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ"
|
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ"
|
||||||
|
|
||||||
#. / Не могу открыть /dev/random
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:194
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:185
|
|
||||||
msgid "Can't open /dev/random"
|
msgid "Can't open /dev/random"
|
||||||
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ /dev/random"
|
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ /dev/random"
|
||||||
|
|
||||||
#. / Не могу открыть PID файл
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:141
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:143
|
|
||||||
msgid "Can't open PID file"
|
msgid "Can't open PID file"
|
||||||
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ PID ÆÁÊÌ"
|
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ PID ÆÁÊÌ"
|
||||||
|
|
||||||
#. / Не могу открыть логфайл
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:198
|
||||||
#: /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:190
|
|
||||||
msgid "Can't read /dev/random"
|
msgid "Can't read /dev/random"
|
||||||
msgstr "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ /dev/random"
|
msgstr "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ /dev/random"
|
||||||
|
|
||||||
#. error reading self name
|
#. error reading self name
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:118
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:117
|
||||||
#, fuzzy
|
|
||||||
msgid "Can't read self name"
|
msgid "Can't read self name"
|
||||||
msgstr "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ ÉÍÑ ÐÒÏÃÅÓÓÁ"
|
msgstr "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ ÉÍÑ ÐÒÏÃÅÓÓÁ"
|
||||||
|
|
||||||
#. / Не могу настроить консоль
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:124
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:308
|
#, c-format
|
||||||
|
msgid "Can't set speed %d, got ispeed=%d, ospeed=%d"
|
||||||
|
msgstr "îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÓËÏÒÏÓÔØ ÎÁ %d; ispeed=%d, ospeed=%d"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:347
|
||||||
msgid "Can't setup console"
|
msgid "Can't setup console"
|
||||||
msgstr "îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ"
|
msgstr "îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ"
|
||||||
|
|
||||||
#. / Не могу выполнить stat %s
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:256
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:251
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't stat %s"
|
msgid "Can't stat %s"
|
||||||
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat %s"
|
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat %s"
|
||||||
|
|
||||||
#. / "Не могу использовать несколько параметров без аргументов!"
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:166
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:151
|
|
||||||
msgid "Can't use multiple args with arg_none!"
|
msgid "Can't use multiple args with arg_none!"
|
||||||
msgstr "íÁÓÓÉ× ÐÁÒÁÍÅÔÒÏ× ÎÅ ÍÏÖÅÔ ÉÍÅÔØ ÔÉÐ arg_none!"
|
msgstr "íÁÓÓÉ× ÐÁÒÁÍÅÔÒÏ× ÎÅ ÍÏÖÅÔ ÉÍÅÔØ ÔÉÐ arg_none!"
|
||||||
|
|
||||||
#. / Не могу использовать порт %s
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:102
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:105
|
#, c-format
|
||||||
#, fuzzy, c-format
|
|
||||||
msgid "Can't use port %s"
|
msgid "Can't use port %s"
|
||||||
msgstr "îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÒÔ %s"
|
msgstr "îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÒÔ %s"
|
||||||
|
|
||||||
#. / Целое вне допустимого диапазона
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:82
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:84
|
|
||||||
msgid "Integer out of range"
|
msgid "Integer out of range"
|
||||||
msgstr "ãÅÌÏÅ ×ÎÅ ÄÏÐÕÓÔÉÍÏÇÏ ÄÉÁÐÁÚÏÎÁ"
|
msgstr "ãÅÌÏÅ ×ÎÅ ÄÏÐÕÓÔÉÍÏÇÏ ÄÉÁÐÁÚÏÎÁ"
|
||||||
|
|
||||||
#. / Ошибка mmap
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:295
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:258
|
#, c-format
|
||||||
|
msgid "Key '%s' have no argptr!"
|
||||||
|
msgstr "õ ËÌÀÞÁ '%s' ÎÅÔ ÕËÁÚÁÔÅÌÑ ÎÁ ÐÅÒÅÍÅÎÎÕÀ!"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:289
|
||||||
|
#, c-format
|
||||||
|
msgid "Key '%s' need value"
|
||||||
|
msgstr "ëÌÀÞ '%s' ÔÒÅÂÕÅÔ ÚÎÁÞÅÎÉÑ"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:262
|
||||||
msgid "Mmap error for input"
|
msgid "Mmap error for input"
|
||||||
msgstr "ïÛÉÂËÁ mmap"
|
msgstr "ïÛÉÂËÁ mmap"
|
||||||
|
|
||||||
#. / Не задано имя логфайла
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:332
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:383
|
#, c-format
|
||||||
msgid "Need filename for log file"
|
msgid "Need argument with %s type\n"
|
||||||
msgstr "Не задано имя логфайла"
|
msgstr "îÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ Ó ÔÉÐÏÍ %s\n"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:170
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:168
|
||||||
msgid "Need non-zero buffer for TTY device"
|
msgid "Need non-zero buffer for TTY device"
|
||||||
msgstr "äÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÕÓÔÒÏÊÓÔ×Á ÔÒÅÂÕÅÔÓÑ ÂÕÆÅÒ ÎÅÎÕÌÅ×ÏÇÏ ÒÁÚÍÅÒÁ"
|
msgstr "äÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÕÓÔÒÏÊÓÔ×Á ÔÒÅÂÕÅÔÓÑ ÂÕÆÅÒ ÎÅÎÕÌÅ×ÏÇÏ ÒÁÚÍÅÒÁ"
|
||||||
|
|
||||||
#. / Не задано имя файла!
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:248
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:241
|
|
||||||
msgid "No filename given!"
|
msgid "No filename given!"
|
||||||
msgstr "îÅ ÚÁÄÁÎÏ ÉÍÑ ÆÁÊÌÁ!"
|
msgstr "îÅ ÚÁÄÁÎÏ ÉÍÑ ÆÁÊÌÁ!"
|
||||||
|
|
||||||
#. / Отсутствует имя порта
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:162
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:164
|
|
||||||
msgid "Port name is missing"
|
msgid "Port name is missing"
|
||||||
msgstr "ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ"
|
msgstr "ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ"
|
||||||
|
|
||||||
#. / Пробую открыть логфайл %s в режиме дополнения\n
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:225
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:387
|
msgid "Unsupported option type"
|
||||||
#, c-format
|
msgstr "îÅÐÏÄÄÅÒÖÉ×ÁÅÍÙÊ ÔÉÐ ÏÐÃÉÉ"
|
||||||
msgid "Try to open log file %s in append mode\n"
|
|
||||||
msgstr "Пробую открыть логфайл %s в режиме дополнения\n"
|
|
||||||
|
|
||||||
#. / Неправильный аргумент \"%s\" параметра \"%s\"
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:87
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:480
|
#, c-format
|
||||||
|
msgid "Wrong USART format \"%s\"; use NPS, where N: 5..8; P: N/E/O/1/0, S: "
|
||||||
|
"1/2"
|
||||||
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ USART \"%s\"; ÎÕÖÅÎ NPS, ÇÄÅ N: 5..8; P: N/E/"
|
||||||
|
"O/1/0, S: 1/2"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:494
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong argument \"%s\" of parameter \"%s\""
|
msgid "Wrong argument \"%s\" of parameter \"%s\""
|
||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\""
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:403
|
||||||
|
#, c-format
|
||||||
|
msgid "Wrong double number format '%s'"
|
||||||
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ double: %s"
|
||||||
|
|
||||||
#. amount of pcount and/or scount wrong
|
#. amount of pcount and/or scount wrong
|
||||||
#. / Неправильный формат строки помощи
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:53
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:54
|
|
||||||
msgid "Wrong helpstring!"
|
msgid "Wrong helpstring!"
|
||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ"
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ"
|
||||||
|
|
||||||
#. / Неправильный параметр: %s
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:416
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:470
|
#, c-format
|
||||||
|
msgid "Wrong integer number format '%s'"
|
||||||
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÃÅÌÏÇÏ: %s"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:283
|
||||||
|
#, c-format
|
||||||
|
msgid "Wrong key: '%s'"
|
||||||
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ËÌÀÞ: %s"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:228
|
||||||
|
#, c-format
|
||||||
|
msgid "Wrong number format '%s'"
|
||||||
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÞÉÓÌÁ: %s"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:486
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong parameter: %s"
|
msgid "Wrong parameter: %s"
|
||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s"
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term.c:92
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:267
|
||||||
#, c-format
|
|
||||||
msgid "Wrong speed value: %d!"
|
|
||||||
msgstr "Неправильное значение скорости: %d!"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:252
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "double long arguments: --%s"
|
msgid "double long arguments: --%s"
|
||||||
msgstr "ÄÕÂÌÉÒÕÀÝÉÊÓÑ ÄÌÉÎÎÙÊ ÐÁÒÁÍÅÔÒ: --%s"
|
msgstr "ÄÕÂÌÉÒÕÀÝÉÊÓÑ ÄÌÉÎÎÙÊ ÐÁÒÁÍÅÔÒ: --%s"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:258
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:273
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "double short arguments: -%c"
|
msgid "double short arguments: -%c"
|
||||||
msgstr "ÄÕÂÌÉÒÕÀÝÉÊÓÑ ËÏÒÏÔËÉÊ ÐÁÒÁÍÅÔÒ: -%c"
|
msgstr "ÄÕÂÌÉÒÕÀÝÉÊÓÑ ËÏÒÏÔËÉÊ ÐÁÒÁÍÅÔÒ: -%c"
|
||||||
|
|
||||||
|
|||||||
124
parseargs.c
124
parseargs.c
@ -33,10 +33,10 @@
|
|||||||
char *helpstring = "%s\n";
|
char *helpstring = "%s\n";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief change_helpstring - change standard help header
|
* @brief sl_helpstring - change standard help header
|
||||||
* @param str (i) - new format (MAY consist ONE "%s" for progname)
|
* @param str (i) - new format (MAY consist ONE "%s" for progname)
|
||||||
*/
|
*/
|
||||||
void change_helpstring(char *s){
|
void sl_helpstring(char *s){
|
||||||
int pcount = 0, scount = 0;
|
int pcount = 0, scount = 0;
|
||||||
char *str = s;
|
char *str = s;
|
||||||
// check `helpstring` and set it to default in case of error
|
// check `helpstring` and set it to default in case of error
|
||||||
@ -63,7 +63,7 @@ void change_helpstring(char *s){
|
|||||||
* @param t (i) - T_INT for integer or T_LLONG for long long (if argtype would be wided, may add more)
|
* @param t (i) - T_INT for integer or T_LLONG for long long (if argtype would be wided, may add more)
|
||||||
* @return TRUE if conversion done without errors, FALSE otherwise
|
* @return TRUE if conversion done without errors, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
static bool myatoll(void *num, char *str, argtype t){
|
static int myatoll(void *num, char *str, sl_argtype_e t){
|
||||||
long long tmp, *llptr;
|
long long tmp, *llptr;
|
||||||
int *iptr;
|
int *iptr;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
@ -92,7 +92,7 @@ static bool myatoll(void *num, char *str, argtype t){
|
|||||||
|
|
||||||
// the same as myatoll but for double
|
// the same as myatoll but for double
|
||||||
// There's no NAN & INF checking here (what if they would be needed?)
|
// There's no NAN & INF checking here (what if they would be needed?)
|
||||||
static bool myatod(void *num, const char *str, argtype t){
|
static int myatod(void *num, const char *str, sl_argtype_e t){
|
||||||
double tmp, *dptr;
|
double tmp, *dptr;
|
||||||
float *fptr;
|
float *fptr;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
@ -114,21 +114,39 @@ static bool myatod(void *num, const char *str, argtype t){
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get_optind - get index of current option in array options
|
* @brief get_optind - get index of current option in array options
|
||||||
* @param opt (i) - returning val of getopt_long
|
* @param opt (i) - returning val of getopt_long
|
||||||
* @param options (i) - array of options
|
* @param options (i) - array of options
|
||||||
* @return index in array
|
* @return index in array
|
||||||
*/
|
*/
|
||||||
static int get_optind(int opt, myoption *options){
|
static int get_optind(int opt, sl_option_t *options){
|
||||||
int oind;
|
int oind;
|
||||||
myoption *opts = options;
|
sl_option_t *opts = options;
|
||||||
assert(opts);
|
assert(opts);
|
||||||
for(oind = 0; opts->name && opts->val != opt; oind++, opts++);
|
for(oind = 0; opts->name && opts->val != opt; oind++, opts++){
|
||||||
|
DBG("cmp %c and %c", opt, opts->val);
|
||||||
|
}
|
||||||
if(!opts->name || opts->val != opt) // no such parameter
|
if(!opts->name || opts->val != opt) // no such parameter
|
||||||
showhelp(-1, options);
|
sl_showhelp(-1, options);
|
||||||
return oind;
|
return oind;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
static int get_optindl(struct option *opt, sl_option_t *options){
|
||||||
|
int oind;
|
||||||
|
sl_option_t *opts = options;
|
||||||
|
assert(opts);
|
||||||
|
for(oind = 0; opts->name; ){
|
||||||
|
DBG("cmp '%s' and '%s'", opt->name, opts->name);
|
||||||
|
if(0 == strcmp(opt->name, opts->name)) break;
|
||||||
|
oind++, opts++;
|
||||||
|
}
|
||||||
|
if(!opts->name || strcmp(opt->name, opts->name)) // no such parameter
|
||||||
|
sl_showhelp(-1, options);
|
||||||
|
return oind;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get_aptr - reallocate new value in array of multiple repeating arguments
|
* @brief get_aptr - reallocate new value in array of multiple repeating arguments
|
||||||
@ -136,7 +154,7 @@ static int get_optind(int opt, myoption *options){
|
|||||||
* @arg type - its type (for realloc)
|
* @arg type - its type (for realloc)
|
||||||
* @return pointer to new (next) value
|
* @return pointer to new (next) value
|
||||||
*/
|
*/
|
||||||
void *get_aptr(void *paptr, argtype type){
|
void *get_aptr(void *paptr, sl_argtype_e type){
|
||||||
int i = 1;
|
int i = 1;
|
||||||
void **aptr = *((void***)paptr);
|
void **aptr = *((void***)paptr);
|
||||||
if(aptr){ // there's something in array
|
if(aptr){ // there's something in array
|
||||||
@ -181,7 +199,7 @@ void *get_aptr(void *paptr, argtype type){
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief parseargs - parse command line arguments
|
* @brief sl_parseargs - parse command line arguments
|
||||||
* ! If arg is string, then value will be strdup'ed!
|
* ! If arg is string, then value will be strdup'ed!
|
||||||
*
|
*
|
||||||
* @param argc (io) - address of argc of main(), return value of argc stay after `getopt`
|
* @param argc (io) - address of argc of main(), return value of argc stay after `getopt`
|
||||||
@ -192,11 +210,11 @@ void *get_aptr(void *paptr, argtype type){
|
|||||||
*
|
*
|
||||||
* @exit: in case of error this function show help & make `exit(-1)`
|
* @exit: in case of error this function show help & make `exit(-1)`
|
||||||
*/
|
*/
|
||||||
void parseargs(int *argc, char ***argv, myoption *options){
|
void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
|
||||||
char *short_options, *soptr;
|
char *short_options, *soptr;
|
||||||
struct option *long_options, *loptr;
|
struct option *long_options, *loptr;
|
||||||
size_t optsize, i;
|
size_t optsize, i;
|
||||||
myoption *opts = options;
|
sl_option_t *opts = options;
|
||||||
// check whether there is at least one options
|
// check whether there is at least one options
|
||||||
assert(opts);
|
assert(opts);
|
||||||
assert(opts[0].name);
|
assert(opts[0].name);
|
||||||
@ -263,31 +281,45 @@ void parseargs(int *argc, char ***argv, myoption *options){
|
|||||||
// now we have both long_options & short_options and can parse `getopt_long`
|
// now we have both long_options & short_options and can parse `getopt_long`
|
||||||
while(1){
|
while(1){
|
||||||
int opt;
|
int opt;
|
||||||
int oindex = 0, optind = 0; // oindex - number of option in argv, optind - number in options[]
|
int /*oindex = -1,*/ optind = -1; // oindex - number of option in long_options, optind - number in options[]
|
||||||
if((opt = getopt_long(*argc, *argv, short_options, long_options, &oindex)) == -1) break;
|
if((opt = getopt_long(*argc, *argv, short_options, long_options, &optind)) == -1) break;
|
||||||
if(opt == '?'){
|
DBG("%c(%d) = getopt_long(argc, argv, %s, long_options, &%d); optopt=%c(%d), errno=%d", opt, opt, short_options, optind, optopt, optopt, errno);
|
||||||
opt = optopt;
|
if(optind < 0 ) optind = get_optind(opt, options); // find short option -> need to know index of long
|
||||||
optind = get_optind(opt, options);
|
// be careful with "-?" flag: all wrong or ambiguous flags will be interpreted as this!
|
||||||
|
/*
|
||||||
|
if(opt == '?'){ // real '?', wrong option or no argument when need
|
||||||
|
opt = optopt; // original short opt or 0 for wrong or long
|
||||||
|
if(opt == 0){ // '?' or wrong long
|
||||||
|
// there's no way to understand difference between real '-?' and unknown long flag
|
||||||
|
DBG("'?' or unknown parameter");
|
||||||
|
sl_showhelp(-1, options);
|
||||||
|
}else optind = get_optind(opt, options);
|
||||||
|
DBG("optind = %d", optind);
|
||||||
if(options[optind].has_arg == NEED_ARG || options[optind].has_arg == MULT_PAR)
|
if(options[optind].has_arg == NEED_ARG || options[optind].has_arg == MULT_PAR)
|
||||||
showhelp(optind, options); // need argument
|
sl_showhelp(optind, options); // need argument
|
||||||
}
|
}else{
|
||||||
else{
|
// we should call functions get_optind / get_optindl for options where there's no long analog
|
||||||
if(opt == 0 || oindex > 0) optind = oindex;
|
if(opt < ' ') optind = get_optindl(&long_options[oindex], options);
|
||||||
else optind = get_optind(opt, options);
|
else optind = get_optind(opt, options);
|
||||||
}
|
}
|
||||||
|
if(optind < 0) sl_showhelp(-1, options); // wrong argument
|
||||||
|
*/
|
||||||
|
DBG("index=%d", optind);
|
||||||
opts = &options[optind];
|
opts = &options[optind];
|
||||||
// if(opt == 0 && opts->has_arg == NO_ARGS) continue; // only long option changing integer flag
|
DBG("Got option %s", opts->name);
|
||||||
|
|
||||||
// now check option
|
// now check option
|
||||||
if(opts->has_arg == NEED_ARG || opts->has_arg == MULT_PAR)
|
if(opts->has_arg == NEED_ARG || opts->has_arg == MULT_PAR)
|
||||||
if(!optarg) showhelp(optind, options); // need argument
|
if(!optarg) sl_showhelp(optind, options); // need argument
|
||||||
void *aptr;
|
void *aptr;
|
||||||
if(opts->has_arg == MULT_PAR){
|
if(opts->has_arg == MULT_PAR){
|
||||||
aptr = get_aptr(opts->argptr, opts->type);
|
aptr = get_aptr(opts->argptr, opts->type);
|
||||||
}else
|
}else
|
||||||
aptr = opts->argptr;
|
aptr = opts->argptr;
|
||||||
bool result = TRUE;
|
int result = TRUE;
|
||||||
// even if there is no argument, but argptr != NULL, think that optarg = "1"
|
// even if there is no argument, but argptr != NULL, think that optarg = "1"
|
||||||
if(!optarg) optarg = "1";
|
if(!optarg) optarg = "1";
|
||||||
|
const char *type = NULL;
|
||||||
switch(opts->type){
|
switch(opts->type){
|
||||||
default:
|
default:
|
||||||
case arg_none:
|
case arg_none:
|
||||||
@ -295,25 +327,31 @@ void parseargs(int *argc, char ***argv, myoption *options){
|
|||||||
break;
|
break;
|
||||||
case arg_int:
|
case arg_int:
|
||||||
result = myatoll(aptr, optarg, arg_int);
|
result = myatoll(aptr, optarg, arg_int);
|
||||||
|
type = _("integer");
|
||||||
break;
|
break;
|
||||||
case arg_longlong:
|
case arg_longlong:
|
||||||
result = myatoll(aptr, optarg, arg_longlong);
|
result = myatoll(aptr, optarg, arg_longlong);
|
||||||
|
type = _("long long");
|
||||||
break;
|
break;
|
||||||
case arg_double:
|
case arg_double:
|
||||||
result = myatod(aptr, optarg, arg_double);
|
result = myatod(aptr, optarg, arg_double);
|
||||||
|
type = _("double");
|
||||||
break;
|
break;
|
||||||
case arg_float:
|
case arg_float:
|
||||||
result = myatod(aptr, optarg, arg_float);
|
result = myatod(aptr, optarg, arg_float);
|
||||||
|
type = _("float");
|
||||||
break;
|
break;
|
||||||
case arg_string:
|
case arg_string:
|
||||||
result = (*((void**)aptr) = (void*)strdup(optarg));
|
result = (*((void**)aptr) = (void*)strdup(optarg)) != NULL;
|
||||||
|
type = _("string");
|
||||||
break;
|
break;
|
||||||
case arg_function:
|
case arg_function:
|
||||||
result = ((argfn)aptr)(optarg);
|
result = ((sl_argfn_t)aptr)(optarg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!result){
|
if(!result){
|
||||||
showhelp(optind, options);
|
if(type) fprintf(stderr, _("Need argument with %s type\n"), type);
|
||||||
|
sl_showhelp(optind, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*argc -= optind;
|
*argc -= optind;
|
||||||
@ -325,7 +363,7 @@ void parseargs(int *argc, char ***argv, myoption *options){
|
|||||||
* first - sort by short options; second - sort arguments without sort opts (by long options)
|
* first - sort by short options; second - sort arguments without sort opts (by long options)
|
||||||
*/
|
*/
|
||||||
static int argsort(const void *a1, const void *a2){
|
static int argsort(const void *a1, const void *a2){
|
||||||
const myoption *o1 = (myoption*)a1, *o2 = (myoption*)a2;
|
const sl_option_t *o1 = (sl_option_t*)a1, *o2 = (sl_option_t*)a2;
|
||||||
const char *l1 = o1->name, *l2 = o2->name;
|
const char *l1 = o1->name, *l2 = o2->name;
|
||||||
int s1 = o1->val, s2 = o2->val;
|
int s1 = o1->val, s2 = o2->val;
|
||||||
int *f1 = o1->flag, *f2 = o2->flag;
|
int *f1 = o1->flag, *f2 = o2->flag;
|
||||||
@ -341,17 +379,17 @@ static int argsort(const void *a1, const void *a2){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief showhelp - show help information based on myoption->help values
|
* @brief sl_showhelp - show help information based on sl_option_t->help values
|
||||||
* @param oindex (i) - if non-negative, show only help by myoption[oindex].help
|
* @param oindex (i) - if non-negative, show only help by sl_option_t[oindex].help
|
||||||
* @param options (i) - array of `myoption`
|
* @param options (i) - array of `sl_option_t`
|
||||||
*
|
*
|
||||||
* @exit: run `exit(-1)` !!!
|
* @exit: run `exit(-1)` !!!
|
||||||
*/
|
*/
|
||||||
void showhelp(int oindex, myoption *options){
|
void sl_showhelp(int oindex, sl_option_t *options){
|
||||||
int max_opt_len = 0; // max len of options substring - for right indentation
|
int max_opt_len = 0; // max len of options substring - for right indentation
|
||||||
const int bufsz = 255;
|
const int bufsz = 255;
|
||||||
char buf[bufsz+1];
|
char buf[bufsz+1];
|
||||||
myoption *opts = options;
|
sl_option_t *opts = options;
|
||||||
assert(opts);
|
assert(opts);
|
||||||
assert(opts[0].name); // check whether there is at least one options
|
assert(opts[0].name); // check whether there is at least one options
|
||||||
if(oindex > -1){ // print only one message
|
if(oindex > -1){ // print only one message
|
||||||
@ -383,7 +421,7 @@ void showhelp(int oindex, myoption *options){
|
|||||||
if(N == 0) exit(-2);
|
if(N == 0) exit(-2);
|
||||||
// Now print all help (sorted)
|
// Now print all help (sorted)
|
||||||
opts = options;
|
opts = options;
|
||||||
qsort(opts, N, sizeof(myoption), argsort);
|
qsort(opts, N, sizeof(sl_option_t), argsort);
|
||||||
do{
|
do{
|
||||||
int p = sprintf(buf, " "); // a little indent
|
int p = sprintf(buf, " "); // a little indent
|
||||||
if(!opts->flag && opts->val) // .val is short argument
|
if(!opts->flag && opts->val) // .val is short argument
|
||||||
@ -402,13 +440,13 @@ void showhelp(int oindex, myoption *options){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get_suboption - get suboptions from parameter string
|
* @brief sl_get_suboption - get suboptions from parameter string
|
||||||
* @param str - parameter string
|
* @param str - parameter string
|
||||||
* @param opt - pointer to suboptions structure
|
* @param opt - pointer to suboptions structure
|
||||||
* @return TRUE if all OK
|
* @return TRUE if all OK
|
||||||
*/
|
*/
|
||||||
bool get_suboption(char *str, mysuboption *opt){
|
int sl_get_suboption(char *str, sl_suboption_t *opt){
|
||||||
int findsubopt(char *par, mysuboption *so){
|
int findsubopt(char *par, sl_suboption_t *so){
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
if(!par) return -1;
|
if(!par) return -1;
|
||||||
while(so[idx].name){
|
while(so[idx].name){
|
||||||
@ -417,9 +455,9 @@ bool get_suboption(char *str, mysuboption *opt){
|
|||||||
}
|
}
|
||||||
return -1; // badarg
|
return -1; // badarg
|
||||||
}
|
}
|
||||||
bool opt_setarg(mysuboption *so, int idx, char *val){
|
int opt_setarg(sl_suboption_t *so, int idx, char *val){
|
||||||
mysuboption *soptr = &so[idx];
|
sl_suboption_t *soptr = &so[idx];
|
||||||
bool result = FALSE;
|
int result = FALSE;
|
||||||
void *aptr = soptr->argptr;
|
void *aptr = soptr->argptr;
|
||||||
switch(soptr->type){
|
switch(soptr->type){
|
||||||
default:
|
default:
|
||||||
@ -440,16 +478,16 @@ bool get_suboption(char *str, mysuboption *opt){
|
|||||||
result = myatod(aptr, val, arg_float);
|
result = myatod(aptr, val, arg_float);
|
||||||
break;
|
break;
|
||||||
case arg_string:
|
case arg_string:
|
||||||
result = (*((void**)aptr) = (void*)strdup(val));
|
result = (*((void**)aptr) = (void*)strdup(val)) != NULL;
|
||||||
break;
|
break;
|
||||||
case arg_function:
|
case arg_function:
|
||||||
result = ((argfn)aptr)(val);
|
result = ((sl_argfn_t)aptr)(val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
char *tok;
|
char *tok;
|
||||||
bool ret = FALSE;
|
int ret = FALSE;
|
||||||
char *tmpbuf;
|
char *tmpbuf;
|
||||||
tok = strtok_r(str, ":,", &tmpbuf);
|
tok = strtok_r(str, ":,", &tmpbuf);
|
||||||
do{
|
do{
|
||||||
|
|||||||
50
term.c
50
term.c
@ -1,11 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* client.c - simple terminal client
|
* This file is part of the Snippets project.
|
||||||
|
* Copyright 2013 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
*
|
*
|
||||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
* This program is free software: you can redistribute it and/or modify
|
||||||
*
|
|
||||||
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
@ -14,10 +13,9 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
||||||
* MA 02110-1301, USA.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h> // tcsetattr, close, read, write
|
#include <unistd.h> // tcsetattr, close, read, write
|
||||||
#include <sys/ioctl.h> // ioctl
|
#include <sys/ioctl.h> // ioctl
|
||||||
#include <stdio.h> // printf, getchar, fopen, perror
|
#include <stdio.h> // printf, getchar, fopen, perror
|
||||||
@ -39,7 +37,7 @@ typedef struct {
|
|||||||
tcflag_t bspeed; // baudrate from termios.h
|
tcflag_t bspeed; // baudrate from termios.h
|
||||||
} spdtbl;
|
} spdtbl;
|
||||||
|
|
||||||
static int tty_init(TTY_descr *descr);
|
static int tty_init(sl_tty_t *descr);
|
||||||
|
|
||||||
static spdtbl speeds[] = {
|
static spdtbl speeds[] = {
|
||||||
{50, B50},
|
{50, B50},
|
||||||
@ -76,11 +74,11 @@ static spdtbl speeds[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief conv_spd - test if `speed` is in .speed of `speeds` array
|
* @brief sl_tty_convspd - test if `speed` is in .speed of `speeds` array
|
||||||
* @param speed - integer speed (bps)
|
* @param speed - integer speed (bps)
|
||||||
* @return 0 if error, Bxxx if all OK
|
* @return 0 if error, Bxxx if all OK
|
||||||
*/
|
*/
|
||||||
tcflag_t conv_spd(int speed){
|
tcflag_t sl_tty_convspd(int speed){
|
||||||
spdtbl *spd = speeds;
|
spdtbl *spd = speeds;
|
||||||
int curspeed = 0;
|
int curspeed = 0;
|
||||||
do{
|
do{
|
||||||
@ -98,7 +96,7 @@ tcflag_t conv_spd(int speed){
|
|||||||
* @param descr (io) - port descriptor
|
* @param descr (io) - port descriptor
|
||||||
* @return 0 if all OK or error code
|
* @return 0 if all OK or error code
|
||||||
*/
|
*/
|
||||||
static int tty_init(TTY_descr *descr){
|
static int tty_init(sl_tty_t *descr){
|
||||||
// |O_NONBLOCK ?
|
// |O_NONBLOCK ?
|
||||||
if ((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){
|
if ((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){
|
||||||
/// 钆 拖钦 捎邢特谙琢载 邢以 %s
|
/// 钆 拖钦 捎邢特谙琢载 邢以 %s
|
||||||
@ -134,9 +132,9 @@ static int tty_init(TTY_descr *descr){
|
|||||||
/**
|
/**
|
||||||
* @brief restore_tty - restore opened TTY to previous state and close it
|
* @brief restore_tty - restore opened TTY to previous state and close it
|
||||||
*/
|
*/
|
||||||
void close_tty(TTY_descr **descr){
|
void sl_tty_close(sl_tty_t **descr){
|
||||||
if(descr == NULL || *descr == NULL) return;
|
if(descr == NULL || *descr == NULL) return;
|
||||||
TTY_descr *d = *descr;
|
sl_tty_t *d = *descr;
|
||||||
if(d->comfd){
|
if(d->comfd){
|
||||||
ioctl(d->comfd, TCSANOW, &d->oldtty); // return TTY to previous state
|
ioctl(d->comfd, TCSANOW, &d->oldtty); // return TTY to previous state
|
||||||
close(d->comfd);
|
close(d->comfd);
|
||||||
@ -147,16 +145,16 @@ void close_tty(TTY_descr **descr){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief new_tty - create new TTY structure with partially filled fields
|
* @brief sl_tty_new - create new TTY structure with partially filled fields
|
||||||
* @param comdev - TTY device filename
|
* @param comdev - TTY device filename
|
||||||
* @param speed - speed (number)
|
* @param speed - speed (number)
|
||||||
* @param bufsz - size of buffer for input data (or 0 if opened only to write)
|
* @param bufsz - size of buffer for input data (or 0 if opened only to write)
|
||||||
* @return pointer to TTY structure if all OK
|
* @return pointer to TTY structure if all OK
|
||||||
*/
|
*/
|
||||||
TTY_descr *new_tty(char *comdev, int speed, size_t bufsz){
|
sl_tty_t *sl_tty_new(char *comdev, int speed, size_t bufsz){
|
||||||
tcflag_t spd = conv_spd(speed);
|
tcflag_t spd = sl_tty_convspd(speed);
|
||||||
if(!spd) return NULL;
|
if(!spd) return NULL;
|
||||||
TTY_descr *descr = MALLOC(TTY_descr, 1);
|
sl_tty_t *descr = MALLOC(sl_tty_t, 1);
|
||||||
descr->portname = strdup(comdev);
|
descr->portname = strdup(comdev);
|
||||||
descr->baudrate = spd;
|
descr->baudrate = spd;
|
||||||
descr->speed = speed;
|
descr->speed = speed;
|
||||||
@ -176,12 +174,12 @@ TTY_descr *new_tty(char *comdev, int speed, size_t bufsz){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief tty_open - init & open tty device
|
* @brief sl_tty_open - init & open tty device
|
||||||
* @param d - already filled structure (with new_tty or by hands)
|
* @param d - already filled structure (with new_tty or by hands)
|
||||||
* @param exclusive - == 1 to make exclusive open
|
* @param exclusive - == 1 to make exclusive open
|
||||||
* @return pointer to TTY structure if all OK
|
* @return pointer to TTY structure if all OK
|
||||||
*/
|
*/
|
||||||
TTY_descr *tty_open(TTY_descr *d, int exclusive){
|
sl_tty_t *sl_tty_open(sl_tty_t *d, int exclusive){
|
||||||
if(!d || !d->portname || !d->baudrate) return NULL;
|
if(!d || !d->portname || !d->baudrate) return NULL;
|
||||||
if(exclusive) d->exclusive = TRUE;
|
if(exclusive) d->exclusive = TRUE;
|
||||||
else d->exclusive = FALSE;
|
else d->exclusive = FALSE;
|
||||||
@ -191,11 +189,11 @@ TTY_descr *tty_open(TTY_descr *d, int exclusive){
|
|||||||
|
|
||||||
static struct timeval tvdefault = {.tv_sec = 0, .tv_usec = 5000};
|
static struct timeval tvdefault = {.tv_sec = 0, .tv_usec = 5000};
|
||||||
/**
|
/**
|
||||||
* @brief tty_timeout - set timeout for select() on reading
|
* @brief sl_tty_tmout - set timeout for select() on reading
|
||||||
* @param usec - microseconds of timeout
|
* @param usec - microseconds of timeout
|
||||||
* @return -1 if usec < 0, 0 if all OK
|
* @return -1 if usec < 0, 0 if all OK
|
||||||
*/
|
*/
|
||||||
int tty_timeout(double usec){
|
int sl_tty_tmout(double usec){
|
||||||
if(usec < 0.) return -1;
|
if(usec < 0.) return -1;
|
||||||
tvdefault.tv_sec = 0;
|
tvdefault.tv_sec = 0;
|
||||||
if(usec > 999999){
|
if(usec > 999999){
|
||||||
@ -207,12 +205,12 @@ int tty_timeout(double usec){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief read_tty - read data from TTY with 10ms timeout
|
* @brief sl_tty_read - read data from TTY with 10ms timeout
|
||||||
* @param buff (o) - buffer for data read
|
* @param buff (o) - buffer for data read
|
||||||
* @param length - buffer len
|
* @param length - buffer len
|
||||||
* @return amount of bytes read or -1 if disconnected
|
* @return amount of bytes read or -1 if disconnected
|
||||||
*/
|
*/
|
||||||
int read_tty(TTY_descr *d){
|
int sl_tty_read(sl_tty_t *d){
|
||||||
if(!d || d->comfd < 0) return 0;
|
if(!d || d->comfd < 0) return 0;
|
||||||
size_t L = 0;
|
size_t L = 0;
|
||||||
ssize_t l;
|
ssize_t l;
|
||||||
@ -246,12 +244,12 @@ int read_tty(TTY_descr *d){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief write_tty - write data to serial port
|
* @brief sl_tty_write - write data to serial port
|
||||||
* @param buff (i) - data to write
|
* @param buff (i) - data to write
|
||||||
* @param length - its length
|
* @param length - its length
|
||||||
* @return 0 if all OK
|
* @return 0 if all OK
|
||||||
*/
|
*/
|
||||||
int write_tty(int comfd, const char *buff, size_t length){
|
int sl_tty_write(int comfd, const char *buff, size_t length){
|
||||||
ssize_t L = write(comfd, buff, length);
|
ssize_t L = write(comfd, buff, length);
|
||||||
if((size_t)L != length){
|
if((size_t)L != length){
|
||||||
/// "镗陕肆 诹猩由!"
|
/// "镗陕肆 诹猩由!"
|
||||||
|
|||||||
264
term2.c
Normal file
264
term2.c
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Snippets project.
|
||||||
|
* Copyright 2024 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h> // tcsetattr, close, read, write
|
||||||
|
#include <fcntl.h> // read
|
||||||
|
#include <stdio.h> // printf, getchar, fopen, perror
|
||||||
|
#include <stdlib.h> // exit, realloc
|
||||||
|
#include <string.h> // memcpy
|
||||||
|
#include <sys/ioctl.h> // ioctl
|
||||||
|
#include <sys/stat.h> // read
|
||||||
|
#include <sys/time.h> // gettimeofday
|
||||||
|
#include <time.h> // time
|
||||||
|
#include <unistd.h> // usleep, tcsetattr, close, read, write
|
||||||
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
|
#define LOGBUFSZ (1024)
|
||||||
|
|
||||||
|
// return FALSE if failed
|
||||||
|
static int parse_format(const char *iformat, tcflag_t *flags){
|
||||||
|
tcflag_t f = 0;
|
||||||
|
if(!iformat){ // default
|
||||||
|
if(flags) *flags = CS8;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if(strlen(iformat) != 3) goto someerr;
|
||||||
|
switch(iformat[0]){
|
||||||
|
case '5':
|
||||||
|
f |= CS5;
|
||||||
|
break;
|
||||||
|
case '6':
|
||||||
|
f |= CS6;
|
||||||
|
break;
|
||||||
|
case '7':
|
||||||
|
f |= CS7;
|
||||||
|
break;
|
||||||
|
case '8':
|
||||||
|
f |= CS8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto someerr;
|
||||||
|
}
|
||||||
|
switch(iformat[1]){
|
||||||
|
case '0': // always 0
|
||||||
|
f |= PARENB | CMSPAR;
|
||||||
|
break;
|
||||||
|
case '1': // always 1
|
||||||
|
f |= PARENB | CMSPAR | PARODD;
|
||||||
|
break;
|
||||||
|
case 'E': // even
|
||||||
|
f |= PARENB;
|
||||||
|
break;
|
||||||
|
case 'N': // none
|
||||||
|
break;
|
||||||
|
case 'O': // odd
|
||||||
|
f |= PARENB | PARODD;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto someerr;
|
||||||
|
}
|
||||||
|
switch(iformat[2]){
|
||||||
|
case '1':
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
f |= CSTOPB;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto someerr;
|
||||||
|
}
|
||||||
|
if(flags) *flags = f;
|
||||||
|
return TRUE;
|
||||||
|
someerr:
|
||||||
|
WARNX(_("Wrong USART format \"%s\"; use NPS, where N: 5..8; P: N/E/O/1/0, S: 1/2"), iformat);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief tty_init - open & setup terminal
|
||||||
|
* @param descr (io) - port descriptor
|
||||||
|
* !!! default settings are "8N1".
|
||||||
|
* !!! If you want other, set it like `descr->format = "7O2"` between `sl_tty_new` and `sl_tty_open`
|
||||||
|
* @return 0 if all OK, last error code or 1
|
||||||
|
*/
|
||||||
|
static int tty_init(sl_tty_t *descr){
|
||||||
|
tcflag_t flags;
|
||||||
|
if(!parse_format(descr->format, &flags)) return 1;
|
||||||
|
if((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){
|
||||||
|
/// îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÒÔ %s
|
||||||
|
WARN(_("Can't use port %s"), descr->portname);
|
||||||
|
return globErr ? globErr : 1;
|
||||||
|
}
|
||||||
|
if(ioctl(descr->comfd, TCGETS2, &descr->oldtty)){ // Get settings
|
||||||
|
/// îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÄÅÊÓÔ×ÕÀÝÉÅ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ
|
||||||
|
WARN(_("Can't get old TTY settings"));
|
||||||
|
return globErr ? globErr : 1;
|
||||||
|
}
|
||||||
|
descr->tty = descr->oldtty;
|
||||||
|
descr->tty.c_lflag = 0; // ~(ICANON | ECHO | ECHOE | ISIG)
|
||||||
|
descr->tty.c_iflag = 0; // don't do any changes in input stream
|
||||||
|
descr->tty.c_oflag = 0; // don't do any changes in output stream
|
||||||
|
descr->tty.c_cflag = BOTHER | flags | CREAD | CLOCAL; // other speed, user format, RW, ignore line ctrl
|
||||||
|
descr->tty.c_ispeed = descr->speed;
|
||||||
|
descr->tty.c_ospeed = descr->speed;
|
||||||
|
descr->tty.c_cc[VMIN] = 0; // non-canonical mode
|
||||||
|
descr->tty.c_cc[VTIME] = 5;
|
||||||
|
if(ioctl(descr->comfd, TCSETS2, &descr->tty)){
|
||||||
|
/// îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ
|
||||||
|
WARN(_("Can't apply new TTY settings"));
|
||||||
|
return globErr ? globErr : 1;
|
||||||
|
}
|
||||||
|
ioctl(descr->comfd, TCGETS2, &descr->tty);
|
||||||
|
if(descr->tty.c_ispeed != (speed_t)descr->speed || descr->tty.c_ospeed != (speed_t)descr->speed){
|
||||||
|
WARN(_("Can't set speed %d, got ispeed=%d, ospeed=%d"), descr->speed, descr->tty.c_ispeed, descr->tty.c_ospeed);
|
||||||
|
descr->speed = descr->tty.c_ispeed;
|
||||||
|
}
|
||||||
|
// make exclusive open
|
||||||
|
if(descr->exclusive){
|
||||||
|
if(ioctl(descr->comfd, TIOCEXCL)){
|
||||||
|
/// îÅ ÍÏÇÕ ÓÄÅÌÁÔØ ÐÏÒÔ ÜËÓËÌÀÚÉ×ÎÙÍ
|
||||||
|
WARN(_("Can't do exclusive open"));
|
||||||
|
}}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief restore_tty - restore opened TTY to previous state and close it
|
||||||
|
*/
|
||||||
|
void sl_tty_close(sl_tty_t **descr){
|
||||||
|
if(descr == NULL || *descr == NULL) return;
|
||||||
|
sl_tty_t *d = *descr;
|
||||||
|
if(d->comfd){
|
||||||
|
ioctl(d->comfd, TCSETS2, &d->oldtty); // return TTY to previous state
|
||||||
|
close(d->comfd);
|
||||||
|
}
|
||||||
|
FREE(d->portname);
|
||||||
|
FREE(d->buf);
|
||||||
|
FREE(*descr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_tty_new - create new TTY structure with partially filled fields
|
||||||
|
* @param comdev - TTY device filename
|
||||||
|
* @param speed - speed (number)
|
||||||
|
* @param bufsz - size of buffer for input data (or 0 if opened only to write)
|
||||||
|
* @return pointer to TTY structure if all OK
|
||||||
|
*/
|
||||||
|
sl_tty_t *sl_tty_new(char *comdev, int speed, size_t bufsz){
|
||||||
|
sl_tty_t *descr = MALLOC(sl_tty_t, 1);
|
||||||
|
descr->portname = strdup(comdev);
|
||||||
|
descr->speed = speed;
|
||||||
|
if(!descr->portname){
|
||||||
|
/// ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ
|
||||||
|
WARNX(_("Port name is missing"));
|
||||||
|
}else{
|
||||||
|
if(bufsz){
|
||||||
|
descr->buf = MALLOC(char, bufsz+1);
|
||||||
|
descr->bufsz = bufsz;
|
||||||
|
return descr;
|
||||||
|
}else WARNX(_("Need non-zero buffer for TTY device"));
|
||||||
|
}
|
||||||
|
FREE(descr->portname);
|
||||||
|
FREE(descr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_tty_open - init & open tty device
|
||||||
|
* @param d - already filled structure (with new_tty or by hands)
|
||||||
|
* @param exclusive - == 1 to make exclusive open
|
||||||
|
* @return pointer to TTY structure if all OK
|
||||||
|
*/
|
||||||
|
sl_tty_t *sl_tty_open(sl_tty_t *d, int exclusive){
|
||||||
|
if(!d || !d->portname) return NULL;
|
||||||
|
if(exclusive) d->exclusive = TRUE;
|
||||||
|
else d->exclusive = FALSE;
|
||||||
|
if(tty_init(d)) return NULL;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timeval tvdefault = {.tv_sec = 0, .tv_usec = 5000};
|
||||||
|
/**
|
||||||
|
* @brief sl_tty_tmout - set timeout for select() on reading
|
||||||
|
* @param usec - microseconds of timeout
|
||||||
|
* @return -1 if usec < 0, 0 if all OK
|
||||||
|
*/
|
||||||
|
int sl_tty_tmout(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 sl_tty_read - read data from TTY with 10ms timeout
|
||||||
|
* @param buff (o) - buffer for data read
|
||||||
|
* @param length - buffer len
|
||||||
|
* @return amount of bytes read or -1 if disconnected
|
||||||
|
*/
|
||||||
|
int sl_tty_read(sl_tty_t *d){
|
||||||
|
if(!d || d->comfd < 0) return 0;
|
||||||
|
size_t L = 0;
|
||||||
|
ssize_t l;
|
||||||
|
size_t length = d->bufsz;
|
||||||
|
char *ptr = d->buf;
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
int retval;
|
||||||
|
do{
|
||||||
|
l = 0;
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(d->comfd, &rfds);
|
||||||
|
//memcpy(&tv, &tvdefault, sizeof(struct timeval));
|
||||||
|
tv = tvdefault;
|
||||||
|
retval = select(d->comfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
if(!retval) break;
|
||||||
|
if(retval < 0){
|
||||||
|
if(errno == EINTR) continue;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(FD_ISSET(d->comfd, &rfds)){
|
||||||
|
l = read(d->comfd, ptr, length);
|
||||||
|
if(l < 1) return -1; // disconnected
|
||||||
|
ptr += l; L += l;
|
||||||
|
length -= l;
|
||||||
|
}
|
||||||
|
}while(l && length);
|
||||||
|
d->buflen = L;
|
||||||
|
d->buf[L] = 0;
|
||||||
|
return (size_t)L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_tty_write - write data to serial port
|
||||||
|
* @param buff (i) - data to write
|
||||||
|
* @param length - its length
|
||||||
|
* @return 0 if all OK
|
||||||
|
*/
|
||||||
|
int sl_tty_write(int comfd, const char *buff, size_t length){
|
||||||
|
ssize_t L = write(comfd, buff, length);
|
||||||
|
if((size_t)L != length){
|
||||||
|
/// "ïÛÉÂËÁ ÚÁÐÉÓÉ!"
|
||||||
|
WARN("Write error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
224
usefull_macros.c
224
usefull_macros.c
@ -18,23 +18,25 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/stat.h>
|
#include <ctype.h> // isspace
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <locale.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/file.h> // flock
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <linux/limits.h> // PATH_MAX
|
#include <linux/limits.h> // PATH_MAX
|
||||||
|
#include <locale.h>
|
||||||
#include <math.h> // floor
|
#include <math.h> // floor
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/file.h> // flock
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "usefull_macros.h"
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
@ -56,10 +58,10 @@ const char *sl_libversion(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief dtime - function for different purposes that need to know time intervals
|
* @brief sl_dtime - function for different purposes that need to know time intervals
|
||||||
* @return double value: UNIX time in seconds
|
* @return double value: UNIX time in seconds
|
||||||
*/
|
*/
|
||||||
double dtime(){
|
double sl_dtime(){
|
||||||
double t;
|
double t;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
@ -77,7 +79,7 @@ int globErr = 0; // errno for WARN/ERR
|
|||||||
* @param fmt ... - printf-like format
|
* @param fmt ... - printf-like format
|
||||||
* @return number of printed symbols
|
* @return number of printed symbols
|
||||||
*/
|
*/
|
||||||
int r_pr_(const char *fmt, ...){
|
static int r_pr_(const char *fmt, ...){
|
||||||
va_list ar; int i;
|
va_list ar; int i;
|
||||||
printf(COLOR_RED);
|
printf(COLOR_RED);
|
||||||
va_start(ar, fmt);
|
va_start(ar, fmt);
|
||||||
@ -86,7 +88,7 @@ int r_pr_(const char *fmt, ...){
|
|||||||
printf(COLOR_OLD);
|
printf(COLOR_OLD);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
int g_pr_(const char *fmt, ...){
|
static int g_pr_(const char *fmt, ...){
|
||||||
va_list ar; int i;
|
va_list ar; int i;
|
||||||
printf(COLOR_GREEN);
|
printf(COLOR_GREEN);
|
||||||
va_start(ar, fmt);
|
va_start(ar, fmt);
|
||||||
@ -101,7 +103,7 @@ int g_pr_(const char *fmt, ...){
|
|||||||
* @param fmt ... - printf-like format
|
* @param fmt ... - printf-like format
|
||||||
* @return number of printed symbols
|
* @return number of printed symbols
|
||||||
*/
|
*/
|
||||||
int r_WARN(const char *fmt, ...){
|
static int r_WARN(const char *fmt, ...){
|
||||||
va_list ar; int i = 1;
|
va_list ar; int i = 1;
|
||||||
fprintf(stderr, COLOR_RED);
|
fprintf(stderr, COLOR_RED);
|
||||||
va_start(ar, fmt);
|
va_start(ar, fmt);
|
||||||
@ -128,7 +130,7 @@ static const char stars[] = "****************************************";
|
|||||||
* @param fmt ... - printf-like format
|
* @param fmt ... - printf-like format
|
||||||
* @return number of printed symbols
|
* @return number of printed symbols
|
||||||
*/
|
*/
|
||||||
int s_WARN(const char *fmt, ...){
|
static int s_WARN(const char *fmt, ...){
|
||||||
va_list ar; int i;
|
va_list ar; int i;
|
||||||
i = fprintf(stderr, "\n%s\n", stars);
|
i = fprintf(stderr, "\n%s\n", stars);
|
||||||
va_start(ar, fmt);
|
va_start(ar, fmt);
|
||||||
@ -143,7 +145,7 @@ int s_WARN(const char *fmt, ...){
|
|||||||
i += fprintf(stderr, "\n");
|
i += fprintf(stderr, "\n");
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
int r_pr_notty(const char *fmt, ...){
|
static int r_pr_notty(const char *fmt, ...){
|
||||||
va_list ar; int i;
|
va_list ar; int i;
|
||||||
i = printf("\n%s\n", stars);
|
i = printf("\n%s\n", stars);
|
||||||
va_start(ar, fmt);
|
va_start(ar, fmt);
|
||||||
@ -154,10 +156,10 @@ int r_pr_notty(const char *fmt, ...){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief initial_setup - setup locale & console
|
* @brief sl_init - setup locale & console
|
||||||
* Run this function in the beginning of main() to setup locale & coloured output
|
* Run this function in the beginning of main() to setup locale & coloured output
|
||||||
*/
|
*/
|
||||||
void initial_setup(){
|
void sl_init(){
|
||||||
// setup coloured output
|
// setup coloured output
|
||||||
if(isatty(STDOUT_FILENO)){ // make color output in tty
|
if(isatty(STDOUT_FILENO)){ // make color output in tty
|
||||||
red = r_pr_; green = g_pr_;
|
red = r_pr_; green = g_pr_;
|
||||||
@ -180,10 +182,10 @@ void initial_setup(){
|
|||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief throw_random_seed - Generate a quasy-random number to initialize PRNG
|
* @brief sl_random_seed - Generate a quasy-random number to initialize PRNG
|
||||||
* @return value for srand48
|
* @return value for srand48
|
||||||
*/
|
*/
|
||||||
long throw_random_seed(){
|
long sl_random_seed(){
|
||||||
long r_ini;
|
long r_ini;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
int fd = open("/dev/random", O_RDONLY);
|
int fd = open("/dev/random", O_RDONLY);
|
||||||
@ -201,7 +203,7 @@ long throw_random_seed(){
|
|||||||
close(fd);
|
close(fd);
|
||||||
}while(0);
|
}while(0);
|
||||||
if(fail){
|
if(fail){
|
||||||
double tt = dtime() * 1e6;
|
double tt = sl_dtime() * 1e6;
|
||||||
double mx = (double)LONG_MAX;
|
double mx = (double)LONG_MAX;
|
||||||
r_ini = (long)(tt - mx * floor(tt/mx));
|
r_ini = (long)(tt - mx * floor(tt/mx));
|
||||||
}
|
}
|
||||||
@ -209,10 +211,10 @@ long throw_random_seed(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get_available_mem
|
* @brief sl_mem_avail
|
||||||
* @return system available physical memory
|
* @return system available physical memory
|
||||||
*/
|
*/
|
||||||
uint64_t get_available_mem(){
|
uint64_t sl_mem_avail(){
|
||||||
return sysconf(_SC_AVPHYS_PAGES) * (uint64_t) sysconf(_SC_PAGE_SIZE);
|
return sysconf(_SC_AVPHYS_PAGES) * (uint64_t) sysconf(_SC_PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,12 +224,12 @@ uint64_t get_available_mem(){
|
|||||||
* Memory
|
* Memory
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
/**
|
/**
|
||||||
* @brief my_alloc - safe memory allocation for macro ALLOC
|
* @brief sl_alloc - safe memory allocation for macro ALLOC
|
||||||
* @param N - number of elements to allocate
|
* @param N - number of elements to allocate
|
||||||
* @param S - size of single element (typically sizeof)
|
* @param S - size of single element (typically sizeof)
|
||||||
* @return pointer to allocated memory area
|
* @return pointer to allocated memory area
|
||||||
*/
|
*/
|
||||||
void *my_alloc(size_t N, size_t S){
|
void *sl_alloc(size_t N, size_t S){
|
||||||
void *p = calloc(N, S);
|
void *p = calloc(N, S);
|
||||||
if(!p) ERR("malloc");
|
if(!p) ERR("malloc");
|
||||||
//assert(p);
|
//assert(p);
|
||||||
@ -235,11 +237,11 @@ void *my_alloc(size_t N, size_t S){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief My_mmap - mmap file to a memory area
|
* @brief sl_mmap - mmap file to a memory area
|
||||||
* @param filename (i) - name of file to mmap
|
* @param filename (i) - name of file to mmap
|
||||||
* @return stuct with mmap'ed file or die
|
* @return stuct with mmap'ed file or die
|
||||||
*/
|
*/
|
||||||
mmapbuf *My_mmap(char *filename){
|
sl_mmapbuf_t *sl_mmap(char *filename){
|
||||||
int fd;
|
int fd;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
size_t Mlen;
|
size_t Mlen;
|
||||||
@ -269,17 +271,17 @@ mmapbuf *My_mmap(char *filename){
|
|||||||
}
|
}
|
||||||
/// îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ
|
/// îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ
|
||||||
if(close(fd)) WARN(_("Can't close mmap'ed file"));
|
if(close(fd)) WARN(_("Can't close mmap'ed file"));
|
||||||
mmapbuf *ret = MALLOC(mmapbuf, 1);
|
sl_mmapbuf_t *ret = MALLOC(sl_mmapbuf_t, 1);
|
||||||
ret->data = ptr;
|
ret->data = ptr;
|
||||||
ret->len = Mlen;
|
ret->len = Mlen;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief My_munmap - unmap memory file
|
* @brief sl_munmap - unmap memory file
|
||||||
* @param b (i) - mmap'ed buffer
|
* @param b (i) - mmap'ed buffer
|
||||||
*/
|
*/
|
||||||
void My_munmap(mmapbuf *b){
|
void sl_munmap(sl_mmapbuf_t *b){
|
||||||
if(munmap(b->data, b->len)){
|
if(munmap(b->data, b->len)){
|
||||||
/// îÅ ÍÏÇÕ munmap
|
/// îÅ ÍÏÇÕ munmap
|
||||||
ERR(_("Can't munmap"));
|
ERR(_("Can't munmap"));
|
||||||
@ -287,44 +289,86 @@ void My_munmap(mmapbuf *b){
|
|||||||
FREE(b);
|
FREE(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_omitspaces - omit leading spaces
|
||||||
|
* @param v - source string
|
||||||
|
* @return pointer to first non-blank character (could be '\0' if end of string reached)
|
||||||
|
*/
|
||||||
|
char *sl_omitspaces(const char *v){
|
||||||
|
if(!v) return NULL;
|
||||||
|
char *p = (char*)v;
|
||||||
|
while(*p && isspace(*p)) ++p;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the same as sl_omitspaces, but return (last non-space char + 1) in string or its first char
|
||||||
|
char *sl_omitspacesr(const char *v){
|
||||||
|
if(!v) return NULL;
|
||||||
|
char *eol = (char*)v + strlen(v) - 1;
|
||||||
|
while(eol > v && isspace(*eol)) --eol;
|
||||||
|
if(eol == v && isspace(*eol)) return eol;
|
||||||
|
return eol + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
* Terminal in no-echo mode
|
* Terminal in no-echo mode
|
||||||
* BE CAREFULL! These functions aren't thread-safe!
|
* BE CAREFULL! These functions aren't thread-safe!
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
static struct termios oldt, newt; // console flags
|
// console flags
|
||||||
|
#ifndef SL_USE_OLD_TTY
|
||||||
|
static struct termios2 oldt, newt;
|
||||||
|
#else
|
||||||
|
static struct termios oldt, newt;
|
||||||
|
#endif
|
||||||
static int console_changed = 0;
|
static int console_changed = 0;
|
||||||
/**
|
/**
|
||||||
* @brief restore_console - restore console to default mode
|
* @brief sl_restore_con - restore console to default mode
|
||||||
*/
|
*/
|
||||||
void restore_console(){
|
void sl_restore_con(){
|
||||||
if(console_changed)
|
if(console_changed)
|
||||||
|
#ifndef SL_USE_OLD_TTY
|
||||||
|
ioctl(STDIN_FILENO, TCSETS2, &oldt);
|
||||||
|
#else
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // return terminal to previous state
|
tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // return terminal to previous state
|
||||||
|
#endif
|
||||||
console_changed = 0;
|
console_changed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief setup_con - setup console to non-canonical noecho mode
|
* @brief sl_setup_con - setup console to non-canonical noecho mode
|
||||||
*/
|
*/
|
||||||
void setup_con(){
|
void sl_setup_con(){
|
||||||
if(console_changed) return;
|
if(console_changed) return;
|
||||||
|
#ifndef SL_USE_OLD_TTY
|
||||||
|
ioctl(STDIN_FILENO, TCGETS2, &oldt);
|
||||||
|
#else
|
||||||
tcgetattr(STDIN_FILENO, &oldt);
|
tcgetattr(STDIN_FILENO, &oldt);
|
||||||
|
#endif
|
||||||
newt = oldt;
|
newt = oldt;
|
||||||
newt.c_lflag &= ~(ICANON | ECHO);
|
newt.c_lflag &= ~(ICANON | ECHO);
|
||||||
|
#ifndef SL_USE_OLD_TTY
|
||||||
|
if(ioctl(STDIN_FILENO, TCSETS2, &newt)){
|
||||||
|
#else
|
||||||
if(tcsetattr(STDIN_FILENO, TCSANOW, &newt) < 0){
|
if(tcsetattr(STDIN_FILENO, TCSANOW, &newt) < 0){
|
||||||
|
#endif
|
||||||
/// îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ
|
/// îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ
|
||||||
WARN(_("Can't setup console"));
|
WARN(_("Can't setup console"));
|
||||||
|
#ifndef SL_USE_OLD_TTY
|
||||||
|
ioctl(STDIN_FILENO, TCSETS2, &oldt);
|
||||||
|
#else
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||||
|
#endif
|
||||||
signals(1); //quit?
|
signals(1); //quit?
|
||||||
}
|
}
|
||||||
console_changed = 1;
|
console_changed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief read_console - read character from console without echo
|
* @brief sl_read_con - read character from console without echo
|
||||||
* @return char read or zero
|
* @return char read or zero
|
||||||
*/
|
*/
|
||||||
int read_console(){
|
int sl_read_con(){
|
||||||
int rb;
|
int rb;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int retval;
|
int retval;
|
||||||
@ -346,102 +390,58 @@ int read_console(){
|
|||||||
* wait until at least one character pressed
|
* wait until at least one character pressed
|
||||||
* @return character read
|
* @return character read
|
||||||
*/
|
*/
|
||||||
int mygetchar(){
|
int sl_getchar(){
|
||||||
int ret;
|
int ret;
|
||||||
do ret = read_console();
|
do ret = sl_read_con();
|
||||||
while(ret == 0);
|
while(ret == 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief str2double - safely convert data from string to double
|
* @brief sl_str2d - safely convert data from string to double
|
||||||
* @param num (o) - double number read from string
|
* @param num (o) - double number read from string
|
||||||
* @param str (i) - input string
|
* @param str (i) - input string
|
||||||
* @return 1 if success, 0 if fails
|
* @return 1 if success, 0 if fails
|
||||||
*/
|
*/
|
||||||
int str2double(double *num, const char *str){
|
int sl_str2d(double *num, const char *str){
|
||||||
double res;
|
double res;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
if(!str) return 0;
|
if(!str) return FALSE;
|
||||||
res = strtod(str, &endptr);
|
res = strtod(str, &endptr);
|
||||||
if(endptr == str || *str == '\0' || *endptr != '\0'){
|
if(endptr == str || *str == '\0' || *endptr != '\0'){
|
||||||
/// "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÞÉÓÌÁ double!"
|
/// "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÞÉÓÌÁ double '%s'"
|
||||||
WARNX("Wrong double number format!");
|
WARNX(_("Wrong double number format '%s'"), str);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(num) *num = res; // you may run it like myatod(NULL, str) to test wether str is double number
|
if(num) *num = res; // you may run it like myatod(NULL, str) to test wether str is double number
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
// and so on
|
||||||
/******************************************************************************\
|
int sl_str2ll(long long *num, const char *str){
|
||||||
* Logging to file
|
long long res;
|
||||||
* DEPRECATED!!! DEPRECATED!!! DEPRECATED!!! DEPRECATED!!! DEPRECATED!!! DEPRECATED!!!
|
char *endptr;
|
||||||
\******************************************************************************/
|
if(!str) return FALSE;
|
||||||
FILE *Flog = NULL; // log file descriptor
|
res = strtoll(str, &endptr, 0);
|
||||||
char *logname = NULL;
|
if(endptr == str || *str == '\0' || *endptr != '\0'){
|
||||||
time_t log_open_time = 0;
|
/// "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÞÉÓÌÁ double!"
|
||||||
/**
|
WARNX(_("Wrong number format!"));
|
||||||
* @brief openlogfile - try to open log file
|
return FALSE;
|
||||||
* @param name (i) - log file name
|
|
||||||
* if failed show warning message
|
|
||||||
*/
|
|
||||||
void openlogfile(char *name){
|
|
||||||
if(!name){
|
|
||||||
/// îÅ ÚÁÄÁÎÏ ÉÍÑ ÌÏÇÆÁÊÌÁ
|
|
||||||
WARNX(_("Need filename for log file"));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
/// ðÒÏÂÕÀ ÏÔËÒÙÔØ ÌÏÇÆÁÊÌ %s × ÒÅÖÉÍÅ ÄÏÐÏÌÎÅÎÉÑ\n
|
if(num) *num = res;
|
||||||
green(_("Try to open log file %s in append mode\n"), name);
|
return TRUE;
|
||||||
fflush(stdout);
|
|
||||||
if(!(Flog = fopen(name, "a"))){
|
|
||||||
/// îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÌÏÇÆÁÊÌ
|
|
||||||
WARN(_("Can't open log file"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
log_open_time = time(NULL);
|
|
||||||
logname = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save message to log file, rotate logs every 24 hours
|
|
||||||
*/
|
|
||||||
int putlog(const char *fmt, ...){
|
|
||||||
if(!Flog) return 0;
|
|
||||||
time_t t_now = time(NULL);
|
|
||||||
if(t_now - log_open_time > 86400){ // rotate log
|
|
||||||
fprintf(Flog, "\n\t\t%sRotate log\n", ctime(&t_now));
|
|
||||||
fclose(Flog);
|
|
||||||
char newname[PATH_MAX];
|
|
||||||
snprintf(newname, PATH_MAX, "%s.old", logname);
|
|
||||||
if(rename(logname, newname)) WARN("rename()");
|
|
||||||
openlogfile(logname);
|
|
||||||
if(!Flog) return 0;
|
|
||||||
}
|
|
||||||
//int i = fprintf(Flog, "%s\t\t", ctime(&t_now));
|
|
||||||
char buf[256];
|
|
||||||
strftime(buf, 255, "%Y/%m/%d %H:%M:%S", localtime(&t_now));
|
|
||||||
int i = fprintf(Flog, "%s\t\t", buf);
|
|
||||||
va_list ar;
|
|
||||||
va_start(ar, fmt);
|
|
||||||
i = vfprintf(Flog, fmt, ar);
|
|
||||||
va_end(ar);
|
|
||||||
fprintf(Flog, "\n");
|
|
||||||
fflush(Flog);
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
* Logging to file
|
* Logging to file
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
sl_log *globlog = NULL; // "global" log file (the first opened logfile)
|
sl_log_t *sl_globlog = NULL; // "global" log file (the first opened logfile)
|
||||||
/**
|
/**
|
||||||
* @brief sl_createlog - create log file, test file open ability
|
* @brief sl_createlog - create log file, test file open ability
|
||||||
* @param logpath - path to log file
|
* @param logpath - path to log file
|
||||||
* @param level - lowest message level (e.g. LOGLEVEL_ERR won't allow to write warn/msg/dbg)
|
* @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
|
* @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){
|
sl_log_t *sl_createlog(const char *logpath, sl_loglevel_e level, int prefix){
|
||||||
if(level < LOGLEVEL_NONE || level > LOGLEVEL_ANY) return NULL;
|
if(level < LOGLEVEL_NONE || level > LOGLEVEL_ANY) return NULL;
|
||||||
if(!logpath) return NULL;
|
if(!logpath) return NULL;
|
||||||
FILE *logfd = fopen(logpath, "a");
|
FILE *logfd = fopen(logpath, "a");
|
||||||
@ -450,7 +450,7 @@ sl_log *sl_createlog(const char *logpath, sl_loglevel level, int prefix){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
fclose(logfd);
|
fclose(logfd);
|
||||||
sl_log *log = MALLOC(sl_log, 1);
|
sl_log_t *log = MALLOC(sl_log_t, 1);
|
||||||
log->logpath = strdup(logpath);
|
log->logpath = strdup(logpath);
|
||||||
if(!log->logpath){
|
if(!log->logpath){
|
||||||
WARN("strdup()");
|
WARN("strdup()");
|
||||||
@ -462,7 +462,7 @@ sl_log *sl_createlog(const char *logpath, sl_loglevel level, int prefix){
|
|||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sl_deletelog(sl_log **log){
|
void sl_deletelog(sl_log_t **log){
|
||||||
if(!log || !*log) return;
|
if(!log || !*log) return;
|
||||||
FREE((*log)->logpath);
|
FREE((*log)->logpath);
|
||||||
FREE(*log);
|
FREE(*log);
|
||||||
@ -476,7 +476,7 @@ void sl_deletelog(sl_log **log){
|
|||||||
* @param fmt - format and the rest part of message
|
* @param fmt - format and the rest part of message
|
||||||
* @return amount of symbols saved in file
|
* @return amount of symbols saved in file
|
||||||
*/
|
*/
|
||||||
int sl_putlogt(int timest, sl_log *log, sl_loglevel lvl, const char *fmt, ...){
|
int sl_putlogt(int timest, sl_log_t *log, sl_loglevel_e lvl, const char *fmt, ...){
|
||||||
if(!log || !log->logpath) return 0;
|
if(!log || !log->logpath) return 0;
|
||||||
if(lvl > log->loglevel) return 0;
|
if(lvl > log->loglevel) return 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -484,9 +484,9 @@ int sl_putlogt(int timest, sl_log *log, sl_loglevel lvl, const char *fmt, ...){
|
|||||||
if(!logfd) return 0;
|
if(!logfd) return 0;
|
||||||
int lfd = fileno(logfd);
|
int lfd = fileno(logfd);
|
||||||
// try to lock file
|
// try to lock file
|
||||||
double t0 = dtime();
|
double t0 = sl_dtime();
|
||||||
int locked = 0;
|
int locked = 0;
|
||||||
while(dtime() - t0 < 0.1){ // timeout for 0.1s
|
while(sl_dtime() - t0 < 0.1){ // timeout for 0.1s
|
||||||
if(-1 == flock(lfd, LOCK_EX | LOCK_NB)) continue;
|
if(-1 == flock(lfd, LOCK_EX | LOCK_NB)) continue;
|
||||||
locked = 1;
|
locked = 1;
|
||||||
break;
|
break;
|
||||||
|
|||||||
198
usefull_macros.h
198
usefull_macros.h
@ -20,14 +20,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __USEFULL_MACROS_H__
|
|
||||||
#define __USEFULL_MACROS_H__
|
|
||||||
|
|
||||||
#include <stdbool.h> // bool
|
#ifdef SL_USE_OLD_TTY
|
||||||
#include <unistd.h> // pid_t
|
|
||||||
#include <errno.h> // errno
|
|
||||||
#include <termios.h> // termios
|
#include <termios.h> // termios
|
||||||
|
#else
|
||||||
|
#include <asm-generic/termbits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h> // errno
|
||||||
#include <stdlib.h> // alloc, free
|
#include <stdlib.h> // alloc, free
|
||||||
|
#include <sys/types.h> // pid_t
|
||||||
|
#include <unistd.h> // pid_t
|
||||||
// just for different purposes
|
// just for different purposes
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -103,8 +106,8 @@ void WEAK signals(int sig);
|
|||||||
/*
|
/*
|
||||||
* Memory allocation
|
* Memory allocation
|
||||||
*/
|
*/
|
||||||
#define ALLOC(type, var, size) type * var = ((type *)my_alloc(size, sizeof(type)))
|
#define ALLOC(type, var, size) type * var = ((type *)sl_alloc(size, sizeof(type)))
|
||||||
#define MALLOC(type, size) ((type *)my_alloc(size, sizeof(type)))
|
#define MALLOC(type, size) ((type *)sl_alloc(size, sizeof(type)))
|
||||||
#define FREE(ptr) do{if(ptr){free(ptr); ptr = NULL;}}while(0)
|
#define FREE(ptr) do{if(ptr){free(ptr); ptr = NULL;}}while(0)
|
||||||
|
|
||||||
#ifndef DBL_EPSILON
|
#ifndef DBL_EPSILON
|
||||||
@ -115,38 +118,48 @@ void WEAK signals(int sig);
|
|||||||
const char *sl_libversion();
|
const char *sl_libversion();
|
||||||
|
|
||||||
// double value of UNIX time
|
// double value of UNIX time
|
||||||
double dtime();
|
double sl_dtime();
|
||||||
|
|
||||||
// functions for color output in tty & no-color in pipes
|
// functions for color output in tty & no-color in pipes
|
||||||
extern int (*red)(const char *fmt, ...);
|
extern int (*red)(const char *fmt, ...);
|
||||||
extern int (*_WARN)(const char *fmt, ...);
|
extern int (*_WARN)(const char *fmt, ...);
|
||||||
extern int (*green)(const char *fmt, ...);
|
extern int (*green)(const char *fmt, ...);
|
||||||
// safe allocation
|
// safe allocation
|
||||||
void * my_alloc(size_t N, size_t S);
|
void *sl_alloc(size_t N, size_t S);
|
||||||
// setup locales & other
|
// setup locales & other
|
||||||
void initial_setup();
|
void sl_init();
|
||||||
|
|
||||||
// mmap file
|
// mmap file
|
||||||
typedef struct{
|
typedef struct{
|
||||||
char *data;
|
char *data;
|
||||||
size_t len;
|
size_t len;
|
||||||
} mmapbuf;
|
} sl_mmapbuf_t;
|
||||||
mmapbuf *My_mmap(char *filename);
|
sl_mmapbuf_t *sl_mmap(char *filename);
|
||||||
void My_munmap(mmapbuf *b);
|
void sl_munmap(sl_mmapbuf_t *b);
|
||||||
|
|
||||||
// console in non-echo mode
|
// console in non-echo mode
|
||||||
void restore_console();
|
void sl_restore_con();
|
||||||
void setup_con();
|
void sl_setup_con();
|
||||||
int read_console();
|
int sl_read_con();
|
||||||
int mygetchar();
|
int sl_getchar();
|
||||||
|
|
||||||
long throw_random_seed();
|
long sl_random_seed();
|
||||||
|
|
||||||
uint64_t get_available_mem();
|
uint64_t sl_mem_avail();
|
||||||
|
|
||||||
|
// omit leading spaces
|
||||||
|
char *sl_omitspaces(const char *str);
|
||||||
|
// omit trailing spaces
|
||||||
|
char *sl_omitspacesr(const char *v);
|
||||||
|
|
||||||
|
// convert string to double with checking
|
||||||
|
int sl_str2d(double *num, const char *str);
|
||||||
|
int sl_str2ll(long long *num, const char *str);
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
The original term.h
|
The original term.h
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
|
#ifdef SL_USE_OLD_TTY
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *portname; // device filename (should be freed before structure freeing)
|
char *portname; // device filename (should be freed before structure freeing)
|
||||||
int speed; // baudrate in human-readable format
|
int speed; // baudrate in human-readable format
|
||||||
@ -157,23 +170,31 @@ typedef struct {
|
|||||||
char *buf; // buffer for data read
|
char *buf; // buffer for data read
|
||||||
size_t bufsz; // size of buf
|
size_t bufsz; // size of buf
|
||||||
size_t buflen; // length of data read into buf
|
size_t buflen; // length of data read into buf
|
||||||
bool exclusive; // should device be exclusive opened
|
int exclusive; // should device be exclusive opened
|
||||||
} TTY_descr;
|
} sl_tty_t;
|
||||||
|
|
||||||
void close_tty(TTY_descr **descr);
|
tcflag_t sl_tty_convspd(int speed);
|
||||||
TTY_descr *new_tty(char *comdev, int speed, size_t bufsz);
|
#else
|
||||||
TTY_descr *tty_open(TTY_descr *d, int exclusive);
|
typedef struct {
|
||||||
int read_tty(TTY_descr *descr);
|
char *portname; // device filename (should be freed before structure freeing)
|
||||||
int tty_timeout(double usec);
|
int speed; // baudrate in human-readable format
|
||||||
int write_tty(int comfd, const char *buff, size_t length);
|
char *format; // format like 8N1
|
||||||
tcflag_t conv_spd(int speed);
|
struct termios2 oldtty; // TTY flags for previous port settings
|
||||||
|
struct termios2 tty; // TTY flags for current settings
|
||||||
|
int comfd; // TTY file descriptor
|
||||||
|
char *buf; // buffer for data read
|
||||||
|
size_t bufsz; // size of buf
|
||||||
|
size_t buflen; // length of data read into buf
|
||||||
|
int exclusive; // should device be exclusive opened
|
||||||
|
} sl_tty_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
// convert string to double with checking
|
void sl_tty_close(sl_tty_t **descr);
|
||||||
int str2double(double *num, const char *str);
|
sl_tty_t *sl_tty_new(char *comdev, int speed, size_t bufsz);
|
||||||
|
sl_tty_t *sl_tty_open(sl_tty_t *d, int exclusive);
|
||||||
// logging (deprecated)
|
int sl_tty_read(sl_tty_t *descr);
|
||||||
void __attribute__ ((deprecated)) openlogfile(char *name);
|
int sl_tty_tmout(double usec);
|
||||||
int __attribute__ ((deprecated)) putlog(const char *fmt, ...);
|
int sl_tty_write(int comfd, const char *buff, size_t length);
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
Logging
|
Logging
|
||||||
@ -184,31 +205,32 @@ typedef enum{
|
|||||||
LOGLEVEL_WARN, // only warnings and errors
|
LOGLEVEL_WARN, // only warnings and errors
|
||||||
LOGLEVEL_MSG, // all without debug
|
LOGLEVEL_MSG, // all without debug
|
||||||
LOGLEVEL_DBG, // all messages
|
LOGLEVEL_DBG, // all messages
|
||||||
LOGLEVEL_ANY // all shit
|
LOGLEVEL_ANY, // all shit
|
||||||
} sl_loglevel;
|
LOGLEVEL_AMOUNT // total amount
|
||||||
|
} sl_loglevel_e;
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
char *logpath; // full path to logfile
|
char *logpath; // full path to logfile
|
||||||
sl_loglevel loglevel; // loglevel
|
sl_loglevel_e loglevel; // loglevel
|
||||||
int addprefix; // if !=0 add record type to each line(e.g. [ERR])
|
int addprefix; // if !=0 add record type to each line(e.g. [ERR])
|
||||||
} sl_log;
|
} sl_log_t;
|
||||||
|
|
||||||
extern sl_log *globlog; // "global" log file
|
extern sl_log_t *sl_globlog; // "global" log file
|
||||||
|
|
||||||
sl_log *sl_createlog(const char *logpath, sl_loglevel level, int prefix);
|
sl_log_t *sl_createlog(const char *logpath, sl_loglevel_e level, int prefix);
|
||||||
void sl_deletelog(sl_log **log);
|
void sl_deletelog(sl_log_t **log);
|
||||||
int sl_putlogt(int timest, sl_log *log, sl_loglevel lvl, const char *fmt, ...);
|
int sl_putlogt(int timest, sl_log_t *log, sl_loglevel_e lvl, const char *fmt, ...);
|
||||||
// open "global" log
|
// open "global" log
|
||||||
#define OPENLOG(nm, lvl, prefix) (globlog = sl_createlog(nm, lvl, prefix))
|
#define OPENLOG(nm, lvl, prefix) (sl_globlog = sl_createlog(nm, lvl, prefix))
|
||||||
// shortcuts for different log levels; ..ADD - add message without timestamp
|
// shortcuts for different log levels; ..ADD - add message without timestamp
|
||||||
#define LOGERR(...) do{sl_putlogt(1, globlog, LOGLEVEL_ERR, __VA_ARGS__);}while(0)
|
#define LOGERR(...) do{sl_putlogt(1, sl_globlog, LOGLEVEL_ERR, __VA_ARGS__);}while(0)
|
||||||
#define LOGERRADD(...) do{sl_putlogt(0, globlog, LOGLEVEL_ERR, __VA_ARGS__);}while(0)
|
#define LOGERRADD(...) do{sl_putlogt(0, sl_globlog, LOGLEVEL_ERR, __VA_ARGS__);}while(0)
|
||||||
#define LOGWARN(...) do{sl_putlogt(1, globlog, LOGLEVEL_WARN, __VA_ARGS__);}while(0)
|
#define LOGWARN(...) do{sl_putlogt(1, sl_globlog, LOGLEVEL_WARN, __VA_ARGS__);}while(0)
|
||||||
#define LOGWARNADD(...) do{sl_putlogt(0, globlog, LOGLEVEL_WARN, __VA_ARGS__);}while(0)
|
#define LOGWARNADD(...) do{sl_putlogt(0, sl_globlog, LOGLEVEL_WARN, __VA_ARGS__);}while(0)
|
||||||
#define LOGMSG(...) do{sl_putlogt(1, globlog, LOGLEVEL_MSG, __VA_ARGS__);}while(0)
|
#define LOGMSG(...) do{sl_putlogt(1, sl_globlog, LOGLEVEL_MSG, __VA_ARGS__);}while(0)
|
||||||
#define LOGMSGADD(...) do{sl_putlogt(0, globlog, LOGLEVEL_MSG, __VA_ARGS__);}while(0)
|
#define LOGMSGADD(...) do{sl_putlogt(0, sl_globlog, LOGLEVEL_MSG, __VA_ARGS__);}while(0)
|
||||||
#define LOGDBG(...) do{sl_putlogt(1, globlog, LOGLEVEL_DBG, __VA_ARGS__);}while(0)
|
#define LOGDBG(...) do{sl_putlogt(1, sl_globlog, LOGLEVEL_DBG, __VA_ARGS__);}while(0)
|
||||||
#define LOGDBGADD(...) do{sl_putlogt(0, globlog, LOGLEVEL_DBG, __VA_ARGS__);}while(0)
|
#define LOGDBGADD(...) do{sl_putlogt(0, sl_globlog, LOGLEVEL_DBG, __VA_ARGS__);}while(0)
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
The original parseargs.h
|
The original parseargs.h
|
||||||
@ -217,7 +239,7 @@ int sl_putlogt(int timest, sl_log *log, sl_loglevel lvl, const char *fmt, ...);
|
|||||||
#define APTR(x) ((void*)x)
|
#define APTR(x) ((void*)x)
|
||||||
|
|
||||||
// if argptr is a function:
|
// if argptr is a function:
|
||||||
typedef bool(*argfn)(void *arg);
|
typedef int(*sl_argfn_t)(void *arg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* type of getopt's argument
|
* type of getopt's argument
|
||||||
@ -238,8 +260,8 @@ typedef enum {
|
|||||||
arg_double, // double
|
arg_double, // double
|
||||||
arg_float, // float
|
arg_float, // float
|
||||||
arg_string, // char *
|
arg_string, // char *
|
||||||
arg_function // parse_args will run function `bool (*fn)(char *optarg, int N)`
|
arg_function // parse_args will run function `int (*fn)(char *optarg, int N)`
|
||||||
} argtype;
|
} sl_argtype_e;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure for getopt_long & help
|
* Structure for getopt_long & help
|
||||||
@ -265,30 +287,30 @@ typedef enum{
|
|||||||
NEED_ARG = 1,
|
NEED_ARG = 1,
|
||||||
OPT_ARG = 2,
|
OPT_ARG = 2,
|
||||||
MULT_PAR
|
MULT_PAR
|
||||||
} hasarg;
|
} sl_hasarg_e;
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
// these are from struct option:
|
// these are from struct option:
|
||||||
const char *name; // long option's name
|
const char *name; // long option's name
|
||||||
hasarg has_arg; // 0 - no args, 1 - nesessary arg, 2 - optionally arg, 4 - need arg & key can repeat (args are stored in null-terminated array)
|
sl_hasarg_e has_arg; // 0 - no args, 1 - nesessary arg, 2 - optionally arg, 3 - need arg & key can repeat (args are stored in null-terminated array)
|
||||||
int *flag; // NULL to return val, pointer to int - to set its value of val (function returns 0)
|
int *flag; // NULL to return val, pointer to int - to set its value of val (function returns 0)
|
||||||
int val; // short opt name (if flag == NULL) or flag's value
|
int val; // short opt name (if flag == NULL) or flag's value
|
||||||
// and these are mine:
|
// and these are mine:
|
||||||
argtype type; // type of argument
|
sl_argtype_e type; // type of argument
|
||||||
void *argptr; // pointer to variable to assign optarg value or function `bool (*fn)(char *optarg, int N)`
|
void *argptr; // pointer to variable to assign optarg value or function `int (*fn)(char *optarg, int N)`
|
||||||
const char *help; // help string which would be shown in function `showhelp` or NULL
|
const char *help; // help string which would be shown in function `showhelp` or NULL
|
||||||
} myoption;
|
} sl_option_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Suboptions structure, almost the same like myoption
|
* Suboptions structure, almost the same like sl_option_t
|
||||||
* used in parse_subopts()
|
* used in parse_subopts()
|
||||||
*/
|
*/
|
||||||
typedef struct{
|
typedef struct{
|
||||||
const char *name;
|
const char *name;
|
||||||
hasarg has_arg;
|
sl_hasarg_e has_arg;
|
||||||
argtype type;
|
sl_argtype_e type;
|
||||||
void *argptr;
|
void *argptr;
|
||||||
} mysuboption;
|
} sl_suboption_t;
|
||||||
|
|
||||||
// last string of array (all zeros)
|
// last string of array (all zeros)
|
||||||
#define end_option {0,0,0,0,0,0,0}
|
#define end_option {0,0,0,0,0,0,0}
|
||||||
@ -296,14 +318,14 @@ typedef struct{
|
|||||||
|
|
||||||
extern const char *__progname;
|
extern const char *__progname;
|
||||||
|
|
||||||
void showhelp(int oindex, myoption *options);
|
void sl_showhelp(int oindex, sl_option_t *options);
|
||||||
void parseargs(int *argc, char ***argv, myoption *options);
|
void sl_parseargs(int *argc, char ***argv, sl_option_t *options);
|
||||||
/**
|
/**
|
||||||
* @brief change_helpstring - change standard help header
|
* @brief sl_helpstring - change standard help header
|
||||||
* @param str (i) - new format (MAY consist ONE "%s" for progname)
|
* @param str (i) - new format (MAY consist ONE "%s" for progname)
|
||||||
*/
|
*/
|
||||||
void change_helpstring(char *s);
|
void sl_helpstring(char *s);
|
||||||
bool get_suboption(char *str, mysuboption *opt);
|
int sl_get_suboption(char *str, sl_suboption_t *opt);
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
@ -314,24 +336,44 @@ bool get_suboption(char *str, mysuboption *opt);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// default function to run if another process found
|
// default function to run if another process found
|
||||||
void WEAK iffound_default(pid_t pid);
|
void WEAK sl_iffound_deflt(pid_t pid);
|
||||||
// check that our process is exclusive
|
// check that our process is exclusive
|
||||||
void check4running(char *selfname, char *pidfilename);
|
void sl_check4running(char *selfname, char *pidfilename);
|
||||||
// read name of process by its PID
|
// read name of process by its PID
|
||||||
char *readPSname(pid_t pid);
|
char *sl_getPSname(pid_t pid);
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
The original fifo_lifo.h
|
The original fifo_lifo.h
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
typedef struct buff_node{
|
typedef struct sl_buff_node{
|
||||||
void *data;
|
void *data;
|
||||||
struct buff_node *next, *last;
|
struct sl_buff_node *next, *last;
|
||||||
} List;
|
} sl_list_t;
|
||||||
|
|
||||||
List *list_push_tail(List **lst, void *v);
|
sl_list_t *sl_list_push_tail(sl_list_t **lst, void *v);
|
||||||
List *list_push(List **lst, void *v);
|
sl_list_t *sl_list_push(sl_list_t **lst, void *v);
|
||||||
void *list_pop(List **lst);
|
void *sl_list_pop(sl_list_t **lst);
|
||||||
|
|
||||||
|
/******************************************************************************\
|
||||||
|
The original config.h
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
// max length of key (including '\0')
|
||||||
|
#define SL_KEY_LEN (32)
|
||||||
|
// max length of value (including '\0')
|
||||||
|
#define SL_VAL_LEN (128)
|
||||||
|
|
||||||
#endif // __USEFULL_MACROS_H__
|
// starting symbol of any comment
|
||||||
|
#define SL_COMMENT_CHAR '#'
|
||||||
|
|
||||||
|
// option or simple configuration value (don't work for functions)
|
||||||
|
typedef struct{
|
||||||
|
union{
|
||||||
|
int ival; long long llval; double dval; float fval;
|
||||||
|
};
|
||||||
|
sl_argtype_e type;
|
||||||
|
} sl_optval;
|
||||||
|
|
||||||
|
int sl_get_keyval(const char *pair, char key[SL_KEY_LEN], char value[SL_VAL_LEN]);
|
||||||
|
char *sl_print_opts(sl_option_t *opt, int showall);
|
||||||
|
int sl_conf_readopts(const char *filename, sl_option_t *options);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user