freestanding: ptr_str, string concat, struct declaration
* compiler: extract c_common_macros from c_headers, and use it in bare_c_headers too. Support for ptr_str and string concatenation in -freestanding mode. * Add tests for structs and string concatenation in -freestanding mode . * Move check_string_add_works to string/string.v .pull/3119/head
							parent
							
								
									dadf147382
								
							
						
					
					
						commit
						b7c477cc18
					
				| 
						 | 
				
			
			@ -1 +1,5 @@
 | 
			
		|||
checks
 | 
			
		||||
linuxsys/linuxsys
 | 
			
		||||
string/string
 | 
			
		||||
consts/consts
 | 
			
		||||
structs/structs
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,7 @@ fn main() {
 | 
			
		|||
	vcheck("linuxsys")
 | 
			
		||||
	vcheck("string")
 | 
			
		||||
	vcheck("consts")
 | 
			
		||||
	vcheck("structs")
 | 
			
		||||
	exit(0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,12 +39,24 @@ fn check_str_clone() {
 | 
			
		|||
	assert c == "-6789"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn check_string_add_works(){
 | 
			
		||||
  abc := 'abc'
 | 
			
		||||
  combined := 'a' + 'b' + 'c'
 | 
			
		||||
  assert abc.len == combined.len
 | 
			
		||||
  assert abc[0] == combined[0]
 | 
			
		||||
  assert abc[1] == combined[1]
 | 
			
		||||
  assert abc[2] == combined[2]
 | 
			
		||||
  assert abc[0] == `a`
 | 
			
		||||
  assert abc == combined
 | 
			
		||||
}  
 | 
			
		||||
 | 
			
		||||
fn main () {
 | 
			
		||||
	mut fails := 0
 | 
			
		||||
	fails += forkedtest.normal_run(check_string_eq, "check_string_eq")
 | 
			
		||||
	fails += forkedtest.normal_run(check_i64_tos, "check_i64_tos")
 | 
			
		||||
	fails += forkedtest.normal_run(check_i64_str, "check_i64_str")
 | 
			
		||||
	fails += forkedtest.normal_run(check_str_clone, "check_str_clone")
 | 
			
		||||
	fails += forkedtest.normal_run(check_string_add_works,    "check_string_add_works")
 | 
			
		||||
	assert fails == 0
 | 
			
		||||
	sys_exit(0)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
module main
 | 
			
		||||
import forkedtest
 | 
			
		||||
 | 
			
		||||
struct SimpleEmptyStruct{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct NonEmptyStruct{
 | 
			
		||||
  x int
 | 
			
		||||
  y int
 | 
			
		||||
  z int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn check_simple_empty_struct(){  
 | 
			
		||||
  s := SimpleEmptyStruct{}
 | 
			
		||||
  addr_s := &s
 | 
			
		||||
  str_addr_s := ptr_str( addr_s )
 | 
			
		||||
  assert !isnil(addr_s)
 | 
			
		||||
  assert str_addr_s.len > 3
 | 
			
		||||
  println(str_addr_s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn check_non_empty_struct(){  
 | 
			
		||||
  a := NonEmptyStruct{1,2,3}
 | 
			
		||||
  b := NonEmptyStruct{4,5,6}
 | 
			
		||||
  assert sizeof(NonEmptyStruct) > 0
 | 
			
		||||
  assert sizeof(SimpleEmptyStruct) < sizeof(NonEmptyStruct)
 | 
			
		||||
  assert a.x == 1
 | 
			
		||||
  assert a.y == 2
 | 
			
		||||
  assert a.z == 3
 | 
			
		||||
  assert b.x + b.y + b.z == 15
 | 
			
		||||
  assert ptr_str(&a) != ptr_str(&b)
 | 
			
		||||
  println('sizeof SimpleEmptyStruct:' + i64_str( sizeof(SimpleEmptyStruct) , 10 ))
 | 
			
		||||
  println('sizeof NonEmptyStruct:' + i64_str( sizeof(NonEmptyStruct) , 10 ))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main(){
 | 
			
		||||
	mut fails := 0
 | 
			
		||||
	fails += forkedtest.normal_run(check_simple_empty_struct, "check_simple_empty_struct")
 | 
			
		||||
	fails += forkedtest.normal_run(check_non_empty_struct,    "check_non_empty_struct")
 | 
			
		||||
	assert fails == 0
 | 
			
		||||
	sys_exit(0)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +22,22 @@ pub fn tos(s byteptr, len int) string {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (s string) add(a string) string {
 | 
			
		||||
	new_len := a.len + s.len
 | 
			
		||||
	mut res := string {
 | 
			
		||||
		len: new_len
 | 
			
		||||
		str: malloc(new_len + 1)
 | 
			
		||||
	}
 | 
			
		||||
	for j := 0; j < s.len; j++ {
 | 
			
		||||
		res[j] = s[j]
 | 
			
		||||
	}
 | 
			
		||||
	for j := 0; j < a.len; j++ {
 | 
			
		||||
		res[s.len + j] = a[j]
 | 
			
		||||
	}
 | 
			
		||||
	res[new_len] = `\0`// V strings are not null terminated, but just in case
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
pub fn tos_clone(s byteptr) string {
 | 
			
		||||
	if s == 0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +116,13 @@ pub fn i64_str(n0 i64, base int) string {
 | 
			
		|||
	return i64_tos(buf, 79, n0, base)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn ptr_str(ptr voidptr) string {
 | 
			
		||||
  buf := [16]byte
 | 
			
		||||
  hex := i64_tos(buf, 15, i64(ptr), 16)
 | 
			
		||||
  res := '0x' + hex
 | 
			
		||||
  return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn (a string) clone() string {
 | 
			
		||||
	mut b := string {
 | 
			
		||||
		len: a.len
 | 
			
		||||
| 
						 | 
				
			
			@ -109,3 +132,4 @@ pub fn (a string) clone() string {
 | 
			
		|||
	b[a.len] = `\0`
 | 
			
		||||
	return b
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,28 @@ module compiler
 | 
			
		|||
 | 
			
		||||
const (
 | 
			
		||||
 | 
			
		||||
c_common_macros = '
 | 
			
		||||
 | 
			
		||||
#define EMPTY_STRUCT_DECLARATION
 | 
			
		||||
#define EMPTY_STRUCT_INITIALIZATION 0
 | 
			
		||||
// Due to a tcc bug, the length of an array needs to be specified, but GCC crashes if it is...
 | 
			
		||||
#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[])
 | 
			
		||||
#define TCCSKIP(x) x
 | 
			
		||||
 | 
			
		||||
#ifdef __TINYC__
 | 
			
		||||
#undef EMPTY_STRUCT_DECLARATION
 | 
			
		||||
#undef EMPTY_STRUCT_INITIALIZATION
 | 
			
		||||
#define EMPTY_STRUCT_DECLARATION char _dummy
 | 
			
		||||
#define EMPTY_STRUCT_INITIALIZATION 0
 | 
			
		||||
#undef EMPTY_ARRAY_OF_ELEMS
 | 
			
		||||
#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n])
 | 
			
		||||
#undef TCCSKIP
 | 
			
		||||
#define TCCSKIP(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define OPTION_CAST(x) (x)
 | 
			
		||||
'
 | 
			
		||||
 | 
			
		||||
c_headers = '
 | 
			
		||||
 | 
			
		||||
//#include <inttypes.h>  // int64_t etc
 | 
			
		||||
| 
						 | 
				
			
			@ -69,24 +91,7 @@ c_headers = '
 | 
			
		|||
#include <sys/wait.h> // os__wait uses wait on nix
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define EMPTY_STRUCT_DECLARATION
 | 
			
		||||
#define EMPTY_STRUCT_INITIALIZATION 0
 | 
			
		||||
// Due to a tcc bug, the length of an array needs to be specified, but GCC crashes if it is...
 | 
			
		||||
#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[])
 | 
			
		||||
#define TCCSKIP(x) x
 | 
			
		||||
 | 
			
		||||
#ifdef __TINYC__
 | 
			
		||||
#undef EMPTY_STRUCT_DECLARATION
 | 
			
		||||
#undef EMPTY_STRUCT_INITIALIZATION
 | 
			
		||||
#define EMPTY_STRUCT_DECLARATION char _dummy
 | 
			
		||||
#define EMPTY_STRUCT_INITIALIZATION 0
 | 
			
		||||
#undef EMPTY_ARRAY_OF_ELEMS
 | 
			
		||||
#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n])
 | 
			
		||||
#undef TCCSKIP
 | 
			
		||||
#define TCCSKIP(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define OPTION_CAST(x) (x)
 | 
			
		||||
$c_common_macros 
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#define WINVER 0x0600
 | 
			
		||||
| 
						 | 
				
			
			@ -209,19 +214,7 @@ typedef map map_string;
 | 
			
		|||
 | 
			
		||||
bare_c_headers = '
 | 
			
		||||
 | 
			
		||||
#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[])
 | 
			
		||||
#define TCCSKIP(x) x
 | 
			
		||||
 | 
			
		||||
#ifdef __TINYC__
 | 
			
		||||
#undef EMPTY_ARRAY_OF_ELEMS
 | 
			
		||||
#define EMPTY_ARRAY_OF_ELEMS(x,n) (x[n])
 | 
			
		||||
#undef TCCSKIP
 | 
			
		||||
#define TCCSKIP(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EMPTY_STRUCT_INITIALIZATION
 | 
			
		||||
#define EMPTY_STRUCT_INITIALIZATION 0
 | 
			
		||||
#endif
 | 
			
		||||
$c_common_macros
 | 
			
		||||
 | 
			
		||||
#ifndef exit
 | 
			
		||||
#define exit(rc) sys_exit(rc)
 | 
			
		||||
| 
						 | 
				
			
			@ -229,3 +222,5 @@ void sys_exit (int);
 | 
			
		|||
#endif
 | 
			
		||||
'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue