update folders
This commit is contained in:
BIN
snipplets/code/.assets/fondo para itchio.png
Normal file
BIN
snipplets/code/.assets/fondo para itchio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.0 KiB |
BIN
snipplets/code/.assets/monogram-extended.ttf
Normal file
BIN
snipplets/code/.assets/monogram-extended.ttf
Normal file
Binary file not shown.
BIN
snipplets/code/.assets/v-logo.png
Normal file
BIN
snipplets/code/.assets/v-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
13
snipplets/code/Arduino/init_blink.h
Normal file
13
snipplets/code/Arduino/init_blink.h
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
Author: Alexander Popov
|
||||
License: Unlicense
|
||||
*/
|
||||
|
||||
void init_blink(int times, int delay) {
|
||||
for (int count = 0; count < times; count++) {
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
delay(delay);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
delay(delay);
|
||||
}
|
||||
}
|
12
snipplets/code/Bash/command_exists.sh
Normal file
12
snipplets/code/Bash/command_exists.sh
Normal file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! [ -x "$(command -v git)" ]; then
|
||||
echo 'Error: git is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v crystal &> /dev/null
|
||||
then
|
||||
echo "<the_command> could not be found"
|
||||
exit
|
||||
fi
|
26
snipplets/code/Bash/irc_logger.sh
Executable file
26
snipplets/code/Bash/irc_logger.sh
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
# https://linuxconcept.com/making-a-simple-irc-chat-bot-logger-using-bash-script/
|
||||
|
||||
nick="blb$$"
|
||||
channel=admin
|
||||
server=iiiypuk.me
|
||||
config=/tmp/irclog
|
||||
[ -n "$1" ] && channel=$1
|
||||
[ -n "$2" ] && server=$2
|
||||
config="${config}_${channel}"
|
||||
echo "NICK $nick" > $config
|
||||
echo "USER $nick +i * :$0" >> $config
|
||||
echo "JOIN #$channel" >> $config
|
||||
trap "rm -f $config;exit 0" INT TERM EXIT
|
||||
tail -f $config | nc $server 6667 | while read MESSAGE
|
||||
do
|
||||
case "$MESSAGE" in
|
||||
PING*) echo "PONG${MESSAGE#PING}" >> $config;; *QUIT*) ;;
|
||||
*PART*) ;;
|
||||
*JOIN*) ;;
|
||||
*NICK*) ;;
|
||||
*PRIVMSG*) echo "${MESSAGE}" | sed -nr "s/^:([^!]+).*PRIVMSG[^:]+:(.*)/[$(date '+%R')] \1> \2/p" >> $config;;
|
||||
*) echo "${MESSAGE}";;
|
||||
esac
|
||||
done
|
17
snipplets/code/Bash/unix-socket-server.sh
Executable file
17
snipplets/code/Bash/unix-socket-server.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# TCP
|
||||
#coproc nc -l localhost 3000
|
||||
|
||||
# UnixSocket
|
||||
coproc nc -l -U ./app.sock
|
||||
|
||||
while read -r cmd; do
|
||||
case $cmd in
|
||||
d) date ;;
|
||||
q) break ;;
|
||||
*) echo 'Try again?'
|
||||
esac
|
||||
done <&"${COPROC[0]}" >&"${COPROC[1]}"
|
||||
|
||||
kill "$COPROC_PID"
|
38
snipplets/code/C/AF_INET_sockets/echo_client.c
Normal file
38
snipplets/code/C/AF_INET_sockets/echo_client.c
Normal file
@ -0,0 +1,38 @@
|
||||
/* https://rsdn.org/article/unix/sockets.xml */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
char message[] = "Hello there!\n";
|
||||
char buf[sizeof(message)];
|
||||
|
||||
int main()
|
||||
{
|
||||
int sock;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(3425); // или любой другой порт...
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
perror("connect");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
send(sock, message, sizeof(message), 0);
|
||||
recv(sock, buf, sizeof(message), 0);
|
||||
|
||||
printf(buf);
|
||||
close(sock);
|
||||
|
||||
return 0;
|
||||
}
|
48
snipplets/code/C/AF_INET_sockets/echo_server.c
Normal file
48
snipplets/code/C/AF_INET_sockets/echo_server.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* https://rsdn.org/article/unix/sockets.xml */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int sock, listener;
|
||||
struct sockaddr_in addr;
|
||||
char buf[1024];
|
||||
int bytes_read;
|
||||
|
||||
listener = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listener < 0) {
|
||||
perror("socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(3425);
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
if (bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
perror("bind");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
listen(listener, 1);
|
||||
|
||||
while(1) {
|
||||
sock = accept(listener, NULL, NULL);
|
||||
if (sock < 0) {
|
||||
perror("accept");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
bytes_read = recv(sock, buf, 1024, 0);
|
||||
if (bytes_read <= 0) break;
|
||||
send(sock, buf, bytes_read, 0);
|
||||
}
|
||||
|
||||
close(sock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
8
snipplets/code/C/Makefile
Normal file
8
snipplets/code/C/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
CC = clang
|
||||
CFLAGS = -O2
|
||||
LDFLAGS = -lsqlite3
|
||||
|
||||
all: sqlite3_create sqlite3_insert sqlite3_select sqlite3_update sqlite3_delete
|
||||
|
||||
clean:
|
||||
rm sqlite3_create sqlite3_insert sqlite3_select sqlite3_update sqlite3_delete
|
9
snipplets/code/C/README.md
Normal file
9
snipplets/code/C/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# C
|
||||
|
||||
## SQLite 3
|
||||
|
||||
- [CREATE TABLE](sqlite/sqlite3_create.c)
|
||||
- [INSERT INTO](sqlite/sqlite3_insert.c)
|
||||
- [SELECT](sqlite/sqlite3_select.c)
|
||||
- [UPDATE](sqlite/sqlite3_update.c)
|
||||
- [DELETE](sqlite/sqlite3_delete.c)
|
30
snipplets/code/C/atomic.c
Normal file
30
snipplets/code/C/atomic.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
#include <threads.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
atomic_int acnt;
|
||||
int cnt;
|
||||
|
||||
int f(void* thr_data)
|
||||
{
|
||||
(void)thr_data;
|
||||
for(int n = 0; n < 1000; ++n) {
|
||||
++cnt;
|
||||
++acnt;
|
||||
// for this example, relaxed memory order is sufficient, e.g.
|
||||
// atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
thrd_t thr[10];
|
||||
for(int n = 0; n < 10; ++n)
|
||||
thrd_create(&thr[n], f, NULL);
|
||||
for(int n = 0; n < 10; ++n)
|
||||
thrd_join(thr[n], NULL);
|
||||
|
||||
printf("The atomic counter is %u\n", acnt);
|
||||
printf("The non-atomic counter is %u\n", cnt);
|
||||
}
|
10
snipplets/code/C/clear_string.c
Normal file
10
snipplets/code/C/clear_string.c
Normal file
@ -0,0 +1,10 @@
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
char *buffer = malloc(256 + 1);
|
||||
|
||||
buffer[0] = '\0';
|
||||
strcpy(buffer, "");
|
||||
memset(buffer, '\0', sizeof(buffer));
|
||||
|
||||
return 0;
|
||||
}
|
10
snipplets/code/C/format-code
Executable file
10
snipplets/code/C/format-code
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
files=(
|
||||
"file.c"
|
||||
)
|
||||
|
||||
for file in "${files[@]}"
|
||||
do
|
||||
clang-format -i --style=LLVM --sort-includes=false $file
|
||||
done
|
6
snipplets/code/C/libserialport/.editorconfig
Normal file
6
snipplets/code/C/libserialport/.editorconfig
Normal file
@ -0,0 +1,6 @@
|
||||
[{clear,build,format-code}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[{*.c,*.ino}]
|
||||
indent_size = 2
|
12
snipplets/code/C/libserialport/.gitignore
vendored
Normal file
12
snipplets/code/C/libserialport/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# libserialport examples
|
||||
port_info.c
|
||||
list_ports.c
|
||||
send_receive.c
|
||||
|
||||
# binaries
|
||||
port_info
|
||||
list_ports
|
||||
send_receive
|
||||
|
||||
listen
|
||||
abc.txt
|
1
snipplets/code/C/libserialport/Board/.gitignore
vendored
Normal file
1
snipplets/code/C/libserialport/Board/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
3party/
|
24
snipplets/code/C/libserialport/Board/Board.ino
Normal file
24
snipplets/code/C/libserialport/Board/Board.ino
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
Author: Alexander Popov
|
||||
License: Unlicense
|
||||
*/
|
||||
|
||||
#include "3party/AsyncStream.h"
|
||||
AsyncStream<50> serial(&Serial, '\n');
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (strcmp(serial.buf, "ping") == 0) {
|
||||
Serial.println("PONG");
|
||||
}
|
||||
|
||||
Serial.println("ooooo");
|
||||
// delay(1000);
|
||||
Serial.println("zzzz");
|
||||
// delay(1000);
|
||||
Serial.println("xxx");
|
||||
// delay(1000);
|
||||
}
|
3
snipplets/code/C/libserialport/Board/README.md
Normal file
3
snipplets/code/C/libserialport/Board/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
Download `AsyncStream.h` from
|
||||
https://github.com/GyverLibs/AsyncStream
|
||||
and drop in to `3party` folder.
|
18
snipplets/code/C/libserialport/README.md
Normal file
18
snipplets/code/C/libserialport/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
Download `libserialport` library.
|
||||
|
||||
```sh
|
||||
git clone git://sigrok.org/libserialport
|
||||
```
|
||||
|
||||
For **build** code use `build` script or build files manually.
|
||||
|
||||
Example:
|
||||
|
||||
```sh
|
||||
export C_INCLUDE_PATH=<path/to/libserialport>
|
||||
export LIBRARY_PATH=<path/to/libserialport/.libs>
|
||||
|
||||
gcc -static -Wall -O3 -o <output_filename> <file.c> -lserialport
|
||||
```
|
||||
|
||||
Arduino example project store in `Board` folder.
|
20
snipplets/code/C/libserialport/build_gcc
Executable file
20
snipplets/code/C/libserialport/build_gcc
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# build - script for build all files.
|
||||
#
|
||||
# Alexander Popov <iiiypuk@fastmail.fm>
|
||||
|
||||
export C_INCLUDE_PATH=$HOME/Git/libserialport
|
||||
export LIBRARY_PATH=$HOME/Git/libserialport/.libs
|
||||
|
||||
for file in \
|
||||
port_info.c \
|
||||
list_ports.c \
|
||||
send_receive.c \
|
||||
listen.c \
|
||||
|
||||
do
|
||||
echo -ne "[ ] Building $file...\r"
|
||||
gcc -static -Wall -O3 -o ${file%.*} $file -lserialport
|
||||
echo [OK
|
||||
done
|
20
snipplets/code/C/libserialport/build_tcc
Executable file
20
snipplets/code/C/libserialport/build_tcc
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# build - script for build all files.
|
||||
#
|
||||
# Alexander Popov <iiiypuk@fastmail.fm>
|
||||
|
||||
export C_INCLUDE_PATH=$HOME/Git/libserialport
|
||||
export LIBRARY_PATH=$HOME/Git/libserialport/.libs
|
||||
|
||||
for file in \
|
||||
port_info.c \
|
||||
list_ports.c \
|
||||
send_receive.c \
|
||||
listen.c \
|
||||
|
||||
do
|
||||
echo -ne "[ ] Building $file...\r"
|
||||
tcc -Wall -O3 -o ${file%.*} -I$C_INCLUDE_PATH $file $LIBRARY_PATH/libserialport.a
|
||||
echo [OK
|
||||
done
|
17
snipplets/code/C/libserialport/clear
Executable file
17
snipplets/code/C/libserialport/clear
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# clear - script for delete all builded files.
|
||||
#
|
||||
# Alexander Popov <iiiypuk@fastmail.fm>
|
||||
|
||||
files=(
|
||||
"port_info"
|
||||
"list_ports"
|
||||
"send_receive"
|
||||
"listen"
|
||||
)
|
||||
|
||||
for file in ${files[@]}
|
||||
do
|
||||
rm $file &> /dev/null
|
||||
done
|
14
snipplets/code/C/libserialport/format-code
Executable file
14
snipplets/code/C/libserialport/format-code
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# formt-code - script for beautify code by clang-format.
|
||||
#
|
||||
# Alexander Popov <iiiypuk@fastmail.fm>
|
||||
|
||||
files=(
|
||||
"listen.c"
|
||||
)
|
||||
|
||||
for file in "${files[@]}"
|
||||
do
|
||||
clang-format -i --style=LLVM --sort-includes=false $file
|
||||
done
|
133
snipplets/code/C/libserialport/listen.c
Normal file
133
snipplets/code/C/libserialport/listen.c
Normal file
@ -0,0 +1,133 @@
|
||||
#include <libserialport.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* Helper function for error handling. */
|
||||
int check(enum sp_return result);
|
||||
void handle_sigint(int sig);
|
||||
|
||||
bool INTERRUPT = false;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct sp_port *serial_port;
|
||||
char *port_name;
|
||||
|
||||
const int size = 256;
|
||||
char *buffer = malloc(size + 1);
|
||||
|
||||
const unsigned int timeout = 1000;
|
||||
int result;
|
||||
|
||||
/* Get the port name from the command line. */
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s <port>\n\n", argv[0]);
|
||||
|
||||
struct sp_port **port_list;
|
||||
enum sp_return result = sp_list_ports(&port_list);
|
||||
|
||||
/* Getting the available ports. */
|
||||
if (result != SP_OK) {
|
||||
puts("Getting available ports failed!");
|
||||
} else {
|
||||
puts("Available ports:");
|
||||
|
||||
int i;
|
||||
for (i = 0; port_list[i] != NULL; i++) {
|
||||
/* Get the name of the port. */
|
||||
struct sp_port *port = port_list[i];
|
||||
char *port_name = sp_get_port_name(port);
|
||||
|
||||
printf(" * %s\n", port_name);
|
||||
}
|
||||
|
||||
printf("\nAvailable %d ports.\n", i);
|
||||
|
||||
sp_free_port_list(port_list);
|
||||
}
|
||||
|
||||
return -1;
|
||||
} else {
|
||||
port_name = argv[1];
|
||||
}
|
||||
|
||||
printf("Connecting to '%s'...\n", port_name);
|
||||
check(sp_get_port_by_name(port_name, &serial_port));
|
||||
check(sp_open(serial_port, SP_MODE_READ_WRITE));
|
||||
|
||||
check(sp_set_baudrate(serial_port, 9600));
|
||||
check(sp_set_bits(serial_port, 8));
|
||||
check(sp_set_parity(serial_port, SP_PARITY_NONE));
|
||||
check(sp_set_stopbits(serial_port, 1));
|
||||
check(sp_set_flowcontrol(serial_port, SP_FLOWCONTROL_NONE));
|
||||
puts("Connected.");
|
||||
|
||||
signal(SIGINT, handle_sigint);
|
||||
|
||||
FILE *output_file;
|
||||
output_file = fopen("./abc.txt", "w");
|
||||
|
||||
/* Reading lines from serial port. */
|
||||
bool reading = true;
|
||||
while (reading && !INTERRUPT) {
|
||||
int pos = 0;
|
||||
|
||||
/* Character-by-character reading. */
|
||||
while (pos < size) {
|
||||
result = check(sp_blocking_read(serial_port, buffer + pos, 1, timeout));
|
||||
|
||||
if (result == -1) {
|
||||
puts("Error reading from serial port");
|
||||
|
||||
reading = false;
|
||||
break;
|
||||
} else if (result == 0) {
|
||||
puts("No more data");
|
||||
break;
|
||||
} else {
|
||||
if (buffer[pos] == '\n') {
|
||||
buffer[pos] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
puts(buffer);
|
||||
fputs(buffer, output_file);
|
||||
}
|
||||
|
||||
fclose(output_file);
|
||||
free(buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function for error handling. */
|
||||
int check(enum sp_return result) {
|
||||
char *error_message;
|
||||
|
||||
switch (result) {
|
||||
case SP_ERR_ARG:
|
||||
puts("Error: Invalid argument.");
|
||||
abort();
|
||||
case SP_ERR_FAIL:
|
||||
error_message = sp_last_error_message();
|
||||
printf("Error: Failed: %s\n", error_message);
|
||||
sp_free_error_message(error_message);
|
||||
abort();
|
||||
case SP_ERR_SUPP:
|
||||
puts("Error: Not supported.");
|
||||
abort();
|
||||
case SP_ERR_MEM:
|
||||
puts("Error: Couldn't allocate memory.");
|
||||
abort();
|
||||
case SP_OK:
|
||||
default:
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_sigint(int sig) { INTERRUPT = true; }
|
3
snipplets/code/C/read csv/example.csv
Normal file
3
snipplets/code/C/read csv/example.csv
Normal file
@ -0,0 +1,3 @@
|
||||
id,text,desc
|
||||
1,ololo,none
|
||||
2,l33t,hack
|
|
31
snipplets/code/C/read csv/read_csv.c
Normal file
31
snipplets/code/C/read csv/read_csv.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <stdio.h> // file handling functions
|
||||
#include <stdlib.h> // atoi
|
||||
#include <string.h> // strtok
|
||||
|
||||
int main() {
|
||||
char buffer[80];
|
||||
FILE *stream = fopen("example.csv", "r");
|
||||
|
||||
while (fgets(buffer, 80, stream)) {
|
||||
char *token = strtok(buffer, ",");
|
||||
|
||||
// If you only need the first column of each row
|
||||
// Если нам нужен только первый столбец каждой строки
|
||||
if (token) {
|
||||
int n = atoi(token);
|
||||
printf("%s\n", n);
|
||||
}
|
||||
|
||||
// If you need all the values in a row
|
||||
// Если нам нужны все значения подряд
|
||||
while (token) {
|
||||
// Just printing each integer here but handle as needed
|
||||
// int n = atoi(token);
|
||||
printf("%s\n", token);
|
||||
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
6
snipplets/code/C/rest_server/.gitignore
vendored
Normal file
6
snipplets/code/C/rest_server/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
orcania/
|
||||
ulfius/
|
||||
|
||||
*.a
|
||||
|
||||
rest
|
7
snipplets/code/C/rest_server/Makefile
Normal file
7
snipplets/code/C/rest_server/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
CC = clang
|
||||
|
||||
all:
|
||||
$(CC) -std=c99 -Wall -O3 -o rest main.c -lulfius -lorcania
|
||||
|
||||
tcc:
|
||||
tcc -O3 -I./ulfius/include -I./orcania/include -o rest main.c libulfius.2.7.13.a liborcania.2.3.2.a -lyder -lgnutls -lz -ljansson -lmicrohttpd -lcurl
|
16
snipplets/code/C/rest_server/README.md
Normal file
16
snipplets/code/C/rest_server/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
REST API
|
||||
--------
|
||||
|
||||
* `http://localhost:8000/api/param/:name` - возвращает `:name`
|
||||
* `http://localhost:8000/api/param/quit` - завершит выполнение программы
|
||||
|
||||
Зависимости
|
||||
-----------
|
||||
|
||||
* [ulfius](https://github.com/babelouest/ulfius)
|
||||
* [orcania](https://github.com/babelouest/orcania)
|
||||
|
||||
```sh
|
||||
ar rcs libulfius.2.7.13.a ulfius.o u_map.o u_request.o u_response.o u_send_request.o u_websocket.o yuarel.o
|
||||
ar rcs liborcania.2.3.2.a orcania.o memory.o base64.o
|
||||
```
|
26
snipplets/code/C/rest_server/main.c
Normal file
26
snipplets/code/C/rest_server/main.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <ulfius.h>
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "server.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// создаём отдельный поток, в котором запускаем сервер
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, NULL, thread_server, (void *)&tid);
|
||||
|
||||
// while (true) {
|
||||
// }
|
||||
|
||||
pthread_exit(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
BIN
snipplets/code/C/rest_server/qa/answer.png
Normal file
BIN
snipplets/code/C/rest_server/qa/answer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
61
snipplets/code/C/rest_server/qa/question.md
Normal file
61
snipplets/code/C/rest_server/qa/question.md
Normal file
@ -0,0 +1,61 @@
|
||||
Помогите с проблемой. Не завершается `while` цикл при изменении переменной `running`.
|
||||
|
||||
```
|
||||
while (running) {
|
||||
// loop
|
||||
}
|
||||
```
|
||||
|
||||
Использую библиотеку `ulfius` для реализации REST API сервера.
|
||||
Есть функция `thread_server()`, которую из `main()` запускаю в отдельном потоке,
|
||||
в которой запускается `ulfius` сервер.
|
||||
|
||||
```
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, NULL, thread_server, (void *)&tid);
|
||||
```
|
||||
|
||||
Сервер запускаю следующим образом:
|
||||
```
|
||||
int ret;
|
||||
ret = ulfius_start_framework(&instance);
|
||||
|
||||
if (ret == U_OK) {
|
||||
printf("Server started at %d.\n", PORT);
|
||||
} else {
|
||||
printf("Error starting server as %d port.\n", PORT);
|
||||
}
|
||||
|
||||
while (running) {
|
||||
printf("\r%b", running);
|
||||
}
|
||||
printf("Server halt.\n");
|
||||
|
||||
ulfius_stop_framework(&instance);
|
||||
ulfius_clean_instance(&instance);
|
||||
```
|
||||
|
||||
`running` - глобальная переменная типа `bool`.
|
||||
|
||||
В документации к библиотеке, чтобы сервер не схлопывался используется следующий код.
|
||||
```
|
||||
if (ret == U_OK) {
|
||||
getchar();
|
||||
}
|
||||
```
|
||||
|
||||
Есть callback функция, которая вызывается при обращении к API,
|
||||
в которой я проверяю отправленное пользователем значение, и если оно равняется `quit`
|
||||
присваиваю переменной `running` значение `false`, чтобы сервер закрылся.
|
||||
|
||||
Если из цикла `while (running) { printf("\r%b", running); }` убрать `printf()`,
|
||||
либо выполнять другие операции, например присвоение `a = 1;` то сервер не закрывается,
|
||||
хотя значение `running` равняется `0`.
|
||||
|
||||
Я пишу утилиту для внутенного использования, которая общается с Arduino платой
|
||||
посредством библиотеки `libserialport` и в цикле читает данные.
|
||||
|
||||
Хочу, чтобы утилита по REST получала данные и отправляла их на плату,
|
||||
но не получается реализовать нормальное завершение программы, потому что сервер не умирает.
|
||||
|
||||
**OS:** Linux
|
75
snipplets/code/C/rest_server/server.h
Normal file
75
snipplets/code/C/rest_server/server.h
Normal file
@ -0,0 +1,75 @@
|
||||
atomic_bool running = true;
|
||||
|
||||
#define PORT 8000
|
||||
#define PREFIX "/api"
|
||||
|
||||
int callback_default(const struct _u_request *request,
|
||||
struct _u_response *response, void *user_data);
|
||||
int callback_all_test_foo(const struct _u_request *request,
|
||||
struct _u_response *response, void *user_data);
|
||||
|
||||
void *thread_server(void *vargp) {
|
||||
int ret;
|
||||
struct _u_instance instance;
|
||||
|
||||
if (ulfius_init_instance(&instance, PORT, NULL, NULL) != U_OK) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
instance.max_post_body_size = 1024;
|
||||
|
||||
ulfius_add_endpoint_by_val(&instance, "GET", PREFIX, "/param/:name", 0,
|
||||
&callback_all_test_foo, "user data 1");
|
||||
ulfius_add_endpoint_by_val(&instance, "POST", PREFIX, "/param/:name", 0,
|
||||
&callback_all_test_foo, "user data 2");
|
||||
|
||||
ulfius_set_default_endpoint(&instance, &callback_default, NULL);
|
||||
|
||||
ret = ulfius_start_framework(&instance);
|
||||
|
||||
if (ret == U_OK) {
|
||||
printf("Server started at %d.\n", PORT);
|
||||
} else {
|
||||
printf("Error starting server as %d port.\n", PORT);
|
||||
}
|
||||
|
||||
while (running) {
|
||||
}
|
||||
printf("Server halt.\n");
|
||||
|
||||
ulfius_stop_framework(&instance);
|
||||
ulfius_clean_instance(&instance);
|
||||
}
|
||||
|
||||
int callback_default(const struct _u_request *request,
|
||||
struct _u_response *response, void *user_data) {
|
||||
(void)(request);
|
||||
(void)(user_data);
|
||||
ulfius_set_string_body_response(response, 404,
|
||||
"Page not found, do what you want");
|
||||
|
||||
return U_CALLBACK_CONTINUE;
|
||||
}
|
||||
|
||||
int callback_all_test_foo(const struct _u_request *request,
|
||||
struct _u_response *response, void *user_data) {
|
||||
// url_params = request->map_url
|
||||
// post_params = request->map_post_body
|
||||
|
||||
const char **keys, *value;
|
||||
keys = u_map_enum_keys(request->map_url);
|
||||
value = u_map_get(request->map_url, keys[0]);
|
||||
|
||||
if (strcmp("quit", value) == 0) {
|
||||
running = false;
|
||||
}
|
||||
|
||||
char *response_body = msprintf("Your %s is %s\n", keys[0], value);
|
||||
|
||||
print_to_terminal(response_body);
|
||||
ulfius_set_string_body_response(response, 200, response_body);
|
||||
|
||||
o_free(response_body);
|
||||
|
||||
return U_CALLBACK_CONTINUE;
|
||||
}
|
1
snipplets/code/C/rest_server/utils.h
Normal file
1
snipplets/code/C/rest_server/utils.h
Normal file
@ -0,0 +1 @@
|
||||
void print_to_terminal(char *text) { printf("%s", text); }
|
12
snipplets/code/C/rgbToHex.c
Normal file
12
snipplets/code/C/rgbToHex.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
int red = 0;
|
||||
int green = 128;
|
||||
int blue = 64;
|
||||
|
||||
printf("#%.2x%.2x%.2x\n", red, green, blue); //#008040
|
||||
|
||||
return 0;
|
||||
}
|
52
snipplets/code/C/sqlite/sqlite3_create.c
Normal file
52
snipplets/code/C/sqlite/sqlite3_create.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
|
||||
int i;
|
||||
for(i = 0; i<argc; i++) {
|
||||
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
sqlite3 *db;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
char *sql;
|
||||
|
||||
/* Open database */
|
||||
rc = sqlite3_open("test.db", &db);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return(0);
|
||||
} else {
|
||||
fprintf(stdout, "Opened database successfully\n");
|
||||
}
|
||||
|
||||
/* Create SQL statement */
|
||||
sql = "CREATE TABLE COMPANY(" \
|
||||
"ID INT PRIMARY KEY NOT NULL," \
|
||||
"NAME TEXT NOT NULL," \
|
||||
"AGE INT NOT NULL," \
|
||||
"ADDRESS CHAR(50)," \
|
||||
"SALARY REAL);";
|
||||
|
||||
/* Execute SQL statement */
|
||||
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
} else {
|
||||
fprintf(stdout, "Table created successfully\n");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
51
snipplets/code/C/sqlite/sqlite3_delete.c
Normal file
51
snipplets/code/C/sqlite/sqlite3_delete.c
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int callback(void *data, int argc, char **argv, char **azColName) {
|
||||
int i;
|
||||
fprintf(stderr, "%s: ", (const char*)data);
|
||||
|
||||
for (i = 0; i<argc; i++) {
|
||||
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
sqlite3 *db;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
char *sql;
|
||||
const char* data = "Callback function called";
|
||||
|
||||
/* Open database */
|
||||
rc = sqlite3_open("test.db", &db);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return(0);
|
||||
} else {
|
||||
fprintf(stderr, "Opened database successfully\n");
|
||||
}
|
||||
|
||||
/* Create merged SQL statement */
|
||||
sql = "DELETE from COMPANY where ID=2; " \
|
||||
"SELECT * from COMPANY";
|
||||
|
||||
/* Execute SQL statement */
|
||||
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
} else {
|
||||
fprintf(stdout, "Operation done successfully\n");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
55
snipplets/code/C/sqlite/sqlite3_insert.c
Normal file
55
snipplets/code/C/sqlite/sqlite3_insert.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
|
||||
int i;
|
||||
for (i = 0; i<argc; i++) {
|
||||
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
sqlite3 *db;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
char *sql;
|
||||
|
||||
/* Open database */
|
||||
rc = sqlite3_open("test.db", &db);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return(0);
|
||||
} else {
|
||||
fprintf(stderr, "Opened database successfully\n");
|
||||
}
|
||||
|
||||
/* Create SQL statement */
|
||||
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \
|
||||
"VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
|
||||
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \
|
||||
"VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); " \
|
||||
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
|
||||
"VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
|
||||
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
|
||||
"VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00);";
|
||||
|
||||
/* Execute SQL statement */
|
||||
rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
} else {
|
||||
fprintf(stdout, "Records created successfully\n");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
50
snipplets/code/C/sqlite/sqlite3_select.c
Normal file
50
snipplets/code/C/sqlite/sqlite3_select.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int callback(void *data, int argc, char **argv, char **azColName) {
|
||||
int i;
|
||||
fprintf(stderr, "%s: ", (const char*)data);
|
||||
|
||||
for (i = 0; i<argc; i++) {
|
||||
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
sqlite3 *db;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
char *sql;
|
||||
const char* data = "Callback function called";
|
||||
|
||||
/* Open database */
|
||||
rc = sqlite3_open("test.db", &db);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return(0);
|
||||
} else {
|
||||
fprintf(stderr, "Opened database successfully\n");
|
||||
}
|
||||
|
||||
/* Create SQL statement */
|
||||
sql = "SELECT * from COMPANY";
|
||||
|
||||
/* Execute SQL statement */
|
||||
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
} else {
|
||||
fprintf(stdout, "Operation done successfully\n");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
51
snipplets/code/C/sqlite/sqlite3_update.c
Normal file
51
snipplets/code/C/sqlite/sqlite3_update.c
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
static int callback(void *data, int argc, char **argv, char **azColName) {
|
||||
int i;
|
||||
fprintf(stderr, "%s: ", (const char*)data);
|
||||
|
||||
for(i = 0; i<argc; i++) {
|
||||
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
sqlite3 *db;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
char *sql;
|
||||
const char* data = "Callback function called";
|
||||
|
||||
/* Open database */
|
||||
rc = sqlite3_open("test.db", &db);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return(0);
|
||||
} else {
|
||||
fprintf(stderr, "Opened database successfully\n");
|
||||
}
|
||||
|
||||
/* Create merged SQL statement */
|
||||
sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \
|
||||
"SELECT * from COMPANY";
|
||||
|
||||
/* Execute SQL statement */
|
||||
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
} else {
|
||||
fprintf(stdout, "Operation done successfully\n");
|
||||
}
|
||||
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
31
snipplets/code/C/thread.c
Normal file
31
snipplets/code/C/thread.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* https://www.geeksforgeeks.org/multithreading-in-c/ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
int g = 0;
|
||||
|
||||
void *my_thread(void *vargp) {
|
||||
int *id = (int *)vargp;
|
||||
|
||||
static int s = 0;
|
||||
|
||||
++s;
|
||||
++g;
|
||||
|
||||
printf("Thread ID: %d, Static: %d, Global: %d\n", *id, ++s, ++g);
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t tid;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 3; i++)
|
||||
pthread_create(&tid, NULL, my_thread, (void *)&tid);
|
||||
|
||||
pthread_exit(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
BIN
snipplets/code/C/unixsocket/a.out
Executable file
BIN
snipplets/code/C/unixsocket/a.out
Executable file
Binary file not shown.
BIN
snipplets/code/C/unixsocket/client
Executable file
BIN
snipplets/code/C/unixsocket/client
Executable file
Binary file not shown.
79
snipplets/code/C/unixsocket/client.c
Normal file
79
snipplets/code/C/unixsocket/client.c
Normal file
@ -0,0 +1,79 @@
|
||||
// https://systemprogrammingatntu.github.io/mp2/unix_socket.html
|
||||
|
||||
#define SOCKET_NAME "/tmp/resol.sock"
|
||||
#define BUFFER_SIZE 12
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct sockaddr_un addr;
|
||||
int i;
|
||||
int ret;
|
||||
int data_socket;
|
||||
char buffer[BUFFER_SIZE];
|
||||
|
||||
/* Create local socket. */
|
||||
data_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (data_socket == -1) {
|
||||
perror("socket");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* For portability clear the whole structure, since some
|
||||
* implementations have additional (nonstandard) fields in
|
||||
* the structure.
|
||||
*/
|
||||
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
|
||||
/* Connect socket to socket address */
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
|
||||
|
||||
ret = connect (data_socket, (const struct sockaddr *) &addr,
|
||||
sizeof(struct sockaddr_un));
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "The server is down.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Send arguments. */
|
||||
for (i = 1; i < argc; ++i) {
|
||||
ret = write(data_socket, argv[i], strlen(argv[i]) + 1);
|
||||
if (ret == -1) {
|
||||
perror("write");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Request result. */
|
||||
strcpy (buffer, "END");
|
||||
ret = write(data_socket, buffer, strlen(buffer) + 1);
|
||||
if (ret == -1) {
|
||||
perror("write");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Receive result. */
|
||||
ret = read(data_socket, buffer, BUFFER_SIZE);
|
||||
if (ret == -1) {
|
||||
perror("read");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Ensure buffer is 0-terminated. */
|
||||
buffer[BUFFER_SIZE - 1] = 0;
|
||||
|
||||
printf("Result = %s\n", buffer);
|
||||
|
||||
/* Close socket. */
|
||||
close(data_socket);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
BIN
snipplets/code/C/unixsocket/server
Executable file
BIN
snipplets/code/C/unixsocket/server
Executable file
Binary file not shown.
123
snipplets/code/C/unixsocket/server.c
Normal file
123
snipplets/code/C/unixsocket/server.c
Normal file
@ -0,0 +1,123 @@
|
||||
// https://systemprogrammingatntu.github.io/mp2/unix_socket.html
|
||||
|
||||
#define SOCKET_NAME "/tmp/resol.sock"
|
||||
#define BUFFER_SIZE 12
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct sockaddr_un addr;
|
||||
int down_flag = 0;
|
||||
int ret;
|
||||
int listen_socket;
|
||||
int data_socket;
|
||||
int result;
|
||||
char buffer[BUFFER_SIZE];
|
||||
|
||||
/*
|
||||
* In case the program exited inadvertently on the last run,
|
||||
* remove the socket.
|
||||
*/
|
||||
unlink(SOCKET_NAME);
|
||||
|
||||
/* Create local socket. */
|
||||
listen_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (listen_socket == -1) {
|
||||
perror("socket");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* For portability clear the whole structure, since some
|
||||
* implementations have additional (nonstandard) fields in
|
||||
* the structure.
|
||||
*/
|
||||
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||
|
||||
/* Bind socket to socket name. */
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
|
||||
|
||||
ret = bind(listen_socket, (const struct sockaddr *) &addr,
|
||||
sizeof(struct sockaddr_un));
|
||||
if (ret == -1) {
|
||||
perror("bind");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare for accepting connections. The backlog size is set
|
||||
* to 20. So while one request is being processed other requests
|
||||
* can be waiting.
|
||||
*/
|
||||
ret = listen(listen_socket, 20);
|
||||
if (ret == -1) {
|
||||
perror("listen");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* This is the main loop for handling connections. */
|
||||
for (;;) {
|
||||
/* Wait for incoming connection. */
|
||||
data_socket = accept(listen_socket, NULL, NULL);
|
||||
if (data_socket == -1) {
|
||||
perror("accept");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
result = 0;
|
||||
for(;;) {
|
||||
/* Wait for next data packet. */
|
||||
ret = read(data_socket, buffer, BUFFER_SIZE);
|
||||
if (ret == -1) {
|
||||
perror("read");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Ensure buffer is 0-terminated. */
|
||||
buffer[BUFFER_SIZE - 1] = 0;
|
||||
|
||||
/* Handle commands. */
|
||||
if (!strncmp(buffer, "DOWN", BUFFER_SIZE)) {
|
||||
down_flag = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strncmp(buffer, "END", BUFFER_SIZE)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add received summand. */
|
||||
result += atoi(buffer);
|
||||
}
|
||||
|
||||
/* Send result. */
|
||||
sprintf(buffer, "%d", result);
|
||||
ret = write(data_socket, buffer, BUFFER_SIZE);
|
||||
|
||||
if (ret == -1) {
|
||||
perror("write");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Close socket. */
|
||||
close(data_socket);
|
||||
|
||||
/* Quit on DOWN command. */
|
||||
if (down_flag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close(listen_socket);
|
||||
|
||||
/* Unlink the socket. */
|
||||
unlink(SOCKET_NAME);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
6
snipplets/code/CSS/README.md
Normal file
6
snipplets/code/CSS/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# CSS
|
||||
|
||||
- [`@font-face`](font-face.css) - пример добавления шрифта из файла
|
||||
- [Pixel Art](pixel-art.css) - настройки для рендера Pixel Art на `canvas`
|
||||
- [Список без точек](ul-remove-bullets.css) - убираем точки (bullet) в списках
|
||||
- [BG Image cover](back-image-cover.css) - Фоновое изображение по центру
|
8
snipplets/code/CSS/back-image-cover.css
Normal file
8
snipplets/code/CSS/back-image-cover.css
Normal file
@ -0,0 +1,8 @@
|
||||
body{
|
||||
margin: 0px;
|
||||
height: 100vh;
|
||||
background-image: url('../img/landing.jpg');
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
3
snipplets/code/CSS/base64.css
Normal file
3
snipplets/code/CSS/base64.css
Normal file
@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-image: url('data:image/png;base64,%codeForImage%');
|
||||
}
|
8
snipplets/code/CSS/font-face.css
Normal file
8
snipplets/code/CSS/font-face.css
Normal file
@ -0,0 +1,8 @@
|
||||
@font-face {
|
||||
font-family: 'MyWebFont';
|
||||
src: url('webfont.eot'); /* IE9 Compat Modes */
|
||||
src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('webfont.woff') format('woff'), /* Modern Browsers */
|
||||
url('webfont.ttf') format('truetype'), /* Safari, Android, iOS */
|
||||
url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
|
||||
}
|
7
snipplets/code/CSS/pixel-art.css
Normal file
7
snipplets/code/CSS/pixel-art.css
Normal file
@ -0,0 +1,7 @@
|
||||
canvas {
|
||||
image-rendering: crisp-edges;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
/* JavaScript */
|
||||
/* context.imageSmoothingEnabled = false; */
|
3
snipplets/code/CSS/ul-remove-bullets.css
Normal file
3
snipplets/code/CSS/ul-remove-bullets.css
Normal file
@ -0,0 +1,3 @@
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
24
snipplets/code/Crystal/Colorize.cr
Normal file
24
snipplets/code/Crystal/Colorize.cr
Normal file
@ -0,0 +1,24 @@
|
||||
require "colorize"
|
||||
|
||||
"foo".colorize(:green)
|
||||
100.colorize(:red)
|
||||
[1, 2, 3].colorize(:blue)
|
||||
|
||||
# Available colors are:
|
||||
# :default
|
||||
# :black
|
||||
# :red
|
||||
# :green
|
||||
# :yellow
|
||||
# :blue
|
||||
# :magenta
|
||||
# :cyan
|
||||
# :light_gray
|
||||
# :dark_gray
|
||||
# :light_red
|
||||
# :light_green
|
||||
# :light_yellow
|
||||
# :light_blue
|
||||
# :light_magenta
|
||||
# :light_cyan
|
||||
# :white
|
13
snipplets/code/Crystal/README.md
Normal file
13
snipplets/code/Crystal/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Crystal
|
||||
|
||||
## std
|
||||
- [Значение из Regex::MatchData](value_from_match.cr) - Получить значение из `Regex::MatchData("Happy")`
|
||||
- [IO::TimeoutError](prompt_timeout.cr) - Установка тайм-аута на пользовательский ввод
|
||||
- [ENV["..."]](env_variable.cr) - Переменные среды
|
||||
- [Colorize](Colorize.cr) - Цветной вывод в консоль
|
||||
- [JSON](json.cr) - Пример работы с JSON
|
||||
- [Fiber](schedule.cr) - Пример распаралеливания кода и расписания
|
||||
- [http/client](http_client.cr) - Пример HTTP клиента
|
||||
|
||||
## Stuff
|
||||
- [`irc_bot.cr`](irc_bot.cr) - Реализация клиента (бота) для IRC
|
28
snipplets/code/Crystal/UNIXSockets/by_faustinoaq/client.cr
Normal file
28
snipplets/code/Crystal/UNIXSockets/by_faustinoaq/client.cr
Normal file
@ -0,0 +1,28 @@
|
||||
require "socket"
|
||||
|
||||
client = UNIXSocket.new("/tmp/myapp.sock")
|
||||
|
||||
Signal::INT.trap {
|
||||
client.puts "quit"
|
||||
exit
|
||||
}
|
||||
|
||||
print "name: "
|
||||
name = gets.to_s
|
||||
|
||||
spawn {
|
||||
loop {
|
||||
msg = client.gets
|
||||
if msg
|
||||
puts msg
|
||||
else
|
||||
puts "server closed"
|
||||
exit
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
msg = gets.to_s
|
||||
client.puts "#{name}: #{msg}"
|
||||
}
|
@ -0,0 +1 @@
|
||||
https://github.com/crystal-lang/crystal/issues/4277#issuecomment-294009173
|
38
snipplets/code/Crystal/UNIXSockets/by_faustinoaq/server.cr
Normal file
38
snipplets/code/Crystal/UNIXSockets/by_faustinoaq/server.cr
Normal file
@ -0,0 +1,38 @@
|
||||
require "socket"
|
||||
|
||||
server = UNIXServer.new("/tmp/myapp.sock")
|
||||
CLIENTS = [] of UNIXSocket
|
||||
|
||||
Signal::INT.trap {
|
||||
puts "closing server..."
|
||||
server.close
|
||||
exit
|
||||
}
|
||||
|
||||
def on_message(client)
|
||||
loop {
|
||||
msg = client.gets
|
||||
if msg == "quit"
|
||||
puts "deleting client..."
|
||||
CLIENTS.delete client
|
||||
pp CLIENTS.size
|
||||
break
|
||||
else
|
||||
yield msg
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
loop {
|
||||
puts "waiting for client on /tmp/myapp.sock"
|
||||
new_client = server.accept
|
||||
spawn {
|
||||
on_message(new_client) { |msg|
|
||||
CLIENTS.each { |client|
|
||||
client.puts msg unless client == new_client
|
||||
}
|
||||
}
|
||||
}
|
||||
CLIENTS << new_client
|
||||
pp CLIENTS.size
|
||||
}
|
24
snipplets/code/Crystal/UNIXSockets/client.cr
Normal file
24
snipplets/code/Crystal/UNIXSockets/client.cr
Normal file
@ -0,0 +1,24 @@
|
||||
require "socket"
|
||||
|
||||
# connect to socket
|
||||
sock = UNIXSocket.new("/tmp/myapp.sock")
|
||||
|
||||
loop do
|
||||
print "Enter command [help, start, run]: "
|
||||
|
||||
# get string from terminal input
|
||||
string = gets.not_nil!.to_s
|
||||
|
||||
if string == "q"
|
||||
break
|
||||
end
|
||||
|
||||
# send string to server
|
||||
sock.puts "#{string}\n"
|
||||
|
||||
# get response from server & print
|
||||
response = sock.gets
|
||||
puts response
|
||||
end
|
||||
|
||||
sock.close
|
46
snipplets/code/Crystal/UNIXSockets/server.cr
Normal file
46
snipplets/code/Crystal/UNIXSockets/server.cr
Normal file
@ -0,0 +1,46 @@
|
||||
require "socket"
|
||||
require "file_utils"
|
||||
|
||||
SOCKET = "/tmp/myapp.sock"
|
||||
|
||||
begin
|
||||
FileUtils.rm(SOCKET)
|
||||
rescue e : File::NotFoundError
|
||||
end
|
||||
|
||||
server = UNIXServer.new(SOCKET)
|
||||
CLIENTS = [] of UNIXSocket
|
||||
|
||||
Signal::INT.trap do
|
||||
puts "Closing server..."
|
||||
server.close(delete = true)
|
||||
|
||||
exit
|
||||
end
|
||||
|
||||
def handle_client(client)
|
||||
loop do
|
||||
message = client.gets
|
||||
|
||||
p! client
|
||||
|
||||
if message == "start"
|
||||
puts "::request START command::"
|
||||
client.puts "Hello :)"
|
||||
elsif message == "help"
|
||||
puts "::request HELP command::"
|
||||
client.puts "This example ECHO unix server!"
|
||||
elsif message == "run"
|
||||
puts "::request RUN command::"
|
||||
client.puts "Ready, Set, GO!"
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
puts "Listen..."
|
||||
|
||||
while client = server.accept
|
||||
spawn handle_client(client)
|
||||
end
|
9
snipplets/code/Crystal/ctrl-c_interrupt.cr
Normal file
9
snipplets/code/Crystal/ctrl-c_interrupt.cr
Normal file
@ -0,0 +1,9 @@
|
||||
LibC.signal Signal::INT.value, ->(s : Int32) {
|
||||
puts "CTRL-C handler here!"
|
||||
exit
|
||||
}
|
||||
|
||||
Signal::INT.trap do
|
||||
puts "CTRL-C handler here!"
|
||||
exit
|
||||
end
|
3
snipplets/code/Crystal/env_variable.cr
Normal file
3
snipplets/code/Crystal/env_variable.cr
Normal file
@ -0,0 +1,3 @@
|
||||
shell = ENV["SHELL"]
|
||||
|
||||
puts "SHELL: #{shell}\nLANG: #{ENV["COLORTERM"]}"
|
11
snipplets/code/Crystal/http_client.cr
Normal file
11
snipplets/code/Crystal/http_client.cr
Normal file
@ -0,0 +1,11 @@
|
||||
require "json"
|
||||
require "http/client"
|
||||
|
||||
minecraft_url = "https://launchermeta.mojang.com/mc/game/version_manifest_v2.json"
|
||||
response = HTTP::Client.get minecraft_url
|
||||
|
||||
version_manifest = JSON.parse(response.body)
|
||||
|
||||
version = version_manifest["latest"]["release"]
|
||||
|
||||
puts version
|
24
snipplets/code/Crystal/irc_bot.cr
Normal file
24
snipplets/code/Crystal/irc_bot.cr
Normal file
@ -0,0 +1,24 @@
|
||||
require "socket"
|
||||
|
||||
puts "Connecting..."
|
||||
irc = TCPSocket.new("iiiypuk.me", 6667)
|
||||
|
||||
irc << "USER crystal localhost localhost :This is a bot!\n"
|
||||
irc << "NICK crystal\r\n"
|
||||
irc << "JOIN #admin\r\n"
|
||||
irc << "PRIVMSG #admin :!time\r\n"
|
||||
|
||||
while true
|
||||
response = irc.gets
|
||||
puts response
|
||||
|
||||
if response.to_s.includes?("PING")
|
||||
irc << "PONG #{response.to_s.split[1]}\r\n"
|
||||
end
|
||||
|
||||
if response.to_s.includes?("!time")
|
||||
irc << "PRIVMSG #admin :#{Time.local.to_unix}\r\n"
|
||||
end
|
||||
end
|
||||
|
||||
irc.close
|
5
snipplets/code/Crystal/json.cr
Normal file
5
snipplets/code/Crystal/json.cr
Normal file
@ -0,0 +1,5 @@
|
||||
require "json"
|
||||
|
||||
# Парсинг строки
|
||||
value = JSON.parse("[1, 2, 3]")
|
||||
p! value[0]
|
2
snipplets/code/Crystal/prompt_timeout.cr
Normal file
2
snipplets/code/Crystal/prompt_timeout.cr
Normal file
@ -0,0 +1,2 @@
|
||||
STDIN.read_timeout = 1
|
||||
STDIN.gets # raises IO::TimeoutError (after 1 second)
|
18
snipplets/code/Crystal/schedule.cr
Normal file
18
snipplets/code/Crystal/schedule.cr
Normal file
@ -0,0 +1,18 @@
|
||||
def every(period : Time::Span, &block : -> T) forall T
|
||||
spawn do
|
||||
loop do
|
||||
block.call
|
||||
sleep period
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
every(2.seconds) {
|
||||
puts "-@-@-"
|
||||
}
|
||||
|
||||
every(4.seconds) {
|
||||
puts "(-.-)Zzz..."
|
||||
}
|
||||
|
||||
sleep
|
8
snipplets/code/Crystal/value_from_match.cr
Normal file
8
snipplets/code/Crystal/value_from_match.cr
Normal file
@ -0,0 +1,8 @@
|
||||
test_string_1 = "rw------- (0o600)"
|
||||
# test_string_2 = "rwx------ (0o700)"
|
||||
|
||||
if /\d{3}/.match(test_string_1).try &.[0] != "600"
|
||||
puts "Password file permissions is not RW for you.".colorize(:red)
|
||||
|
||||
exit(0)
|
||||
end
|
8
snipplets/code/Gambas/array_foreach.bas
Normal file
8
snipplets/code/Gambas/array_foreach.bas
Normal file
@ -0,0 +1,8 @@
|
||||
' equpix color pallete
|
||||
Dim equpix15 As Array
|
||||
equpix15 = [5389390, 2763322, 4084802, 8672348, 3694716, 6060630, 1052708, 11697750, 13913682, 5613716, 8432704, 15501899, 9162938, 16764008, 16775360]
|
||||
|
||||
Dim color As Integer
|
||||
For Each color In equpix15
|
||||
Print color
|
||||
Next
|
13
snipplets/code/GameMaker/draw_text.gml
Normal file
13
snipplets/code/GameMaker/draw_text.gml
Normal file
@ -0,0 +1,13 @@
|
||||
/// @description Draw text
|
||||
|
||||
draw_set_font(Monogram_12);
|
||||
draw_set_halign(fa_right);
|
||||
|
||||
var text = "Version: " + global.version + " | by emilecok";
|
||||
var text_height = string_height(text);
|
||||
|
||||
draw_set_color(c_black);
|
||||
draw_text(room_width - 10 + 1, room_height - text_height + 1, text);
|
||||
|
||||
draw_set_color(c_white);
|
||||
draw_text(room_width - 10, room_height - text_height, text);
|
8
snipplets/code/GameMaker/fullscreen_toggle.gml
Normal file
8
snipplets/code/GameMaker/fullscreen_toggle.gml
Normal file
@ -0,0 +1,8 @@
|
||||
/// @description Fullscreen toggle
|
||||
|
||||
if window_get_fullscreen() {
|
||||
window_set_fullscreen(false);
|
||||
}
|
||||
else {
|
||||
window_set_fullscreen(true);
|
||||
}
|
3
snipplets/code/GameMaker/room_background.gml
Normal file
3
snipplets/code/GameMaker/room_background.gml
Normal file
@ -0,0 +1,3 @@
|
||||
var background = layer_background_get_id(layer_get_id("Background"));
|
||||
var my_color = make_colour_rgb(71, 45, 60);
|
||||
layer_background_blend(background, my_color);
|
7
snipplets/code/HTML/README.md
Normal file
7
snipplets/code/HTML/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# HTML
|
||||
|
||||
- [Sematic HTML5](SEMATIC-HTML5.md) - Гайд по сематическим тегам
|
||||
|
||||
- [favicons.html](favicons.html)
|
||||
- [anchors.html](anchors.html) - Пример использования якоря на странице
|
||||
- [humans.txt](humans.txt)
|
128
snipplets/code/HTML/SEMATIC-HTML5.md
Normal file
128
snipplets/code/HTML/SEMATIC-HTML5.md
Normal file
@ -0,0 +1,128 @@
|
||||
Основные семантические теги HTML
|
||||
================================
|
||||
Среди «старых» тегов из ранних версий HTML тоже есть семантические —
|
||||
например, тег `<p>`, который обозначает параграф.
|
||||
|
||||
При этом теги `<i>` или `<b>` не семантические,
|
||||
потому что они не добавляют смысла выделенному тексту,
|
||||
а просто определяют его внешний вид.
|
||||
|
||||
Но в актуальной версии стандарта HTML Living Standard есть семантические теги
|
||||
почти для всех основных частей сайта, и лучше пользоваться ими.
|
||||
Вот несколько примеров семантических тегов.
|
||||
|
||||
`<article>`
|
||||
---------
|
||||
**Значение:** независимая, отделяемая смысловая единица,
|
||||
например комментарий, твит, статья, виджет ВК и так далее.
|
||||
|
||||
**Особенности:** желателен заголовок внутри.
|
||||
|
||||
**Типовые ошибки:** путают с тегами `<section>` и `<div>`.
|
||||
|
||||
`<section>`
|
||||
-----------
|
||||
**Значение:** смысловой раздел документа. Неотделяемый, в отличие от `<article>`.
|
||||
|
||||
**Особенности:** желателен заголовок внутри.
|
||||
|
||||
**Типовые ошибки:** путают с тегами `<article>` и `<div>`.
|
||||
|
||||
`<aside>`
|
||||
---------
|
||||
**Значение:** побочный, косвенный для страницы контент.
|
||||
|
||||
**Особенности:** может иметь свой заголовок. Может встречаться несколько раз на странице.
|
||||
|
||||
**Типовые ошибки:** считать `<aside>` тегом для «боковой панели»
|
||||
и размечать этим тегом основной контент, который связан с окружающими его элементами.
|
||||
|
||||
`<nav>`
|
||||
-------
|
||||
**Значение:** навигационный раздел со ссылками на другие страницы или другие части страниц.
|
||||
|
||||
**Особенности:** используется для основной навигации,а не для всех групп ссылок.
|
||||
Основной является навигация или нет — на усмотрение верстальщика.
|
||||
Например, меню в подвале сайта можно не оборачивать в `<nav>`.
|
||||
В подвале обычно появляется краткий список ссылок
|
||||
(например, ссылка на главную, копирайт и условия) — это не является основной навигацией,
|
||||
семантически для такой информации предназначен `<footer>` сам по себе.
|
||||
|
||||
**Типовые ошибки:** многие считают, что в `<nav>` может быть только список навигационных ссылок,
|
||||
но согласно спецификации там может быть навигация в любой форме.
|
||||
|
||||
`<header>`
|
||||
----------
|
||||
**Значение:** вводная часть смыслового раздела или всего сайта,
|
||||
обычно содержит подсказки и навигацию. Чаще всего повторяется на всех страницах сайта.
|
||||
|
||||
**Особенности:** этих элементов может быть несколько на странице.
|
||||
|
||||
**Типовые ошибки:** использовать только как шапку сайта.
|
||||
|
||||
`<main>`
|
||||
--------
|
||||
**Значение:** основное, не повторяющееся на других страницах, содержание страницы.
|
||||
|
||||
**Особенности:** должен быть один на странице, исходя из определения.
|
||||
|
||||
**Типовые ошибки:** включать в этот тег то, что повторяется на других страницах
|
||||
(навигацию, копирайты и так далее).
|
||||
|
||||
`<footer>`
|
||||
----------
|
||||
**Значение:** заключительная часть смыслового раздела или всего сайта,
|
||||
обычно содержит информацию об авторах, список литературы, копирайт и так далее.
|
||||
Чаще всего повторяется на всех страницах сайта.
|
||||
|
||||
**Особенности:** этих элементов может быть несколько на странице.
|
||||
Тег `<footer>` не обязан находиться в конце раздела.
|
||||
**Типовые ошибки:** использовать только как подвал сайта.
|
||||
|
||||
Как разметить страницу с точки зрения семантики
|
||||
===============================================
|
||||
Процесс разметки можно разделить на несколько шагов с разной степенью детализации.
|
||||
|
||||
1. Крупные смысловые блоки на каждой странице сайта. Теги: `<header>`, `<main>`, `<footer>`.
|
||||
2. Крупные смысловые разделы в блоках. Теги: `<nav>`, `<section>`, `<article>`, `<aside>`.
|
||||
3. Заголовок всего документа и заголовки смысловых разделов. Теги: `<h1>-<h6>`.
|
||||
4. Мелкие элементы в смысловых разделах. Списки, таблицы, демо-материалы, параграфы и переносы,
|
||||
формы, цитаты, контактная информация и прогресс.
|
||||
5. Фразовые элементы. Изображения, ссылки, кнопки, видео, время и мелкие текстовые элементы.
|
||||
|
||||
Сомневаюсь, какие теги использовать
|
||||
===================================
|
||||
Есть простые правила для выбора нужных тегов.
|
||||
|
||||
1. Получилось найти самый подходящий смысловой тег — использовать его.
|
||||
2. Для потоковых контейнеров — `<div>`.
|
||||
3. Для мелких фразовых элементов (слово или фраза) — `<span>`.
|
||||
4. Правило для определения `<article>`, `<section>` и `<div>`:
|
||||
5. Можете дать имя разделу и вынести этот раздел на другой сайт? — `<article>`
|
||||
6. Можете дать имя разделу, но вынести на другой сайт не можете? — `<section>`
|
||||
7. Не можете дать имя? Получается что-то наподобие «новости и фотогалерея» или «правая колонка»? — `<div>`
|
||||
|
||||
Пример
|
||||
======
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Заголовок страницы</title>
|
||||
</head>
|
||||
<body>
|
||||
<header class="main-header">
|
||||
<!— Шапка сайта —>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<!— Основное содержимое страницы —>
|
||||
</main>
|
||||
|
||||
<footer class="main-footer">
|
||||
<!— Подвал сайта —>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
```
|
3
snipplets/code/HTML/anchors.html
Normal file
3
snipplets/code/HTML/anchors.html
Normal file
@ -0,0 +1,3 @@
|
||||
<p><a name="top"></a></p>
|
||||
<p>...</p>
|
||||
<p><a href="#top">Наверх</a></p>
|
9
snipplets/code/HTML/favicons.html
Normal file
9
snipplets/code/HTML/favicons.html
Normal file
@ -0,0 +1,9 @@
|
||||
<head>
|
||||
<!-- Icons -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="120x120" href="favicon-120x120.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<link rel="manifest" href="site.webmanifest">
|
||||
</head>
|
13
snipplets/code/HTML/humans.txt
Normal file
13
snipplets/code/HTML/humans.txt
Normal file
@ -0,0 +1,13 @@
|
||||
/* SITE */
|
||||
Last update: Thu Apr 13 04:50 PM MSK 2022
|
||||
Language: Russian
|
||||
Doctype: HTML5
|
||||
IDE: Sublime Text 4
|
||||
Components: None
|
||||
|
||||
/* TEAM */
|
||||
Chef: Alexander Popov
|
||||
Contacts: iiiypuk [at] fastmail.fm
|
||||
Twitter: @_iiiypuk
|
||||
Ko-Fi: iiiypuk
|
||||
From: Russia
|
3
snipplets/code/HTML/update-css.html
Normal file
3
snipplets/code/HTML/update-css.html
Normal file
@ -0,0 +1,3 @@
|
||||
<script>
|
||||
document.write("<link type='text/css' href='../ui/css/ui.css?version=" + new Date().getTime() + "' rel='stylesheet' />");
|
||||
</script>
|
17
snipplets/code/HTTP/README.md
Normal file
17
snipplets/code/HTTP/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
# HTTP status code
|
||||
|
||||
## Информационные
|
||||
|
||||
## Успех
|
||||
- `200` `OK` — успешный запрос
|
||||
- `201` `Created` — в результате успешного выполнения запроса был создан новый ресурс
|
||||
|
||||
## Перенаправление
|
||||
|
||||
## Ошибка клиента
|
||||
- `400` `Bad Request` — сервер обнаружил в запросе клиента синтаксическую ошибку
|
||||
- `401` `Unauthorized` — для доступа к запрашиваемому ресурсу требуется аутентификация
|
||||
- `403` `Forbidden` — сервер понял запрос, но он отказывается его выполнять из-за ограничений в доступе для клиента к указанному ресурсу
|
||||
- `404` `Not Found` — ошибка в написании адреса Web-страницы. Сервер понял запрос, но не нашёл соответствующего ресурса по указанному URL
|
||||
|
||||
## Ошибка сервера
|
74
snipplets/code/JavaScript/Intl.DateTimeFormat.js
Normal file
74
snipplets/code/JavaScript/Intl.DateTimeFormat.js
Normal file
@ -0,0 +1,74 @@
|
||||
// Опеределяем, каким образом должна юыть отформтированна дата
|
||||
let exampleFormatter = new Intl.DateTimeFormat('en-US', {
|
||||
// Стиль форматирования для даты
|
||||
// Может использоваться с timeStyle, но не с другими опциями
|
||||
// 'full' (по умолчанию), 'long', 'medium', 'short'
|
||||
// dateStyle: 'full',
|
||||
|
||||
// Стиль форматирования для времени
|
||||
// Может использоваться с dateStyle, но не с другими опциями
|
||||
// 'full' (по умолчанию), 'long', 'medium', 'short'
|
||||
// timeStyle: 'full',
|
||||
|
||||
// Если true, используется 12 часовой формат времени
|
||||
// Значение по умолчанию зависит от локали
|
||||
hour12: true,
|
||||
|
||||
// Как отформатировать время суток (am, morning и т.д.)
|
||||
// Работает только если используются 12-часовой формат времени
|
||||
// 'narrow', 'short', или 'long'
|
||||
dayPeriod: 'narrow',
|
||||
|
||||
// Стиль форматирования дней недели
|
||||
// 'long' ("Четверг"), 'short' ("Чт"), 'narrow' ("Ч")
|
||||
weekday: 'long',
|
||||
|
||||
// Стиль форматирования эпохт
|
||||
// 'long' ("Anno Domini"), 'short' ("AD"), 'narrow' ("A")
|
||||
era: 'short',
|
||||
|
||||
// Стиль форматирования года
|
||||
// 'numeric' ("2023"), '2-digit' ("23")
|
||||
year: 'numeric',
|
||||
|
||||
// Стиль форматирования месяца
|
||||
// 'numeric' ("3"), '2-digit' ("03"), 'long' ("Март"), 'short' ("Мар"), 'narrow' ("М")
|
||||
month: 'long',
|
||||
|
||||
// Стиль форматирования дня месяца
|
||||
// 'numeric' ("1"), '2-digit' ("01")
|
||||
day: 'numeric',
|
||||
|
||||
// Стиль форматирования часов
|
||||
// 'numeric', '2-digit'
|
||||
hour: 'numeric',
|
||||
|
||||
// Стиль форматирования минут
|
||||
// 'numeric', '2-digit'
|
||||
minute: 'numeric',
|
||||
|
||||
// Стиль форматирования секунд
|
||||
// 'numeric', '2-digit'
|
||||
second: 'numeric',
|
||||
|
||||
// Количество цифр, отоброжаемых в долях секунд
|
||||
// от 0 до 3
|
||||
fractionalSecondDigits: 1,
|
||||
|
||||
// Стиль форматирования часвого пояса
|
||||
// 'long' ("Eastern Standard Time"), 'short' ("EST"), 'shortOffset' ("GMT-5"), 'longOffset' ("GMT-0500"), 'shortGeneric' ("ET"), 'longGeneric' ("Eastern Time")
|
||||
timeZoneName: 'short'
|
||||
});
|
||||
|
||||
let formatter = new Intl.DateTimeFormat('en-US', {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: 'short'
|
||||
});
|
||||
|
||||
// Создание объекта Data
|
||||
let date = new Date('2023-10-31T22:00:00');
|
||||
|
||||
// Форматирование даты в строку
|
||||
// вернёт "Oct 31, 2023, 10:00 PM"
|
||||
let halloween = formatter.format(date);
|
||||
console.log(halloween);
|
8
snipplets/code/JavaScript/Object.entries.js
Normal file
8
snipplets/code/JavaScript/Object.entries.js
Normal file
@ -0,0 +1,8 @@
|
||||
const object1 = {
|
||||
a: 'somestring',
|
||||
b: 42
|
||||
};
|
||||
|
||||
for (const [key, value] of Object.entries(object1)) {
|
||||
console.log(`${key}: ${value}`);
|
||||
}
|
30
snipplets/code/JavaScript/README.md
Normal file
30
snipplets/code/JavaScript/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# JavaScript
|
||||
|
||||
## Basic
|
||||
- [Arrays](arrays.js) - работа с массивами
|
||||
- [Spread syntax](spread.js) - распаковка массива в аргументы
|
||||
- [location.href](location.href.js) - Переход на другую страницу
|
||||
- [Text Content](textContent.js) - Получить текстовое содержимое элемента
|
||||
- [Add DOM Elements](addElements.js) - Добавление элементов в DOM
|
||||
- [Add Class](addClass.js) - Добавление/Удаление классов
|
||||
|
||||
## Advanced
|
||||
- [Intl.DateTimeFormat](Intl.DateTimeFormat.js) - форматировнные строки из дат
|
||||
|
||||
## Перебор элементов
|
||||
- [Object.entries()](Object.entries.js) - Перебор объектов, ассоционных массивов
|
||||
|
||||
## Requests
|
||||
- [fetch](fetch.js) - Fetch запрос JSON данных
|
||||
- [xhr](xhrPostForm.js) - отправка формы POST запросом используя XHR
|
||||
|
||||
## Other
|
||||
- [Webpack](webpack.md) example config
|
||||
|
||||
## Canvas
|
||||
- [Drawing text](drawing-text.js) - примеры рисования текста на CANVAS
|
||||
- [`measureText()`](measureText.js) - возвращает информацию об измеренном тексте, например ширину
|
||||
- [`drawImage()`](canvas.drawImage.js) - метод Canvas 2D API рисования изображения на холсте
|
||||
|
||||
## GameDev
|
||||
- Canvas [GameLoop](gameloop.js) example
|
5
snipplets/code/JavaScript/addClass.js
Normal file
5
snipplets/code/JavaScript/addClass.js
Normal file
@ -0,0 +1,5 @@
|
||||
// Use element.classList.add to add a class:
|
||||
element.classList.add('my-class');
|
||||
|
||||
// And element.classList.remove to remove a class:
|
||||
element.classList.remove('my-class');
|
3
snipplets/code/JavaScript/addElements.js
Normal file
3
snipplets/code/JavaScript/addElements.js
Normal file
@ -0,0 +1,3 @@
|
||||
let newDiv = document.createElement('div');
|
||||
newDiv.appendChild(document.createTextNode('some text'));
|
||||
document.body.appendChild(newDiv);
|
17
snipplets/code/JavaScript/arrays.js
Normal file
17
snipplets/code/JavaScript/arrays.js
Normal file
@ -0,0 +1,17 @@
|
||||
let cats = ['Bob', 'Willy', 'Mini'];
|
||||
|
||||
// pop(): Remove an item from the end of an array
|
||||
// pop() returns the removed item
|
||||
cats.pop(); // ['Bob', 'Willy']
|
||||
|
||||
// push(): Add items to the end of an array
|
||||
// push() returns the new array length
|
||||
cats.push('Mini'); // ['Bob', 'Willy', 'Mini']
|
||||
|
||||
// shift(): Remove an item from the beginning of an array
|
||||
// shift() returns the removed item
|
||||
cats.shift(); // ['Willy', 'Mini']
|
||||
|
||||
// unshift(): Add items to the beginning of an array
|
||||
// unshift() returns the new array length.
|
||||
cats.unshift('Puff', 'George'); // ['Puff', 'George', 'Willy', 'Mini']
|
44
snipplets/code/JavaScript/canvas.drawImage.js
Normal file
44
snipplets/code/JavaScript/canvas.drawImage.js
Normal file
@ -0,0 +1,44 @@
|
||||
// void ctx.drawImage(image, dx, dy);
|
||||
// void ctx.drawImage(image, dx, dy, dWidth, dHeight);
|
||||
// void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
|
||||
|
||||
// image
|
||||
// Элемент для отображения в контексте.
|
||||
// Функция принимает любой источник изображения, пригодный для отображения
|
||||
// на холсте
|
||||
// dx
|
||||
// Координата по оси Х, обозначающая стартовую точку холста-приёмника,
|
||||
// в которую будет помещён верхний левый угол исходного image.
|
||||
// dy
|
||||
// Координата по оси Y, обозначающая стартовую точку холста-приёмника,
|
||||
// в которую будет помещён верхний левый угол исходного image.
|
||||
// dWidth
|
||||
// Ширина изображения, полученного из исходного image.
|
||||
// Эта опция позволяет масштабировать изображение по ширине.
|
||||
// Если опция не задана, изображение не будет масштабировано.
|
||||
// dHeight
|
||||
// Высота изображения, полученного из исходного image.
|
||||
// Эта опция позволяет масштабировать изображение по высоте.
|
||||
// Если опция не задана, изображение не будет масштабировано.
|
||||
// sx
|
||||
// Координата по оси X верхнего левого угла фрагмента,
|
||||
// который будет вырезан из изображения-источника и помещён в контекст-приёмник.
|
||||
// sy
|
||||
// Координата по оси Y верхнего левого угла фрагмента,
|
||||
// который будет вырезан из изображения-источника и помещён в контекст-приёмник.
|
||||
// sWidth
|
||||
// Ширина фрагмента, который будет вырезан из изображения источника
|
||||
// и помещён в контекст-приёмник. Если не задана, фрагмент от точки,
|
||||
// заданной sx и sy до правого нижнего угла источника
|
||||
// будет целиком скопирован в контекст-приёмник.
|
||||
// sHeight
|
||||
// Высота фрагмента, который будет вырезан из изображения источника
|
||||
// и помещён в контекст-приёмник.
|
||||
|
||||
function Draw() {
|
||||
let canvas = document.getElementById('canvas');
|
||||
let ctx = canvas.getContext('2d');
|
||||
let image = document.getElementById('source');
|
||||
|
||||
ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);
|
||||
}
|
14
snipplets/code/JavaScript/drawing-text.js
Normal file
14
snipplets/code/JavaScript/drawing-text.js
Normal file
@ -0,0 +1,14 @@
|
||||
function Draw() {
|
||||
let context = document.getElementById('canvas').getContext('2d');
|
||||
|
||||
// Styling text
|
||||
// font = value
|
||||
// textAlign = value | *start, end, left, right, center
|
||||
// textBaseline = value | top, hanging, middle, *alphabetic, ideographic, bottom
|
||||
// direction = value | ltr, rtl, *inherit
|
||||
|
||||
// fillText(text, x, y [, maxWidth])
|
||||
// strokeText(text, x, y [, maxWidth])
|
||||
context.font = '48px serif';
|
||||
context.fillText('Hello world', 10, 50);
|
||||
}
|
3
snipplets/code/JavaScript/fetch.js
Normal file
3
snipplets/code/JavaScript/fetch.js
Normal file
@ -0,0 +1,3 @@
|
||||
fetch('http://example.com/movies.json')
|
||||
.then(response => response.json())
|
||||
.then(data => console.log(data));
|
4
snipplets/code/JavaScript/location.href.js
Normal file
4
snipplets/code/JavaScript/location.href.js
Normal file
@ -0,0 +1,4 @@
|
||||
// Перейти на нужную страницу можно с помощью JavaScript
|
||||
// document.location.href = "https://www.site";
|
||||
|
||||
document.location.href = url.value;
|
5
snipplets/code/JavaScript/measureText.js
Normal file
5
snipplets/code/JavaScript/measureText.js
Normal file
@ -0,0 +1,5 @@
|
||||
const canvas = document.getElementById('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
let text = ctx.measureText('Hello world');
|
||||
console.log(text.width); // 56;
|
11
snipplets/code/JavaScript/spread.js
Normal file
11
snipplets/code/JavaScript/spread.js
Normal file
@ -0,0 +1,11 @@
|
||||
function sum(x, y, z) {
|
||||
return x + y + z;
|
||||
}
|
||||
|
||||
const numbers = [1, 2, 3];
|
||||
|
||||
console.log(sum(...numbers));
|
||||
// expected output: 6
|
||||
|
||||
console.log(sum.apply(null, numbers));
|
||||
// expected output: 6
|
3
snipplets/code/JavaScript/textContent.js
Normal file
3
snipplets/code/JavaScript/textContent.js
Normal file
@ -0,0 +1,3 @@
|
||||
document.getElementById('element').textContent;
|
||||
// If you need to target < IE9 then you need to use
|
||||
document.getElementById('element').innerText;
|
6
snipplets/code/JavaScript/timestamp_to_date.js
Normal file
6
snipplets/code/JavaScript/timestamp_to_date.js
Normal file
@ -0,0 +1,6 @@
|
||||
/*
|
||||
Необходимо timestamp умножить на 1000, поскольку JavaScript отсчитывает время
|
||||
с момента epoch (который равен 01/01/1970) в миллисекундах, а не в секундах.
|
||||
*/
|
||||
|
||||
let date = new Date(timestamp * 1000);
|
33
snipplets/code/JavaScript/webpack.md
Normal file
33
snipplets/code/JavaScript/webpack.md
Normal file
@ -0,0 +1,33 @@
|
||||
## WebPack
|
||||
`packages.json`
|
||||
```json
|
||||
"scripts": {
|
||||
"serve": "webpack serve",
|
||||
"html": "html-minifier --collapse-whitespace --remove-comments src/index.html --output dist/index.html",
|
||||
"css": "csso src/styles.css --output dist/styles.css",
|
||||
"build": "npm run html && npm run css && webpack --mode=production"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^5.42.0",
|
||||
"webpack-cli": "^4.7.2",
|
||||
"webpack-dev-server": "^3.11.2"
|
||||
}
|
||||
```
|
||||
`webpack.config.js`
|
||||
```javascript
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
entry: './src/index.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'engine.js',
|
||||
},
|
||||
devServer: {
|
||||
contentBase: path.join(__dirname, 'src'),
|
||||
compress: false,
|
||||
port: 55555,
|
||||
},
|
||||
};
|
||||
```
|
9
snipplets/code/JavaScript/xhrPostForm.js
Normal file
9
snipplets/code/JavaScript/xhrPostForm.js
Normal file
@ -0,0 +1,9 @@
|
||||
let data = new FormData();
|
||||
|
||||
data.append('item_id', 1);
|
||||
data.append('image_name', 'NAME');
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', '/v.php?type=image_delete', true);
|
||||
xhr.onload = function() { console.log(this.responseText); };
|
||||
xhr.send(data);
|
13
snipplets/code/PHP/Fenom.md
Normal file
13
snipplets/code/PHP/Fenom.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Fenom
|
||||
|
||||
## IF . ELSEIF . ELSE
|
||||
|
||||
```
|
||||
{if <expression>}
|
||||
{* ...code... *}
|
||||
{elseif <expression>}
|
||||
{* ...code... *}
|
||||
{else}
|
||||
{* ...code... *}
|
||||
{/if}
|
||||
```
|
16
snipplets/code/PHP/README.md
Normal file
16
snipplets/code/PHP/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# PHP
|
||||
|
||||
## std
|
||||
- [`setlocale`](setlocale.php) - Устанавливает настройки локали
|
||||
- [`gettype`](gettype.php) - Возвращает тип переменной
|
||||
- [`file_exists`](file_exists.php) - Проверяет существование указанного файла или каталога
|
||||
- [`ksort`](ksort.php) - Сортирует массив по ключу в порядке возрастания
|
||||
- [`array_reverse`](array_reverse.php) - Возвращает массив с элементами в обратном порядке
|
||||
- [`in_array`](in_array.php) - Проверяет, присутствует ли значение в массиве
|
||||
- [`json_decode`](json_decode.php) - Декодирует строку JSON
|
||||
- [`json_encode`](json_encode.php) - Возвращает JSON-представление данных
|
||||
- [`SQLite3`](sqlite3.php) - Простой использования класса SQLite3
|
||||
- [`mail`](mail.php) - Отправляет электронную почту
|
||||
|
||||
## Libs
|
||||
- [`Fenom`](Fenom.md) - fenom
|
22
snipplets/code/PHP/array_reverse.php
Normal file
22
snipplets/code/PHP/array_reverse.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
array_reverse(array $array, bool $preserve_keys = false): array
|
||||
|
||||
Принимает массив array и возвращает новый массив,
|
||||
содержащий элементы исходного массива в обратном порядке.
|
||||
*/
|
||||
|
||||
/*
|
||||
Список параметров:
|
||||
array
|
||||
Входной массив.
|
||||
|
||||
preserve_keys
|
||||
Если установлено в true, то числовые ключи будут сохранены.
|
||||
Нечисловые ключи не подвержены этой опции и всегда сохраняются.
|
||||
*/
|
||||
|
||||
$input = array("php", 4.0, array("green", "red"));
|
||||
$reversed = array_reverse($input);
|
||||
$preserved = array_reverse($input, true);
|
||||
?>
|
27
snipplets/code/PHP/file_exists.php
Normal file
27
snipplets/code/PHP/file_exists.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/*
|
||||
file_exists(string $filename): bool
|
||||
|
||||
Проверяет наличие указанного файла или каталога.
|
||||
*/
|
||||
|
||||
/*
|
||||
filename
|
||||
Путь к файлу или каталогу.
|
||||
|
||||
На платформах Windows, для проверки наличия файлов на сетевых ресурсах,
|
||||
используйте имена, подобные //computername/share/filename
|
||||
или \\computername\share\filename.
|
||||
|
||||
Возвращает true, если файл или каталог, указанный параметром filename,
|
||||
существует, иначе возвращает false.
|
||||
*/
|
||||
|
||||
$filename = '/path/to/foo.txt';
|
||||
|
||||
if (file_exists($filename)) {
|
||||
echo "Файл $filename существует";
|
||||
} else {
|
||||
echo "Файл $filename не существует";
|
||||
}
|
||||
?>
|
18
snipplets/code/PHP/gettype.php
Normal file
18
snipplets/code/PHP/gettype.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
// gettype(mixed $value): string
|
||||
$value = 1;
|
||||
|
||||
// Return Values
|
||||
// Possible values for the returned string are:
|
||||
//
|
||||
// "boolean"
|
||||
// "integer"
|
||||
// "double" (for historical reasons "double" is returned in case of a float, and not simply "float")
|
||||
// "string"
|
||||
// "array"
|
||||
// "object"
|
||||
// "resource"
|
||||
// "resource (closed)" as of PHP 7.2.0
|
||||
// "NULL"
|
||||
// "unknown type"
|
||||
?>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user