Перенос на новую организацию GONEC
This commit is contained in:
commit
00cc6d4af3
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"dep": [
|
||||
{
|
||||
"type": "git",
|
||||
"provider": "GONEC",
|
||||
"repo": "SerialPortInterface"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "git",
|
||||
"provider": "GONEC",
|
||||
"repo": "SystemDelayInterface"
|
||||
}
|
||||
],
|
||||
"cmake": {
|
||||
"inc_dirs": [
|
||||
"./"
|
||||
],
|
||||
"srcs": [
|
||||
"./**.c"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue