move dirs
This commit is contained in:
BIN
code/.assets/fondo para itchio.png
Normal file
BIN
code/.assets/fondo para itchio.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
BIN
code/.assets/monogram-extended.ttf
Normal file
BIN
code/.assets/monogram-extended.ttf
Normal file
Binary file not shown.
BIN
code/.assets/v-logo.png
Normal file
BIN
code/.assets/v-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
27
code/Arduino/README.md
Normal file
27
code/Arduino/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Arduino
|
||||
|
||||
## std
|
||||
|
||||
* [Пример, который возвращает дату и время компиляции скетча](compile_date_time.c)
|
||||
* [Размер типов перенных в байтах](variables_sizes.ino)
|
||||
* Пример работы с [EEPROM](eeprom.ino)
|
||||
|
||||
## Функции
|
||||
|
||||
* Функция, которая моргает встроенным светодиодом [`void init_blink(int times, int delay)`](init_blink.h)
|
||||
|
||||
## Память
|
||||
|
||||
| Тип | Чтение из программы | Запись из программы | Очистка при перезагрузке |
|
||||
|--------|---------------------|---------------------|--------------------------|
|
||||
| Flash | Да, PROGMEM | Можно, но сложно | Нет |
|
||||
| SRAM | Да | Да | Да |
|
||||
| EEPROM | Да | Да | Нет |
|
||||
|
||||
EEPROM представляет собой область памяти, состоящую из элементарных ячеек
|
||||
с размером в один байт (как SRAM). Объём EEPROM разный у разных моделей МК:
|
||||
|
||||
* ATmega328 (Arduino UNO, Nano, Pro Mini): `1 кБ`
|
||||
* ATmega2560 (Arduino Mega): `4 кБ`
|
||||
* ATtiny85 (Digispark): `512 Б`
|
||||
* ESP8266 / ESP32: `4096 Б`
|
||||
11
code/Arduino/compile_date_time.c
Normal file
11
code/Arduino/compile_date_time.c
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Пример, который возвращает дату и время компиляции скетча
|
||||
*/
|
||||
|
||||
void loop() {
|
||||
Serial.println("Built: " __DATE__ " | " __TIME__);
|
||||
/**
|
||||
* Output:
|
||||
* Built: Aug 16 2023 | 21:42:32
|
||||
*/
|
||||
}
|
||||
21
code/Arduino/convert_DATE_to_YYYY-MM-DD.c
Normal file
21
code/Arduino/convert_DATE_to_YYYY-MM-DD.c
Normal file
@@ -0,0 +1,21 @@
|
||||
// TODO: Добавить описание
|
||||
// TODO: Добавить в README.md
|
||||
|
||||
// Adapted from http://stackoverflow.com/questions/1765014/convert-string-from-date-into-a-time-t
|
||||
// Formats __DATE__ to YYYY-MM-DD format
|
||||
String ArduinoDateToDisplayDate(char const *time) {
|
||||
char s_month[5];
|
||||
int month, day, year;
|
||||
static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
|
||||
|
||||
sscanf(time, "%s %d %d", s_month, &day, &year);
|
||||
|
||||
month = (strstr(month_names, s_month)-month_names)/3;
|
||||
|
||||
String monthText = month < 10 ? "0" + String(month) : String(month);
|
||||
String dayText = day < 10 ? "0" + String(day) : String(day);
|
||||
|
||||
return String(year) + "-" + monthText + "-" + dayText;
|
||||
}
|
||||
|
||||
// https://gist.github.com/djohnson001/6df673a8d7f8ac04246a
|
||||
27
code/Arduino/eeprom.ino
Normal file
27
code/Arduino/eeprom.ino
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <EEPROM.h>
|
||||
|
||||
/**
|
||||
* EEPROM.write(адрес, данные) – пишет данные (только byte!) по адресу
|
||||
* EEPROM.update(адрес, данные) – обновляет (та же запись, но лучше) байт данных,
|
||||
* находящийся по адресу. Не реализована для esp8266/32!
|
||||
* EEPROM.read(адрес) – читает и возвращает байт данных, находящийся по адресу
|
||||
* EEPROM.put(адрес, данные) – записывает (по факту – обновляет, update) данные любого типа
|
||||
* (типа переданной переменной) по адресу
|
||||
* EEPROM.get(адрес, данные) – читает данные по адресу
|
||||
* и сам записывает их в данные – указанную переменную
|
||||
* EEPROM[] – библиотека позволяет работать с EEPROM памятью
|
||||
* как с обычным массивом типа byte (uint8_t)
|
||||
*/
|
||||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
Serial.println(EEPROM.read(10)); // выведет 255
|
||||
Serial.println(EEPROM.get(10)); // выведет 255
|
||||
Serial.println(EEPROM[10]); // выведет 255
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//
|
||||
}
|
||||
15
code/Arduino/init_blink.h
Normal file
15
code/Arduino/init_blink.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
}
|
||||
19
code/Arduino/serial.ino
Normal file
19
code/Arduino/serial.ino
Normal file
@@ -0,0 +1,19 @@
|
||||
// TODO: Доработать пример
|
||||
// TODO: Добавить в README.md
|
||||
|
||||
// будем искать слово hello
|
||||
char target[] = "hello";
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
if (Serial.available() > 0) {
|
||||
if (Serial.find(target))
|
||||
Serial.println("found");
|
||||
// вывести found, если было послано hello
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//
|
||||
}
|
||||
73
code/Arduino/variables_sizes.ino
Normal file
73
code/Arduino/variables_sizes.ino
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Скетч, который выводит в Serial размер типов переменных в байтах
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
size_t size_variable;
|
||||
|
||||
int example_int;
|
||||
unsigned int example_uint;
|
||||
signed int example_sint;
|
||||
unsigned long example_ulint;
|
||||
float example_float;
|
||||
double example_double;
|
||||
char example_char;
|
||||
char * example_string;
|
||||
bool example_bool;
|
||||
|
||||
size_variable = sizeof(example_int);
|
||||
Serial.print("int bytes size: " );
|
||||
Serial.println(size_variable);
|
||||
|
||||
size_variable = sizeof(example_uint);
|
||||
Serial.print("unsigned int bytes size: " );
|
||||
Serial.println(size_variable);
|
||||
|
||||
size_variable = sizeof(example_sint);
|
||||
Serial.print("signed int bytes size: " );
|
||||
Serial.println(size_variable);
|
||||
|
||||
size_variable = sizeof(example_ulint);
|
||||
Serial.print("unsigned long bytes size: " );
|
||||
Serial.println(size_variable);
|
||||
|
||||
size_variable = sizeof(example_float);
|
||||
Serial.print("float bytes size: " );
|
||||
Serial.println(size_variable);
|
||||
|
||||
size_variable = sizeof(example_double);
|
||||
Serial.print("double bytes size: " );
|
||||
Serial.println(size_variable);
|
||||
|
||||
size_variable = sizeof(example_char);
|
||||
Serial.print("char bytes size: " );
|
||||
Serial.println(size_variable);
|
||||
|
||||
size_variable = sizeof(example_string);
|
||||
Serial.print("char * bytes size: " );
|
||||
Serial.println(size_variable);
|
||||
|
||||
size_variable = sizeof(example_bool);
|
||||
Serial.print("bool bytes size: " );
|
||||
Serial.println(size_variable);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Arduino Nano
|
||||
*
|
||||
* int bytes size: 2
|
||||
* unsigned int bytes size: 2
|
||||
* signed int bytes size: 2
|
||||
* unsigned long bytes size: 4
|
||||
* float bytes size: 4
|
||||
* double bytes size: 4
|
||||
* char bytes size: 1
|
||||
* char * bytes size: 2
|
||||
* bool bytes size: 1
|
||||
*/
|
||||
5
code/Bash/README.md
Normal file
5
code/Bash/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Bash & Unix Shell
|
||||
|
||||
* [UnixSocket сервер на `nc`](unix-socket-server.sh)
|
||||
* [Проверка наличия команды](command_exists.s)
|
||||
* [Проверка наличия файла/директории](file_folder_exists.sh)
|
||||
14
code/Bash/command_exists.sh
Normal file
14
code/Bash/command_exists.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! [ -x "$(command -v git)" ]; then
|
||||
echo 'Error: git is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# OR
|
||||
|
||||
if ! command -v crystal &> /dev/null
|
||||
then
|
||||
echo "<the_command> could not be found"
|
||||
exit
|
||||
fi
|
||||
25
code/Bash/file_folder_exists.sh
Normal file
25
code/Bash/file_folder_exists.sh
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check file exists
|
||||
FILE=/etc/resolv.conf
|
||||
|
||||
if [ -f "$FILE" ]; then
|
||||
echo "$FILE exists."
|
||||
else
|
||||
echo "$FILE does not exist."
|
||||
fi
|
||||
|
||||
# OR
|
||||
|
||||
[ -f /etc/resolv.conf ] && echo "/etc/resolv.conf exists."
|
||||
|
||||
# Check directory exists
|
||||
DIR=/etc/docker
|
||||
|
||||
if [ -d "$DIR" ]; then
|
||||
echo "$DIR is a directory."
|
||||
fi
|
||||
|
||||
# OR
|
||||
|
||||
[ -d /etc/docker ] && echo "/etc/docker is a directory."
|
||||
29
code/Bash/irc_logger.sh
Executable file
29
code/Bash/irc_logger.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
# TODO: Добавить описание
|
||||
# TODO: Добавить в README.md
|
||||
|
||||
# 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
|
||||
19
code/Bash/unix-socket-server.sh
Executable file
19
code/Bash/unix-socket-server.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
# TODO: Добавить описание и пример работы
|
||||
|
||||
# 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
code/C/AF_INET_sockets/echo_client.c
Normal file
38
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
code/C/AF_INET_sockets/echo_server.c
Normal file
48
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
code/C/Makefile
Normal file
8
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
code/C/README.md
Normal file
9
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
code/C/atomic.c
Normal file
30
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);
|
||||
}
|
||||
4
code/C/buffer_len.h
Normal file
4
code/C/buffer_len.h
Normal file
@@ -0,0 +1,4 @@
|
||||
/* size_t strlen(const char *s); */
|
||||
|
||||
size_t length;
|
||||
length = strlen("Example string");
|
||||
10
code/C/clear_string.c
Normal file
10
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;
|
||||
}
|
||||
719
code/C/conio.h/README.md
Normal file
719
code/C/conio.h/README.md
Normal file
File diff suppressed because one or more lines are too long
BIN
code/C/conio.h/textattr_coding.png
Normal file
BIN
code/C/conio.h/textattr_coding.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
10
code/C/format-code
Executable file
10
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
code/C/libserialport/.editorconfig
Normal file
6
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
code/C/libserialport/.gitignore
vendored
Normal file
12
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
code/C/libserialport/Board/.gitignore
vendored
Normal file
1
code/C/libserialport/Board/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3party/
|
||||
24
code/C/libserialport/Board/Board.ino
Normal file
24
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
code/C/libserialport/Board/README.md
Normal file
3
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
code/C/libserialport/README.md
Normal file
18
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
code/C/libserialport/build_gcc
Executable file
20
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
code/C/libserialport/build_tcc
Executable file
20
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
code/C/libserialport/clear
Executable file
17
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
code/C/libserialport/format-code
Executable file
14
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
code/C/libserialport/listen.c
Normal file
133
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
code/C/read csv/example.csv
Normal file
3
code/C/read csv/example.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
id,text,desc
|
||||
1,ololo,none
|
||||
2,l33t,hack
|
||||
|
31
code/C/read csv/read_csv.c
Normal file
31
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;
|
||||
}
|
||||
2
code/C/rest_server/.editorconfig
Normal file
2
code/C/rest_server/.editorconfig
Normal file
@@ -0,0 +1,2 @@
|
||||
[{*.c,*.h}]
|
||||
indent_size = unset
|
||||
6
code/C/rest_server/.gitignore
vendored
Normal file
6
code/C/rest_server/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
orcania/
|
||||
ulfius/
|
||||
|
||||
*.a
|
||||
|
||||
rest
|
||||
7
code/C/rest_server/Makefile
Normal file
7
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
code/C/rest_server/README.md
Normal file
16
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
code/C/rest_server/main.c
Normal file
26
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
code/C/rest_server/qa/answer.png
Normal file
BIN
code/C/rest_server/qa/answer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
61
code/C/rest_server/qa/question.md
Normal file
61
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
code/C/rest_server/server.h
Normal file
75
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
code/C/rest_server/utils.h
Normal file
1
code/C/rest_server/utils.h
Normal file
@@ -0,0 +1 @@
|
||||
void print_to_terminal(char *text) { printf("%s", text); }
|
||||
12
code/C/rgbToHex.c
Normal file
12
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
code/C/sqlite/sqlite3_create.c
Normal file
52
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
code/C/sqlite/sqlite3_delete.c
Normal file
51
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
code/C/sqlite/sqlite3_insert.c
Normal file
55
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
code/C/sqlite/sqlite3_select.c
Normal file
50
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
code/C/sqlite/sqlite3_update.c
Normal file
51
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
code/C/thread.c
Normal file
31
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;
|
||||
}
|
||||
2
code/C/unixsocket/.editorconfig
Normal file
2
code/C/unixsocket/.editorconfig
Normal file
@@ -0,0 +1,2 @@
|
||||
[{*.c,*.h}]
|
||||
indent_size = unset
|
||||
BIN
code/C/unixsocket/a.out
Executable file
BIN
code/C/unixsocket/a.out
Executable file
Binary file not shown.
BIN
code/C/unixsocket/client
Executable file
BIN
code/C/unixsocket/client
Executable file
Binary file not shown.
79
code/C/unixsocket/client.c
Normal file
79
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
code/C/unixsocket/server
Executable file
BIN
code/C/unixsocket/server
Executable file
Binary file not shown.
123
code/C/unixsocket/server.c
Normal file
123
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);
|
||||
}
|
||||
2
code/C/webui/.editorconfig
Normal file
2
code/C/webui/.editorconfig
Normal file
@@ -0,0 +1,2 @@
|
||||
[{*.c,*.h}]
|
||||
indent_size = unset
|
||||
129
code/C/webui/call_c_from_js.c
Normal file
129
code/C/webui/call_c_from_js.c
Normal file
@@ -0,0 +1,129 @@
|
||||
// Call C from JavaScript Example
|
||||
|
||||
#include "webui.h"
|
||||
|
||||
void my_function_string(webui_event_t* e) {
|
||||
|
||||
// JavaScript:
|
||||
// webui_fn('MyID_One', 'Hello');
|
||||
|
||||
const char* str = webui_get_string(e);
|
||||
printf("my_function_string: %s\n", str); // Hello
|
||||
|
||||
// Need Multiple Arguments?
|
||||
//
|
||||
// WebUI support only one argument. To get multiple arguments
|
||||
// you can send a JSON string from JavaScript then decode it.
|
||||
// Example:
|
||||
//
|
||||
// my_json = my_json_decoder(str);
|
||||
// foo = my_json[0];
|
||||
// bar = my_json[1];
|
||||
}
|
||||
|
||||
void my_function_integer(webui_event_t* e) {
|
||||
|
||||
// JavaScript:
|
||||
// webui_fn('MyID_Two', 123456789);
|
||||
|
||||
long long number = webui_get_int(e);
|
||||
printf("my_function_integer: %lld\n", number); // 123456789
|
||||
}
|
||||
|
||||
void my_function_boolean(webui_event_t* e) {
|
||||
|
||||
// JavaScript:
|
||||
// webui_fn('MyID_Three', true);
|
||||
|
||||
bool status = webui_get_bool(e); // True
|
||||
if(status)
|
||||
printf("my_function_boolean: True\n");
|
||||
else
|
||||
printf("my_function_boolean: False\n");
|
||||
}
|
||||
|
||||
void my_function_with_response(webui_event_t* e) {
|
||||
|
||||
// JavaScript:
|
||||
// const result = webui_fn('MyID_Four', number);
|
||||
|
||||
long long number = webui_get_int(e);
|
||||
number = number * 2;
|
||||
printf("my_function_with_response: %lld\n", number);
|
||||
|
||||
// Send back the response to JavaScript
|
||||
webui_return_int(e, number);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
// HTML
|
||||
const char* my_html =
|
||||
"<html>"
|
||||
" <head>"
|
||||
" <title>Call C from JavaScript Example</title>"
|
||||
" <style>"
|
||||
" body {"
|
||||
" color: white;"
|
||||
" background: #0F2027;"
|
||||
" text-align: center;"
|
||||
" font-size: 16px;"
|
||||
" font-family: sans-serif;"
|
||||
" }"
|
||||
" </style>"
|
||||
" </head>"
|
||||
" <body>"
|
||||
" <h2>WebUI - Call C from JavaScript Example</h2>"
|
||||
" <p>Call C function with argument (<em>See the logs in your terminal</em>)</p>"
|
||||
" <br>"
|
||||
" <button onclick=\"webui_fn('MyID_One', 'Hello');\">Call my_function_string()</button>"
|
||||
" <br>"
|
||||
" <br>"
|
||||
" <button onclick=\"webui_fn('MyID_Two', 123456789);\">Call my_function_integer()</button>"
|
||||
" <br>"
|
||||
" <br>"
|
||||
" <button onclick=\"webui_fn('MyID_Three', true);\">Call my_function_boolean()</button>"
|
||||
" <br>"
|
||||
" <br>"
|
||||
" <p>Call C function and wait for the response</p>"
|
||||
" <br>"
|
||||
" <button onclick=\"MyJS();\">Call my_function_with_response()</button>"
|
||||
" <br>"
|
||||
" <br>"
|
||||
" <input type=\"text\" id=\"MyInputID\" value=\"2\">"
|
||||
" <script>"
|
||||
" function MyJS() {"
|
||||
" const MyInput = document.getElementById('MyInputID');"
|
||||
" const number = MyInput.value;"
|
||||
" webui_fn('MyID_Four', number).then((response) => {"
|
||||
" MyInput.value = response;"
|
||||
" });"
|
||||
" }"
|
||||
" </script>"
|
||||
" <script src=\"/webui.js\"></script>"
|
||||
" </body>"
|
||||
"</html>";
|
||||
|
||||
// Create a window
|
||||
size_t my_window = webui_new_window();
|
||||
|
||||
// Bind HTML elements with C functions
|
||||
webui_bind(my_window, "MyID_One", my_function_string);
|
||||
webui_bind(my_window, "MyID_Two", my_function_integer);
|
||||
webui_bind(my_window, "MyID_Three", my_function_boolean);
|
||||
webui_bind(my_window, "MyID_Four", my_function_with_response);
|
||||
|
||||
// Show the window
|
||||
webui_show(my_window, my_html); // webui_show_browser(my_window, my_html, Chrome);
|
||||
|
||||
// Wait until all windows get closed
|
||||
webui_wait();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
|
||||
return main();
|
||||
}
|
||||
#endif
|
||||
23
code/C/webui/index.html
Normal file
23
code/C/webui/index.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>ololo</title>
|
||||
<script src="/webui.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<button onclick="abc('string');">ssf</button>
|
||||
<br>
|
||||
<button id="clck">Click</button>
|
||||
<script type="text/javascript">
|
||||
window.onload = function () {
|
||||
window.resizeTo(500, 500);
|
||||
}
|
||||
|
||||
function abc(text) {
|
||||
webui_fn('MyID', text).then((response) => { console.log(response); });
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
24
code/C/webui/minimal.c
Normal file
24
code/C/webui/minimal.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <stdio.h>
|
||||
#include "webui.h"
|
||||
|
||||
void fn_one(webui_event_t *e) {
|
||||
const char *str = webui_get_string(e);
|
||||
printf("Data from JavaScript: %s\n", str);
|
||||
|
||||
webui_return_string(e, "Message from C");
|
||||
}
|
||||
|
||||
void fn_two(webui_event_t *e) { puts("Click!"); }
|
||||
|
||||
int main() {
|
||||
size_t my_window = webui_new_window();
|
||||
|
||||
webui_bind(my_window, "MyID", fn_one);
|
||||
webui_bind(my_window, "clck", fn_two);
|
||||
|
||||
webui_show(my_window, "index.html");
|
||||
webui_run(my_window, "alert('Fast!');");
|
||||
webui_wait();
|
||||
|
||||
return 0;
|
||||
}
|
||||
6
code/CSS/README.md
Normal file
6
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
code/CSS/back-image-cover.css
Normal file
8
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
code/CSS/base64.css
Normal file
3
code/CSS/base64.css
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-image: url('data:image/png;base64,%codeForImage%');
|
||||
}
|
||||
8
code/CSS/font-face.css
Normal file
8
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
code/CSS/pixel-art.css
Normal file
7
code/CSS/pixel-art.css
Normal file
@@ -0,0 +1,7 @@
|
||||
canvas {
|
||||
image-rendering: crisp-edges;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
/* JavaScript */
|
||||
/* context.imageSmoothingEnabled = false; */
|
||||
3
code/CSS/ul-remove-bullets.css
Normal file
3
code/CSS/ul-remove-bullets.css
Normal file
@@ -0,0 +1,3 @@
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
24
code/Crystal/Colorize.cr
Normal file
24
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
code/Crystal/README.md
Normal file
13
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
code/Crystal/UNIXSockets/by_faustinoaq/client.cr
Normal file
28
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}"
|
||||
}
|
||||
1
code/Crystal/UNIXSockets/by_faustinoaq/link.txt
Normal file
1
code/Crystal/UNIXSockets/by_faustinoaq/link.txt
Normal file
@@ -0,0 +1 @@
|
||||
https://github.com/crystal-lang/crystal/issues/4277#issuecomment-294009173
|
||||
38
code/Crystal/UNIXSockets/by_faustinoaq/server.cr
Normal file
38
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
code/Crystal/UNIXSockets/client.cr
Normal file
24
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
code/Crystal/UNIXSockets/server.cr
Normal file
46
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
code/Crystal/ctrl-c_interrupt.cr
Normal file
9
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
code/Crystal/env_variable.cr
Normal file
3
code/Crystal/env_variable.cr
Normal file
@@ -0,0 +1,3 @@
|
||||
shell = ENV["SHELL"]
|
||||
|
||||
puts "SHELL: #{shell}\nLANG: #{ENV["COLORTERM"]}"
|
||||
11
code/Crystal/http_client.cr
Normal file
11
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
code/Crystal/irc_bot.cr
Normal file
24
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
code/Crystal/json.cr
Normal file
5
code/Crystal/json.cr
Normal file
@@ -0,0 +1,5 @@
|
||||
require "json"
|
||||
|
||||
# Парсинг строки
|
||||
value = JSON.parse("[1, 2, 3]")
|
||||
p! value[0]
|
||||
2
code/Crystal/prompt_timeout.cr
Normal file
2
code/Crystal/prompt_timeout.cr
Normal file
@@ -0,0 +1,2 @@
|
||||
STDIN.read_timeout = 1
|
||||
STDIN.gets # raises IO::TimeoutError (after 1 second)
|
||||
18
code/Crystal/schedule.cr
Normal file
18
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
code/Crystal/value_from_match.cr
Normal file
8
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
code/Gambas/array_foreach.bas
Normal file
8
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
|
||||
5
code/GameMaker/README.md
Normal file
5
code/GameMaker/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# GameMaker Studio
|
||||
|
||||
* [Переключатель Fullscreen](fullscreen_toggle.gml)
|
||||
* [RGB фон комнаты](room_background.gml)
|
||||
* [Пример рисования текста](draw_text.gml)
|
||||
13
code/GameMaker/draw_text.gml
Normal file
13
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
code/GameMaker/fullscreen_toggle.gml
Normal file
8
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);
|
||||
}
|
||||
5
code/GameMaker/room_background.gml
Normal file
5
code/GameMaker/room_background.gml
Normal file
@@ -0,0 +1,5 @@
|
||||
/// @description RGB room background
|
||||
|
||||
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
code/HTML/README.md
Normal file
7
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
code/HTML/SEMATIC-HTML5.md
Normal file
128
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
code/HTML/anchors.html
Normal file
3
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
code/HTML/favicons.html
Normal file
9
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
code/HTML/humans.txt
Normal file
13
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
code/HTML/update-css.html
Normal file
3
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
code/HTTP/README.md
Normal file
17
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
code/JavaScript/Intl.DateTimeFormat.js
Normal file
74
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
code/JavaScript/Object.entries.js
Normal file
8
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
code/JavaScript/README.md
Normal file
30
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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user