vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.89k stars 2.17k forks source link

can't decode json from a websocket #7531

Closed FrictionlessMike closed 3 years ago

FrictionlessMike commented 3 years ago
$ v doctor
OS: linux, "Void Linux"
Processor: 4 cpus, 64bit, little endian, AMD A10-5750M APU with Radeon(tm) HD Graphics
CC version: cc (GCC) 9.3.0

getwd: /home/void
vmodules: /home/void/.vmodules
vroot: /home/void/code/vlang/v
vexe: /home/void/code/vlang/v/v
vexe mtime: 2020-12-24 08:32:36
is vroot writable: true
is vmodules writable: true
V full version: V 0.2 36dcace.f7787ff

Git version: git version 2.29.2
Git vroot status: 0.1.29-1529-gf7787ff0-dirty
.git/config present: true
thirdparty/tcc status: thirdparty-linux-amd64 7543de81

If it matters, I get the same behavior having done rm -rf ~/.vmodules /tmp/v*.

tldr: calling json.decode fails to compile with the error undefined reference tojson__decode_main__Trade'` when decoding a string from a websocket. It can decode a string literal copied from the output of the websocket. It can, for some reason, also decode strings from the websocket if it has first decoded a string literal.

The offending code is modified from the websocket example that comes with vlib. Here are the interesting bits, with the full code further down:

struct Trade {
    eventtype    string  [json: e]
    tradenumber  int     [json: E]
    symbol       string  [json: s]
    unixtime     int     [json: t]
    price        string  [json: p]
    quantity     string  [json: q]
    bid          int     [json: b]
    ask          int     [json: a]
    timeagain    int     [json: T]
    maker        bool    [json: m]
    taker        bool    [json: M]
}

tr := '{"e":"trade", "E":1608790644305, "s":"BTCUSDT", "t":523514730, "p":"23011.82000000", "q":"0.00590000", "b":4006258168, "a":4006258331, "T":1608790644304, "m":true, "M":true}'
dumbtrade := json.decode(Trade, tr) or { return }

    ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? {
        if msg.payload.len > 0 {
            message := msg.payload.bytestr()
            message_decoded := json.decode(Trade, message) or { eprintln('json trade decode failed') return }
            price := strconv.atof64(message_decoded.price)
            mut f := os.create('/tmp/btc') or { panic(err) }
            f.writeln("${price:5.2f}\n")
            f.flush()
            f.close()
        }
    })

dumbtrade is never used or referenced anywhere in the code, but if it's never defined, compilation fails with this error:

/bin/ld: /tmp/ccsgjeGA.o: in function `anon_1853_57_61_16777217':
/tmp/v/ticker.4939203533116683666.tmp.c:3645: undefined reference to `json__decode_main__Trade'
collect2: error: ld returned 1 exit status

along with hundreds of warnings:

