@@ -34,10 +34,9 @@ int memcmp(const void* lhs, const void* rhs, size_t count)
3434 const unsigned char * p2 = (const unsigned char * )rhs ;
3535 for (size_t i = 0 ; i < count ; ++ i )
3636 {
37- if (p1 [i ] != p2 [i ])
38- {
39- return (p1 [i ] - p2 [i ]);
40- }
37+ int d = p1 [i ] - p2 [i ];
38+ if (d != 0 )
39+ return (d );
4140 }
4241 return (0 );
4342}
@@ -107,11 +106,9 @@ typedef double f64;
107106 max(x, y)
108107#define clamp (x , low , high ) \
109108 clamp_top(clamp_bot(x, low), high)
110- #define buffer (type , name ) \
109+ #define slice (type , name ) \
111110 type* name, nat name##_count
112- #define array_to_buffer (a ) \
113- a, countof(a)
114- #define string_to_buffer (s ) \
111+ #define string_slice (s ) \
115112 s, countof(s) - 1
116113#define vcall (v , c , ...) \
117114 (v)->c(v, ##__VA_ARGS__)
@@ -132,13 +129,6 @@ typedef double f64;
132129 s; \
133130 } \
134131 }
135- #define debug_assert (cond ) \
136- { \
137- if (!(cond)) \
138- { \
139- trap(); \
140- } \
141- }
142132
143133// Memory helpers
144134
@@ -180,8 +170,7 @@ nat time_tick(void)
180170 QueryPerformanceCounter (& t );
181171 nat q = t .QuadPart / f .QuadPart ;
182172 nat r = t .QuadPart % f .QuadPart ;
183- nat num = 1e9 ;
184- nat out = q * num + r * num / f .QuadPart ;
173+ nat out = q * time_second + r * time_second / f .QuadPart ;
185174 return (out );
186175}
187176
@@ -261,7 +250,9 @@ nat string_count(const char* s)
261250 return (count );
262251}
263252
264- nat string_copy (buffer (char , buf ), const char * s )
253+ #define string_copy (b , s ) \
254+ _string_copy(b, countof(b), s)
255+ nat _string_copy (slice (char , buf ), const char * s )
265256{
266257 nat count = 0 ;
267258 while (* s != 0 )
@@ -278,7 +269,9 @@ nat string_copy(buffer(char, buf), const char* s)
278269 return (count );
279270}
280271
281- nat string_append (buffer (char , buf ), const char * s )
272+ #define string_append (b , s ) \
273+ _string_append(b, countof(b), s)
274+ nat _string_append (slice (char , buf ), const char * s )
282275{
283276 nat prev_count = string_count (buf );
284277 nat count = prev_count ;
@@ -296,20 +289,22 @@ nat string_append(buffer(char, buf), const char* s)
296289 return (count - prev_count );
297290}
298291
299- char * _string_format (buffer (char , buf ), buffer (const char * , strings ))
292+ #define string_format (b , ...) \
293+ _string_format(b, countof(b), __VA_ARGS__)
294+ #define _string_format (b , c , ...) \
295+ __string_format(b, c, (const char*[]){__VA_ARGS__}, sizeof((const char*[]){__VA_ARGS__}) / sizeof(const char*))
296+ char * __string_format (slice (char , buf ), slice (const char * , strings ))
300297{
301298 buf [0 ] = 0 ;
302299 for (nat i = 0 ; i < strings_count ; i ++ )
303300 {
304301 const char * s = strings [i ];
305- nat n = string_append (buf , buf_count , s );
302+ nat n = _string_append (buf , buf_count , s );
306303 if (n < string_count (s ))
307304 break ;
308305 }
309306 return (& buf [0 ]);
310307}
311- #define string_format (b , c , ...) \
312- _string_format(b, c, (const char*[]){__VA_ARGS__}, sizeof((const char*[]){__VA_ARGS__}) / sizeof(const char*))
313308
314309// String conversion
315310
@@ -333,9 +328,8 @@ char* uchar_to_string(char (*buf)[5], uchar uc)
333328char * integer_to_string (char (* buf )[66 ], n64 x , nat base , bool is_signed , nat leading_zeroes )
334329{
335330 static const char * digits = "0123456789abcdefghijklmnopqrstuvwxyz" ;
336- debug_assert (base <= 36 );
337- debug_assert (leading_zeroes <= 64 );
338- leading_zeroes = clamp_bot (leading_zeroes , 1 );
331+ base = clamp_top (base , 36 );
332+ leading_zeroes = clamp (leading_zeroes , 1 , 64 );
339333 bool is_neg = (is_signed & (cast (i64 , x ) < 0 ));
340334 x = is_neg ? - (cast (i64 , x )) : x ;
341335 char * numbers = * buf ;
@@ -375,16 +369,27 @@ char* integer_to_string(char (*buf)[66], n64 x, nat base, bool is_signed, nat le
375369
376370// Console
377371
378- LPWSTR * _wargs ;
379- int args_count ;
372+ #define MAX_CMDLINE_LEN_UTF8 (32767 * 3)
373+
380374bool is_cli ;
375+ nat args_count ;
376+ const char * args [MAX_CMDLINE_LEN_UTF8 ];
381377
382- // NOTE: the function is not thread-safe, and argument memory gets overwritten on every call
383- char * console_get_arg (nat i )
378+ void _console_parse_arguments (void )
384379{
385- static char arg [(32767 * 3 ) + 1 ];
386- WideCharToMultiByte (CP_UTF8 , WC_ERR_INVALID_CHARS , _wargs [i ], -1 , arg , countof (arg ), null , null );
387- return (arg );
380+ static char args_global [MAX_CMDLINE_LEN_UTF8 ];
381+ nat args_position = 0 ;
382+ int wargs_count = 0 ;
383+ LPWSTR * wargs = CommandLineToArgvW (GetCommandLineW (), & wargs_count );
384+ for (int i = 0 ; i < wargs_count ; i ++ )
385+ {
386+ char arg [MAX_CMDLINE_LEN_UTF8 ];
387+ int arg_count = WideCharToMultiByte (CP_UTF8 , WC_ERR_INVALID_CHARS , wargs [i ], -1 , arg , countof (arg ), null , null );
388+ memcpy (& args_global [args_position ], arg , arg_count );
389+ args [args_count ++ ] = & args_global [args_position ];
390+ args_position += arg_count ;
391+ }
392+ LocalFree (wargs );
388393}
389394
390395void console_toggle (bool show )
@@ -395,7 +400,9 @@ void console_toggle(bool show)
395400 ShowWindow (console , show ? SW_SHOW : SW_HIDE );
396401}
397402
398- nat console_read (buffer (char , buf ))
403+ #define console_read (b ) \
404+ _console_read(b, countof(b))
405+ nat _console_read (slice (char , buf ))
399406{
400407 nat count = 0 ;
401408 WCHAR codepoint [2 ] = {0 };
@@ -415,14 +422,13 @@ nat console_read(buffer(char, buf))
415422 codepoint [1 ] = surrogate ? wchar : codepoint [1 ];
416423 uchar uc = 0 ;
417424 int size = WideCharToMultiByte (CP_UTF8 , WC_ERR_INVALID_CHARS , codepoint , codepoint_size , cast (LPSTR , & uc ), sizeof (uc ), null , null );
418- debug_assert (size > 0 ); // unicode conversion bug
419425 if (buf_count - count < size + 1 )
420426 break ;
421427 memcpy (& buf [count ], & uc , size );
422428 count += size ;
423429 codepoint [0 ] = 0 ;
424430 }
425- count -= (count > 0 ) & (buf [count - 1 ] == '\r' ) ? 1 : 0 ;
431+ count -= (( count > 0 ) & (buf [count - 1 ] == '\r' ) ) ? 1 : 0 ;
426432 buf [count ] = 0 ;
427433 return (count );
428434}
@@ -437,15 +443,19 @@ void console_write_error(const char* str)
437443 WriteFile (GetStdHandle (STD_ERROR_HANDLE ), str , string_count (str ), null , null );
438444}
439445
440- void _echo (buffer (const char * , strings ))
446+ #define echo (...) \
447+ _echo((const char*[]){__VA_ARGS__}, sizeof((const char*[]){__VA_ARGS__}) / sizeof(const char*))
448+ #define echoln (...) \
449+ _echo((const char*[]){__VA_ARGS__, "\n"}, sizeof((const char*[]){__VA_ARGS__, "\n"}) / sizeof(const char*))
450+ void _echo (slice (const char * , strings ))
441451{
442452 char flush_buf [mem_page_size ] = {0 };
443453 for (nat i = 0 ; i < strings_count ; i ++ )
444454 {
445455 const char * s = strings [i ];
446456 while (true)
447457 {
448- nat n = string_append (flush_buf , countof ( flush_buf ), s );
458+ nat n = string_append (flush_buf , s );
449459 if (n == string_count (s ))
450460 break ;
451461 console_write (flush_buf );
@@ -457,14 +467,13 @@ void _echo(buffer(const char*, strings))
457467 console_write (flush_buf );
458468}
459469
460- #define echo (...) \
461- _echo((const char*[]){__VA_ARGS__}, sizeof((const char*[]){__VA_ARGS__}) / sizeof(const char*))
462- #define echoln (...) \
463- _echo((const char*[]){__VA_ARGS__, "\n"}, sizeof((const char*[]){__VA_ARGS__, "\n"}) / sizeof(const char*))
464-
465- // Assertions
470+ // Assertion
466471
467- void _hope (bool cond , const char * proc_name , buffer (const char * , strings ))
472+ #define hopeless (...) \
473+ hope(false, ##__VA_ARGS__)
474+ #define hope (c , ...) \
475+ _hope(c, __func__, (const char*[]){__VA_ARGS__}, sizeof((const char*[]){__VA_ARGS__}) / sizeof(const char*))
476+ void _hope (bool cond , const char * proc_name , slice (const char * , strings ))
468477{
469478 if (cond )
470479 return ;
@@ -475,7 +484,7 @@ void _hope(bool cond, const char* proc_name, buffer(const char*, strings))
475484 const char * s = strings [i ];
476485 while (true)
477486 {
478- nat n = string_append (flush_buf , countof ( flush_buf ), s );
487+ nat n = string_append (flush_buf , s );
479488 if (n == string_count (s ))
480489 break ;
481490 console_write_error (flush_buf );
@@ -488,11 +497,6 @@ void _hope(bool cond, const char* proc_name, buffer(const char*, strings))
488497 trap ();
489498}
490499
491- #define hope (c , ...) \
492- _hope(c, __func__, (const char*[]){__VA_ARGS__}, sizeof((const char*[]){__VA_ARGS__}) / sizeof(const char*))
493- #define hopeless (...) \
494- hope(false, ##__VA_ARGS__)
495-
496500// Embed
497501
498502struct embed
@@ -524,7 +528,7 @@ void exit(int status)
524528void enter (void )
525529{
526530 is_cli = (GetConsoleProcessList (& (DWORD ){}, 1 ) >= 2 );
527- _wargs = CommandLineToArgvW ( GetCommandLineW (), & args_count );
531+ _console_parse_arguments ( );
528532 SetConsoleOutputCP (65001 );
529533 start ();
530534 exit (0 );
0 commit comments