This commit is contained in:
cfif 2025-06-02 13:26:42 +03:00
commit 23d84ae09a
8 changed files with 2904 additions and 0 deletions

23
modular.json Normal file
View File

@ -0,0 +1,23 @@
{
"dep": [
{
"type": "git",
"provider": "Smart_Components_Aurus",
"repo": "SerialPortInterface"
},
{
"type": "git",
"provider": "Smart_Components_Aurus",
"repo": "SystemDelayInterface"
}
],
"cmake": {
"inc_dirs": [
"./"
],
"srcs": [
"./**.c"
]
}
}

16
snprintf.c Executable file
View File

@ -0,0 +1,16 @@
#include "stream.h"
int
debug_sprintf (char *buf, int size, const char *fmt, ...)
{
stream_buf_t u;
va_list args;
int err;
stropen (&u, buf, size);
va_start (args, fmt);
err = vprintf (&u, fmt, args);
va_end (args);
strclose (&u);
return err;
}

46
sscanf.c Executable file
View File

@ -0,0 +1,46 @@
#include "stream.h"
int debug_scanf (const unsigned char *buf, const char *fmt, ...) {
stream_buf_t u;
va_list args;
int err;
stropen (&u, (unsigned char*) buf, 0);
va_start (args, fmt);
err = vscanf (&u, fmt, args);
va_end (args);
return err;
}
#ifdef TEST
/*
* Testing sscanf(3).
*/
#undef printf
int printf (const char *format, ...);
int
main (void)
{
int i;
short s;
long l;
char a[20], b[20];
sscanf (" -123 +123 123xyzwvabcdefghijk ", " %d%ho%lx%5c%s",
&i, &s, &l, a, b);
printf ("i=%d s=%d l=%ld a=`%.5s' b=`%s'\n",
i, s, l, a, b);
sscanf ("abc0123456789xyz", "abc%[0123456789]xyz", a);
printf ("a =`%s'\n", a);
sscanf ("abc0123456789xyz", "abc%[0-9]xyz", a);
printf ("a =`%s'\n", a);
sscanf ("abc0123456789xyz", "abc%[^a-z]xyz", a);
printf ("a =`%s'\n", a);
return 0;
}
#endif

91
stream.h Executable file
View File

@ -0,0 +1,91 @@
#ifndef __STREAM_FAST_H_
#define __STREAM_FAST_H_ 1
#include "SerialPortIO.h"
#include <stdarg.h>
#include <ctype.h>
#define bool_t int
#define FETCH_BYTE(p) (*(unsigned char*)(p))
int debug_printf (tSerialPortIO *portIo, const char *fmt, ...);
/*
* Поток данных.
* Имеет интерфейс, состоящий из четырех процедур:
* выдача байта, опрос последнего выданного байта,
* прием байта, и опрос первого байта во входящей очереди без удаления.
*/
typedef struct _stream_t {
struct _stream_interface_t *interface;
} stream_t;
typedef struct _stream_interface_t {
void (*putc) (stream_t *u, short c);
unsigned short (*getc) (stream_t *u);
int (*peekc) (stream_t *u);
void (*flush) (stream_t *u);
bool_t (*eof) (stream_t *u);
void (*close) (stream_t *u);
} stream_interface_t;
#define to_stream(x) ((stream_t*)&(x)->interface)
/*
* Методы приходится делать в виде макросов,
* т.к. необходимо приведение типа к родительскому.
*/
#define putchar(x,s) (x)->interface->putc(to_stream (x), s)
#define getchar(x) (x)->interface->getc(to_stream (x))
#define peekchar(x) (x)->interface->peekc(to_stream (x))
#define fflush(x) if ((x)->interface->flush) \
(x)->interface->flush(to_stream (x))
#define feof(x) ((x)->interface->eof ? \
(x)->interface->eof(to_stream (x)) : 0)
#define fclose(x) if ((x)->interface->close) \
(x)->interface->close(to_stream (x))
#define freceiver(x) ((x)->interface->receiver ? \
(x)->interface->receiver(to_stream (x)) : 0)
#define puts(x,str) stream_puts (to_stream (x), str)
#define gets(x,str,n) stream_gets (to_stream (x), str, n)
#define vprintf(x,f,a) stream_vprintf (to_stream (x), f, a)
#define vscanf(x,f,a) stream_vscanf (to_stream (x), f, a)
/* LY: умышленно вызываем ошибки там, где без необходимости вместо puts() используется printf() */
#define printf(x,f,...) stream_printf (to_stream (x), f, ##__VA_ARGS__)
void drain_input (stream_t *u); /* LY: чистит забуферизированный в потоке ввод. */
int stream_puts (stream_t *u, const char *str);
unsigned char *stream_gets (stream_t *u, unsigned char *str, int len);
//int stream_printf (stream_t *u, const char *fmt, ...);
int stream_vprintf (stream_t *u, const char *fmt, va_list args);
int stream_scanf (stream_t *u, const char *fmt, ...);
int stream_vscanf (stream_t *u, const char *fmt, va_list argp);
int debug_sprintf (char *buf, int size, const char *fmt, ...);
//int vsnprintf (unsigned char *buf, int size, const char *fmt, va_list args);
int stream_serial_vprintf (tSerialPortIO *stream, char const *fmt, va_list args);
int debug_scanf (const unsigned char *buf, const char *fmt, ...);
/*
* Вывод в строку как в поток.
* Для snprintf и т.п.
*/
typedef struct {
const stream_interface_t *interface;
unsigned char *buf;
int size;
} stream_buf_t;
stream_t *stropen (stream_buf_t *u, unsigned char *buf, int size);
void strclose (stream_buf_t *u);
/*
* LY: выдает результат vprintf без печати, т.е. считает кол-во символов.
*/
int vprintf_getlen (const char *fmt, va_list args);
extern stream_t null_stream;
#endif /* __STREAM_FAST_H_ */

81
stropen.c Executable file
View File

@ -0,0 +1,81 @@
#include "stream.h"
static void
buf_putchar (stream_buf_t *u, short c)
{
if (u->size > 1) {
/* TODO: unicode to utf8 conversion. */
*u->buf++ = c;
--u->size;
}
}
static unsigned short
buf_getchar (stream_buf_t *u)
{
/* TODO: utf8 to unicode conversion. */
unsigned char c = *u->buf;
if (! c)
return 0;
++u->buf;
return c;
}
static int
buf_peekchar (stream_buf_t *u)
{
/* TODO: utf8 to unicode conversion. */
unsigned char c = *u->buf;
if (! c)
return -1;
return c;
}
static bool_t
buf_feof (stream_buf_t *u)
{
return ! *u->buf;
}
static stream_interface_t buf_interface = {
.putc =
#if __STDC__
(void (*) (stream_t*, short))
#endif
buf_putchar,
.getc =
#if __STDC__
(unsigned short (*) (stream_t*))
#endif
buf_getchar,
.peekc =
#if __STDC__
(int (*) (stream_t*))
#endif
buf_peekchar,
.eof =
#if __STDC__
(bool_t (*) (stream_t*))
#endif
buf_feof,
};
stream_t *
stropen (stream_buf_t *u, unsigned char *buf, int size)
{
u->interface = &buf_interface;
u->buf = buf;
u->size = size;
return (stream_t*) u;
}
void
strclose (stream_buf_t *u)
{
if (u->size > 0) {
*u->buf++ = 0;
--u->size;
}
}

1175
vprintf.c Executable file

File diff suppressed because it is too large Load Diff

1196
vprintfSerial.c Normal file

File diff suppressed because it is too large Load Diff

276
vscanf.c Executable file
View File

@ -0,0 +1,276 @@
#include "cmsis_os.h"
#include "SerialPortIO.h"
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include "SystemDelayInterface.h"
//#include "BaseTypes.h"
#include <stdbool.h>
#include "stream.h"
#define SHORT 0
#define REGULAR 1
#define LONG 2
#define ISSPACE(c) (c==' ' || c=='\t' || c=='\n')
#define ISDIGIT(c,base) ((c>='0' && c<='9') || (base==16 && \
(('a'<=c && c<='f') || ('A'<=c && c<='F'))))
static unsigned char
scan_number (stream_t *stream, void *ptr, unsigned char base,
unsigned short len, unsigned char size)
{
int c;
long val;
unsigned char negate;
/* Skip spaces. */
for (;;) {
c = peekchar (stream);
if (c < 0)
return 0;
if (! ISSPACE ((unsigned char) c))
break;
getchar (stream);
}
/* Get sign. */
negate = 0;
if (c == '-' || c == '+') {
if (c == '-')
negate = 1;
getchar (stream);
len--;
if (len == 0 || feof (stream))
return 0;
c = peekchar (stream);
}
if (! ISDIGIT (c, base))
return 0;
val = 0;
while (len-- > 0) {
/* Scan digits. */
if (! ISDIGIT (c, base))
break;
if (ptr) {
/* Get next digit. */
if (base == 8) val <<= 3;
else if (base == 10) val *= 10;
else val <<= 4;
if ('0' <= c && c <= '9') c -= '0';
else if ('a' <= c && c <= 'f') c -= 'a' - 10;
else c -= 'A' - 10;
val += c;
}
getchar (stream);
c = peekchar (stream);
if (c < 0)
break;
}
if (! ptr)
return 0;
if (negate)
val = -val;
switch (size) {
case SHORT:
*(short*) ptr = val;
break;
case REGULAR:
*(int*) ptr = val;
break;
case LONG:
*(long*) ptr = val;
break;
}
return 1;
}
static unsigned char
match_pattern (unsigned char sym, const char *pattern)
{
unsigned char next, inversion, cstart, cend;
inversion = 0;
next = FETCH_BYTE (pattern++);
if (next == '^') {
inversion = 1;
next = FETCH_BYTE (pattern++);
}
while (next != ']') {
if (next == '\0')
return 0; /* unterminated [ */
cstart = cend = next;
next = FETCH_BYTE (pattern++);
if (next == '-' && (cend = FETCH_BYTE (pattern)) != ']') {
if (cend == '\0')
return 0;
++pattern;
next = FETCH_BYTE (pattern++);
}
if (sym >= cstart && sym <= cend)
return ! inversion;
}
return inversion;
}
static unsigned char
scan_string (stream_t *stream, char *ptr, unsigned char type,
unsigned short len, const char *pattern)
{
unsigned char ch = 0;
char *optr;
optr = ptr;
while (! feof (stream)) {
ch = getchar (stream);
/* Skip spaces, for 's'-format. */
if (type != 's' || ! ISSPACE (ch))
break;
}
while (! feof (stream)) {
if (type == 's') {
if (ISSPACE (ch))
break;
} else if (type == '[') {
if (! match_pattern (ch, pattern))
break;
}
if (ptr)
*ptr++ = ch;
if (--len <= 0)
break;
ch = getchar (stream);
}
if (ptr != optr) {
if (type != 'c')
*ptr++ = '\0';
return 1;
}
return 0;
}
/*
* Scan and recognize input according to a format
*/
int
stream_vscanf (stream_t *stream,
const char *fmt, /* Format string for the scanf */
va_list argp) /* Arguments to scanf */
{
unsigned char ch, size, base;
unsigned short len;
int nmatch, ic;
void *ptr;
const char *pattern = 0;
nmatch = 0;
for (;;) switch (ch = FETCH_BYTE (fmt++)) {
case '\0':
return nmatch;
case '%':
ch = FETCH_BYTE (fmt++);
if (ch == '%')
goto def;
if (ch != '*')
ptr = va_arg (argp, void*);
else {
ptr = 0;
ch = FETCH_BYTE (fmt++);
}
len = 0;
size = REGULAR;
while (ch >= '0' && ch <= '9') {
len = len*10 + ch - '0';
ch = FETCH_BYTE (fmt++);
}
if (len == 0)
len = 30000;
if (ch == 'l') {
ch = FETCH_BYTE (fmt++);
size = LONG;
} else if (ch == 'h') {
size = SHORT;
ch = FETCH_BYTE (fmt++);
} else if (ch == '[') {
pattern = fmt;
ch = FETCH_BYTE (fmt);
if (ch == '^')
ch = FETCH_BYTE (++fmt);
while (ch != 0 && ch != ']')
ch = FETCH_BYTE (++fmt);
if (ch != 0)
++fmt;
ch = '[';
}
if (ch >= 'A' && ch <= 'Z') {
ch = ch + 'a' - 'A';
size = LONG;
}
switch (ch) {
case 0:
return -1;
case 'c':
if (len == 30000)
len = 1;
goto string;
case 's':
case '[':
string: if (scan_string (stream, (char*) ptr, ch, len,
pattern) && ptr)
++nmatch;
break;
case 'o':
base = 8;
goto number;
case 'x':
base = 16;
goto number;
case 'd':
base = 10;
number: if (scan_number (stream, ptr, base, len, size) && ptr)
++nmatch;
break;
}
if (feof (stream))
return nmatch ? nmatch : -1;
break;
case ' ':
case '\n':
case '\t':
/* Skip spaces. */
for (;;) {
ic = peekchar (stream);
if (ic < 0)
break;
if (! ISSPACE ((unsigned char) ic))
break;
getchar (stream);
}
break;
default:
def: ic = peekchar (stream);
if (ic < 0)
return -1;
if ((unsigned char) ic != ch)
return nmatch;
getchar (stream);
}
}