In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h: In function 'atomic_load_ptr':
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:310:9: warning: returning 'uintptr_t' {aka 'long unsigned int'} from a function with return type 'void *' makes pointer from integer without a cast [-Wint-conversion]
  310 |  return atomic_load_explicit((_Atomic uintptr_t*)x, memory_order_seq_cst);
      |         ^~~~~~~~~~~~~~~~~~~~
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h: In function 'atomic_store_ptr':
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:313:2: warning: initialization of 'uintptr_t' {aka 'long unsigned int'} from 'void *' makes integer from pointer without a cast [-Wint-conversion]
  313 |  atomic_store_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
      |  ^~~~~~~~~~~~~~~~~~~~~
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h: In function 'atomic_compare_exchange_weak_ptr':
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:316:14: warning: initialization of 'uintptr_t' {aka 'long unsigned int'} from 'void *' makes integer from pointer without a cast [-Wint-conversion]
  316 |  return (int)atomic_compare_exchange_weak_explicit((_Atomic uintptr_t*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst);
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h: In function 'atomic_compare_exchange_strong_ptr':
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:319:14: warning: initialization of 'uintptr_t' {aka 'long unsigned int'} from 'void *' makes integer from pointer without a cast [-Wint-conversion]
  319 |  return (int)atomic_compare_exchange_strong_explicit((_Atomic uintptr_t*)x, expected, y, memory_order_seq_cst, memory_order_seq_cst);
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h: In function 'atomic_exchange_ptr':
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:322:9: warning: initialization of 'uintptr_t' {aka 'long unsigned int'} from 'void *' makes integer from pointer without a cast [-Wint-conversion]
  322 |  return atomic_exchange_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:322:9: warning: returning 'uintptr_t' {aka 'long unsigned int'} from a function with return type 'void *' makes pointer from integer without a cast [-Wint-conversion]
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h: In function 'atomic_fetch_add_ptr':
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:325:9: warning: returning 'long unsigned int' from a function with return type 'void *' makes pointer from integer without a cast [-Wint-conversion]
  325 |  return atomic_fetch_add_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h: In function 'atomic_fetch_sub_ptr':
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:328:9: warning: returning 'long unsigned int' from a function with return type 'void *' makes pointer from integer without a cast [-Wint-conversion]
  328 |  return atomic_fetch_sub_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h: In function 'atomic_fetch_and_ptr':
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:331:9: warning: returning 'long unsigned int' from a function with return type 'void *' makes pointer from integer without a cast [-Wint-conversion]
  331 |  return atomic_fetch_and_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h: In function 'atomic_fetch_or_ptr':
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:334:9: warning: returning 'long unsigned int' from a function with return type 'void *' makes pointer from integer without a cast [-Wint-conversion]
  334 |  return atomic_fetch_or_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h: In function 'atomic_fetch_xor_ptr':
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:337:9: warning: returning 'long unsigned int' from a function with return type 'void *' makes pointer from integer without a cast [-Wint-conversion]
  337 |  return atomic_fetch_xor_explicit((_Atomic uintptr_t*)x, y, memory_order_seq_cst);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'net__new_addr':
/tmp/v/ticker.5319160554567415405.tmp.c:15940:17: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
15940 |   charptr res = inet_ntop(net__SocketFamily_inet, &addr, buf.data, buf.len);
      |                 ^~~~~~~~~
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'net__TcpConn_peer_ip':
/tmp/v/ticker.5319160554567415405.tmp.c:16322:17: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
16322 |  charptr cstr = inet_ntop(AF_INET, &peeraddr.sin_addr, buf, /*SizeOfVar*/ sizeof(buf));
      |                 ^~~~~~~~~
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'x__openssl__SSLConn_shutdown':
/tmp/v/ticker.5319160554567415405.tmp.c:17548:24: warning: passing argument 1 of 'SSL_shutdown' from incompatible pointer type [-Wincompatible-pointer-types]
17548 |    res = SSL_shutdown(s->ssl);
      |                       ~^~~~~
      |                        |
      |                        struct SSL *
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:756:
/usr/include/openssl/ssl.h:1488:23: note: expected 'SSL *' {aka 'struct ssl_st *'} but argument is of type 'struct SSL *'
 1488 | int SSL_shutdown(SSL *s);
      |                  ~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:17582:16: warning: passing argument 1 of 'SSL_free' from incompatible pointer type [-Wincompatible-pointer-types]
17582 |      SSL_free(s->ssl);
      |               ~^~~~~
      |                |
      |                struct SSL *
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:756:
/usr/include/openssl/ssl.h:1433:20: note: expected 'SSL *' {aka 'struct ssl_st *'} but argument is of type 'struct SSL *'
 1433 | void SSL_free(SSL *ssl);
      |               ~~~~~^~~
/tmp/v/ticker.5319160554567415405.tmp.c:17590:16: warning: passing argument 1 of 'SSL_free' from incompatible pointer type [-Wincompatible-pointer-types]
17590 |      SSL_free(s->ssl);
      |               ~^~~~~
      |                |
      |                struct SSL *
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:756:
/usr/include/openssl/ssl.h:1433:20: note: expected 'SSL *' {aka 'struct ssl_st *'} but argument is of type 'struct SSL *'
 1433 | void SSL_free(SSL *ssl);
      |               ~~~~~^~~
/tmp/v/ticker.5319160554567415405.tmp.c:17603:13: warning: passing argument 1 of 'SSL_free' from incompatible pointer type [-Wincompatible-pointer-types]
17603 |   SSL_free(s->ssl);
      |            ~^~~~~
      |             |
      |             struct SSL *
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:756:
/usr/include/openssl/ssl.h:1433:20: note: expected 'SSL *' {aka 'struct ssl_st *'} but argument is of type 'struct SSL *'
 1433 | void SSL_free(SSL *ssl);
      |               ~~~~~^~~
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'x__openssl__SSLConn_connect':
/tmp/v/ticker.5319160554567415405.tmp.c:17620:9: warning: assignment to 'struct SSL *' from incompatible pointer type 'SSL *' {aka 'struct ssl_st *'} [-Wincompatible-pointer-types]
17620 |  s->ssl = SSL_new(s->sslctx);
      |         ^
In file included from /usr/include/openssl/ssl.h:884,
                 from /tmp/v/ticker.5319160554567415405.tmp.c:756:
/tmp/v/ticker.5319160554567415405.tmp.c:17625:38: warning: passing argument 1 of 'SSL_ctrl' from incompatible pointer type [-Wincompatible-pointer-types]
17625 |  int res = SSL_set_tlsext_host_name(s->ssl, hostname.str);
      |                                     ~^~~~~
      |                                      |
      |                                      struct SSL *
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:756:
/usr/include/openssl/ssl.h:1441:20: note: expected 'SSL *' {aka 'struct ssl_st *'} but argument is of type 'struct SSL *'
 1441 | long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
      |               ~~~~~^~~
/tmp/v/ticker.5319160554567415405.tmp.c:17630:18: warning: passing argument 1 of 'SSL_set_fd' from incompatible pointer type [-Wincompatible-pointer-types]
17630 |  if (SSL_set_fd(s->ssl, tcp_conn->sock.handle) != 1) {
      |                 ~^~~~~
      |                  |
      |                  struct SSL *
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:756:
/usr/include/openssl/ssl.h:1312:21: note: expected 'SSL *' {aka 'struct ssl_st *'} but argument is of type 'struct SSL *'
 1312 | int SSL_set_fd(SSL *s, int fd);
      |                ~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:17635:22: warning: passing argument 1 of 'SSL_connect' from incompatible pointer type [-Wincompatible-pointer-types]
17635 |   res = SSL_connect(s->ssl);
      |                     ~^~~~~
      |                      |
      |                      struct SSL *
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:756:
/usr/include/openssl/ssl.h:1436:23: note: expected 'SSL *' {aka 'struct ssl_st *'} but argument is of type 'struct SSL *'
 1436 | int  SSL_connect(SSL *ssl);
      |                  ~~~~~^~~
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'x__openssl__SSLConn_socket_read_into_ptr':
/tmp/v/ticker.5319160554567415405.tmp.c:17679:19: warning: passing argument 1 of 'SSL_read' from incompatible pointer type [-Wincompatible-pointer-types]
17679 |   res = SSL_read(s->ssl, buf_ptr, len);
      |                  ~^~~~~
      |                   |
      |                   struct SSL *
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:756:
/usr/include/openssl/ssl.h:1438:20: note: expected 'SSL *' {aka 'struct ssl_st *'} but argument is of type 'struct SSL *'
 1438 | int  SSL_read(SSL *ssl, void *buf, int num);
      |               ~~~~~^~~
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'x__openssl__SSLConn_write':
/tmp/v/ticker.5319160554567415405.tmp.c:17744:26: warning: passing argument 1 of 'SSL_write' from incompatible pointer type [-Wincompatible-pointer-types]
17744 |    int sent = SSL_write(s->ssl, ptr, remaining);
      |                         ~^~~~~
      |                          |
      |                          struct SSL *
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:756:
/usr/include/openssl/ssl.h:1440:21: note: expected 'SSL *' {aka 'struct ssl_st *'} but argument is of type 'struct SSL *'
 1440 | int  SSL_write(SSL *ssl, const void *buf, int num);
      |                ~~~~~^~~
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'sync__Channel_close':
/tmp/v/ticker.5319160554567415405.tmp.c:18358:43: warning: passing argument 1 of 'atomic_compare_exchange_weak_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18358 |   if (!(!atomic_compare_exchange_weak_ptr(&ch->adr_written, &nulladr, ((voidptr)(-1))))) break;
      |                                           ^~~~~~~~~~~~~~~~
      |                                           |
      |                                           _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:315:59: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  315 | static inline int atomic_compare_exchange_weak_ptr(void** x, void** expected, void* y) {
      |                                                    ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'sync__Channel_try_push_priv':
/tmp/v/ticker.5319160554567415405.tmp.c:18410:35: warning: passing argument 1 of 'atomic_load_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18410 |   voidptr wradr = atomic_load_ptr(&ch->write_adr);
      |                                   ^~~~~~~~~~~~~~
      |                                   |
      |                                   _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:309:44: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  309 | static inline void* atomic_load_ptr(void** x) {
      |                                     ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18413:43: warning: passing argument 1 of 'atomic_compare_exchange_strong_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18413 |    if (atomic_compare_exchange_strong_ptr(&ch->write_adr, &wradr, ((voidptr)(0)))) {
      |                                           ^~~~~~~~~~~~~~
      |                                           |
      |                                           _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:318:61: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  318 | static inline int atomic_compare_exchange_strong_ptr(void** x, void** expected, void* y) {
      |                                                      ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18417:46: warning: passing argument 1 of 'atomic_compare_exchange_weak_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18417 |      if (!(!atomic_compare_exchange_weak_ptr(&ch->adr_written, &nulladr, wradr))) break;
      |                                              ^~~~~~~~~~~~~~~~
      |                                              |
      |                                              _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:315:59: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  315 | static inline int atomic_compare_exchange_weak_ptr(void** x, void** expected, void* y) {
      |                                                    ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18441:21: warning: passing argument 1 of 'atomic_store_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18441 |    atomic_store_ptr(&ch->read_adr, src);
      |                     ^~~~~~~~~~~~~
      |                     |
      |                     _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:312:44: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  312 | static inline void atomic_store_ptr(void** x, void* y) {
      |                                     ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18442:28: warning: passing argument 1 of 'atomic_load_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18442 |    wradr = atomic_load_ptr(&ch->write_adr);
      |                            ^~~~~~~~~~~~~~
      |                            |
      |                            _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:309:44: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  309 | static inline void* atomic_load_ptr(void** x) {
      |                                     ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18445:44: warning: passing argument 1 of 'atomic_compare_exchange_strong_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18445 |     if (atomic_compare_exchange_strong_ptr(&ch->read_adr, &src2, ((voidptr)(0)))) {
      |                                            ^~~~~~~~~~~~~
      |                                            |
      |                                            _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:318:61: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  318 | static inline int atomic_compare_exchange_strong_ptr(void** x, void** expected, void* y) {
      |                                                      ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18465:44: warning: passing argument 1 of 'atomic_compare_exchange_strong_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18465 |     if (atomic_compare_exchange_strong_ptr(&ch->adr_read, &src2, ((voidptr)(0)))) {
      |                                            ^~~~~~~~~~~~~
      |                                            |
      |                                            _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:318:61: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  318 | static inline int atomic_compare_exchange_strong_ptr(void** x, void** expected, void* y) {
      |                                                      ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18485:60: warning: passing argument 1 of 'atomic_compare_exchange_strong_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18485 |     if (have_swapped || atomic_compare_exchange_strong_ptr(&ch->adr_read, &src2, ((voidptr)(0)))) {
      |                                                            ^~~~~~~~~~~~~
      |                                                            |
      |                                                            _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:318:61: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  318 | static inline int atomic_compare_exchange_strong_ptr(void** x, void** expected, void* y) {
      |                                                      ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18528:46: warning: passing argument 1 of 'atomic_compare_exchange_weak_u16' from incompatible pointer type [-Wincompatible-pointer-types]
18528 |      if (!(!atomic_compare_exchange_weak_u16(status_adr, &expected_status, ((u16)(sync__BufferElemStat_writing))))) break;
      |                                              ^~~~~~~~~~
      |                                              |
      |                                              byteptr {aka unsigned char *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:378:68: note: expected 'short unsigned int *' but argument is of type 'byteptr' {aka 'unsigned char *'}
  378 | static inline int atomic_compare_exchange_weak_u16(unsigned short* x, unsigned short* expected, unsigned short y) {
      |                                                    ~~~~~~~~~~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18532:22: warning: passing argument 1 of 'atomic_store_u16' from incompatible pointer type [-Wincompatible-pointer-types]
18532 |     atomic_store_u16(status_adr, ((u16)(sync__BufferElemStat_written)));
      |                      ^~~~~~~~~~
      |                      |
      |                      byteptr {aka unsigned char *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:375:53: note: expected 'short unsigned int *' but argument is of type 'byteptr' {aka 'unsigned char *'}
  375 | static inline void atomic_store_u16(unsigned short* x, unsigned short y) {
      |                                     ~~~~~~~~~~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'sync__Channel_try_pop_priv':
/tmp/v/ticker.5319160554567415405.tmp.c:18587:36: warning: passing argument 1 of 'atomic_load_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18587 |    voidptr rdadr = atomic_load_ptr(&ch->read_adr);
      |                                    ^~~~~~~~~~~~~
      |                                    |
      |                                    _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:309:44: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  309 | static inline void* atomic_load_ptr(void** x) {
      |                                     ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18590:44: warning: passing argument 1 of 'atomic_compare_exchange_strong_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18590 |     if (atomic_compare_exchange_strong_ptr(&ch->read_adr, &rdadr, ((voidptr)(0)))) {
      |                                            ^~~~~~~~~~~~~
      |                                            |
      |                                            _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:318:61: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  318 | static inline int atomic_compare_exchange_strong_ptr(void** x, void** expected, void* y) {
      |                                                      ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18594:47: warning: passing argument 1 of 'atomic_compare_exchange_weak_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18594 |       if (!(!atomic_compare_exchange_weak_ptr(&ch->adr_read, &nulladr, rdadr))) break;
      |                                               ^~~~~~~~~~~~~
      |                                               |
      |                                               _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:315:59: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  315 | static inline int atomic_compare_exchange_weak_ptr(void** x, void** expected, void* y) {
      |                                                    ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18655:46: warning: passing argument 1 of 'atomic_compare_exchange_weak_u16' from incompatible pointer type [-Wincompatible-pointer-types]
18655 |      if (!(!atomic_compare_exchange_weak_u16(status_adr, &expected_status, ((u16)(sync__BufferElemStat_reading))))) break;
      |                                              ^~~~~~~~~~
      |                                              |
      |                                              byteptr {aka unsigned char *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:378:68: note: expected 'short unsigned int *' but argument is of type 'byteptr' {aka 'unsigned char *'}
  378 | static inline int atomic_compare_exchange_weak_u16(unsigned short* x, unsigned short* expected, unsigned short y) {
      |                                                    ~~~~~~~~~~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18659:22: warning: passing argument 1 of 'atomic_store_u16' from incompatible pointer type [-Wincompatible-pointer-types]
18659 |     atomic_store_u16(status_adr, ((u16)(sync__BufferElemStat_unused)));
      |                      ^~~~~~~~~~
      |                      |
      |                      byteptr {aka unsigned char *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:375:53: note: expected 'short unsigned int *' but argument is of type 'byteptr' {aka 'unsigned char *'}
  375 | static inline void atomic_store_u16(unsigned short* x, unsigned short y) {
      |                                     ~~~~~~~~~~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18674:20: warning: passing argument 1 of 'atomic_store_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18674 |   atomic_store_ptr(&ch->write_adr, dest);
      |                    ^~~~~~~~~~~~~~
      |                    |
      |                    _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:312:44: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  312 | static inline void atomic_store_ptr(void** x, void* y) {
      |                                     ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18676:36: warning: passing argument 1 of 'atomic_load_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18676 |    voidptr rdadr = atomic_load_ptr(&ch->read_adr);
      |                                    ^~~~~~~~~~~~~
      |                                    |
      |                                    _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:309:44: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  309 | static inline void* atomic_load_ptr(void** x) {
      |                                     ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18679:44: warning: passing argument 1 of 'atomic_compare_exchange_strong_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18679 |     if (atomic_compare_exchange_strong_ptr(&ch->write_adr, &dest2, ((voidptr)(0)))) {
      |                                            ^~~~~~~~~~~~~~
      |                                            |
      |                                            _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:318:61: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  318 | static inline int atomic_compare_exchange_strong_ptr(void** x, void** expected, void* y) {
      |                                                      ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18700:43: warning: passing argument 1 of 'atomic_compare_exchange_strong_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18700 |    if (atomic_compare_exchange_strong_ptr(&ch->adr_written, &dest2, ((voidptr)(0)))) {
      |                                           ^~~~~~~~~~~~~~~~
      |                                           |
      |                                           _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:318:61: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  318 | static inline int atomic_compare_exchange_strong_ptr(void** x, void** expected, void* y) {
      |                                                      ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18722:59: warning: passing argument 1 of 'atomic_compare_exchange_strong_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18722 |    if (have_swapped || atomic_compare_exchange_strong_ptr(&ch->adr_written, &dest2, ((voidptr)(0)))) {
      |                                                           ^~~~~~~~~~~~~~~~
      |                                                           |
      |                                                           _Atomic atomic_uintptr_t * {aka _Atomic long unsigned int *}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:318:61: note: expected 'void **' but argument is of type '_Atomic atomic_uintptr_t *' {aka '_Atomic long unsigned int *'}
  318 | static inline int atomic_compare_exchange_strong_ptr(void** x, void** expected, void* y) {
      |                                                      ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'sync__channel_select':
/tmp/v/ticker.5319160554567415405.tmp.c:18789:92: warning: passing argument 1 of 'atomic_exchange_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18789 |     (*(sync__Subscription*)/*ee elem_typ */array_get(subscr, i)).nxt = atomic_exchange_ptr(&ch->write_subscriber, &(*(sync__Subscription*)/*ee elem_typ */array_get(subscr, i)));
      |                                                                                            ^~~~~~~~~~~~~~~~~~~~~
      |                                                                                            |
      |                                                                                            sync__Subscription ** {aka struct sync__Subscription **}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:321:48: note: expected 'void **' but argument is of type 'sync__Subscription **' {aka 'struct sync__Subscription **'}
  321 | static inline void* atomic_exchange_ptr(void** x, void* y) {
      |                                         ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c:18803:92: warning: passing argument 1 of 'atomic_exchange_ptr' from incompatible pointer type [-Wincompatible-pointer-types]
18803 |     (*(sync__Subscription*)/*ee elem_typ */array_get(subscr, i)).nxt = atomic_exchange_ptr(&ch->read_subscriber, &(*(sync__Subscription*)/*ee elem_typ */array_get(subscr, i)));
      |                                                                                            ^~~~~~~~~~~~~~~~~~~~
      |                                                                                            |
      |                                                                                            sync__Subscription ** {aka struct sync__Subscription **}
In file included from /tmp/v/ticker.5319160554567415405.tmp.c:926:
/home/void/code/vlang/v/thirdparty/stdatomic/nix/atomic.h:321:48: note: expected 'void **' but argument is of type 'sync__Subscription **' {aka 'struct sync__Subscription **'}
  321 | static inline void* atomic_exchange_ptr(void** x, void* y) {
      |                                         ~~~~~~~^
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'x__websocket__Client_parse_frame_header':
/tmp/v/ticker.5319160554567415405.tmp.c:19982:35: warning: left shift count >= width of type [-Wshift-count-overflow]
19982 |    frame.payload_len |= buffer[2] << 56;
      |                                   ^~
/tmp/v/ticker.5319160554567415405.tmp.c:19983:35: warning: left shift count >= width of type [-Wshift-count-overflow]
19983 |    frame.payload_len |= buffer[3] << 48;
      |                                   ^~
/tmp/v/ticker.5319160554567415405.tmp.c:19984:35: warning: left shift count >= width of type [-Wshift-count-overflow]
19984 |    frame.payload_len |= buffer[4] << 40;
      |                                   ^~
/tmp/v/ticker.5319160554567415405.tmp.c:19985:35: warning: left shift count >= width of type [-Wshift-count-overflow]
19985 |    frame.payload_len |= buffer[5] << 32;
      |                                   ^~
/tmp/v/ticker.5319160554567415405.tmp.c: In function 'x__websocket__Server_setup_callbacks':
/tmp/v/ticker.5319160554567415405.tmp.c:20880:49: warning: passing argument 2 of 'x__websocket__Client_on_close_ref' from incompatible pointer type [-Wincompatible-pointer-types]
20880 |  x__websocket__Client_on_close_ref(sc->client,  anon_4569_57_7_18_121_16777217, sc);
      |                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                                 |
      |                                                 Option_void (*)(x__websocket__Client *, int,  string,  x__websocket__ServerClient *) {aka struct Option_void (*)(struct x__websocket__Client *, int,  struct string,  struct x__websocket__ServerClient *)}
/tmp/v/ticker.5319160554567415405.tmp.c:19245:95: note: expected 'x__websocket__SocketCloseFn2' {aka 'struct Option_void (*)(struct x__websocket__Client *, int,  struct string,  void *)'} but argument is of type 'Option_void (*)(x__websocket__Client *, int,  string,  x__websocket__ServerClient *)' {aka 'struct Option_void (*)(struct x__websocket__Client *, int,  struct string,  struct x__websocket__ServerClient *)'}
19245 | void x__websocket__Client_on_close_ref(x__websocket__Client* ws, x__websocket__SocketCloseFn2 fun, voidptr ref) {
      |                                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
/bin/ld: /tmp/ccZcw9o3.o: in function `anon_1853_57_61_16777217':
/tmp/v/ticker.5319160554567415405.tmp.c:3645: undefined reference to `json__decode_main__Trade'
collect2: error: ld returned 1 exit status
x/atomic.h:3

Here's the full script.

module main

import os
import x.websocket
import json
import strconv

struct Trade {
    eventtype    string  [json: e]
    tradenumber  int     [json: E]
    symbol       string  [json: s]
    unixtime     int     [json: t]
    price        string  [json: p]
    quantity     string  [json: q]
    bid          int     [json: b]
    ask          int     [json: a]
    timeagain    int     [json: T]
    maker        bool    [json: m]
    taker        bool    [json: M]
}

fn main() {
    go start_client()
    os.get_line()
}

fn start_client() ? {
    mut ws := websocket.new_client('wss://stream.binance.com:9443/ws/btcusdt@trade')?
    ws.on_open(fn (mut ws websocket.Client) ? {
        println('open!')
    })
    ws.on_error(fn (mut ws websocket.Client, err string) ? {
        println('error: $err')
    })
    ws.on_close(fn (mut ws websocket.Client, code int, reason string) ? {
        println('closed')
    })
    //tr := '{"e":"trade", "E":1608790644305, "s":"BTCUSDT", "t":523514730, "p":"23011.82000000", "q":"0.00590000", "b":4006258168, "a":4006258331, "T":1608790644304, "m":true, "M":true}'
    //dumbtrade := json.decode(Trade, tr) or { return }
    ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? {
        if msg.payload.len > 0 {
            message := msg.payload.bytestr()
            message_decoded := json.decode(Trade, message) or { eprintln('json trade decode failed') return }
            price := strconv.atof64(message_decoded.price)
            mut f := os.create('/tmp/btc') or { panic(err) }
            f.writeln("${price:5.2f}\n")
            f.flush()
            f.close()
        }
    })

    ws.connect() or {
        println('error on connect: $err')
    }
    ws.listen() or {
        println('error on listen $err')
    }
    ws.close(1000, 'normal') or {
        println('panicing $err')
    }
    unsafe {
        ws.free()
    }
    println('exiting')
}
Dialga commented 3 years ago

With this change:

      1 diff --git a/i7531.v b/i7531.1.v
      2 index 3da898ffa..5cda819b3 100644
      3 --- a/i7531.v
      4 +++ b/i7531.1.v
      5 @@ -1,5 +1,5 @@
      6  import os
      7 -import x.websocket
      8 +import net.websocket
      9  import json
     10  import strconv
     11
     12 @@ -41,7 +41,7 @@ fn start_client() ? {
     13                         message_decoded := json.decode(Trade, message) or { eprintln('json trade decode failed') return }
     14                         price := strconv.atof64(message_decoded.price)
     15              mut f := os.create('/tmp/btc') or { panic(err) }
     16 -                       f.writeln("${price:5.2f}\n")
     17 +                       f.writeln("${price:5.2f}\n") ?
     18                         f.flush()
     19              f.close()
     20                 }

Your script seems to work now.

$ v run i7531.v
2021-09-23 07:11:58 [INFO ] connecting to host wss://stream.binance.com:9443/ws/btcusdt@trade
2021-09-23 07:11:59 [INFO ] successfully connected to host wss://stream.binance.com:9443/ws/btcusdt@trade
open!
2021-09-23 07:11:59 [INFO ] Starting client listener, server(false)...