v.gen.c: free `indents` in autogenerated .str() methods
parent
d820f2da6f
commit
f9c4365dc7
|
@ -17,6 +17,9 @@ pub fn new_builder(initial_size int) Builder {
|
|||
// write_ptr writes `len` bytes provided byteptr to the accumulated buffer
|
||||
[unsafe]
|
||||
pub fn (mut b Builder) write_ptr(ptr &byte, len int) {
|
||||
if len == 0 {
|
||||
return
|
||||
}
|
||||
unsafe { b.push_many(ptr, len) }
|
||||
}
|
||||
|
||||
|
@ -27,6 +30,9 @@ pub fn (mut b Builder) write_b(data byte) {
|
|||
|
||||
// write implements the Writer interface
|
||||
pub fn (mut b Builder) write(data []byte) ?int {
|
||||
if data.len == 0 {
|
||||
return 0
|
||||
}
|
||||
b << data
|
||||
return data.len
|
||||
}
|
||||
|
@ -85,7 +91,9 @@ pub fn (mut b Builder) writeln(s string) {
|
|||
// for c in s {
|
||||
// b.buf << c
|
||||
// }
|
||||
unsafe { b.push_many(s.str, s.len) }
|
||||
if s.len > 0 {
|
||||
unsafe { b.push_many(s.str, s.len) }
|
||||
}
|
||||
// b.buf << []byte(s) // TODO
|
||||
b << byte(`\n`)
|
||||
}
|
||||
|
|
|
@ -231,17 +231,16 @@ fn (mut g Gen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string
|
|||
g.auto_str_funcs.writeln('static string ${str_fn_name}($styp it) { return indent_${str_fn_name}(it, 0); }')
|
||||
g.type_definitions.writeln('static string indent_${str_fn_name}($styp it, int indent_count); // auto')
|
||||
g.auto_str_funcs.writeln('static string indent_${str_fn_name}($styp it, int indent_count) {')
|
||||
g.auto_str_funcs.writeln('\tstring indents = _SLIT("");')
|
||||
g.auto_str_funcs.writeln('\tfor (int i = 0; i < indent_count; ++i) {')
|
||||
g.auto_str_funcs.writeln('\t\tindents = string__plus(indents, _SLIT(" "));')
|
||||
g.auto_str_funcs.writeln('\t}')
|
||||
|
||||
g.auto_str_funcs.writeln('\treturn str_intp(3, _MOV((StrIntpData[]){
|
||||
g.auto_str_funcs.writeln('\tstring indents = string_repeat(_SLIT(" "), indent_count);')
|
||||
g.auto_str_funcs.writeln('\tstring tmp_ds = ${parent_str_fn_name}(it);')
|
||||
g.auto_str_funcs.writeln('\tstring res = str_intp(3, _MOV((StrIntpData[]){
|
||||
{_SLIT0, $c.si_s_code, {.d_s = indents }},
|
||||
{_SLIT("${clean_type_v_type_name}("), $c.si_s_code, {.d_s = ${parent_str_fn_name}(it) }},
|
||||
{_SLIT("${clean_type_v_type_name}("), $c.si_s_code, {.d_s = tmp_ds }},
|
||||
{_SLIT(")"), 0, {.d_c = 0 }}
|
||||
}));\n')
|
||||
|
||||
}));')
|
||||
g.auto_str_funcs.writeln('\tstring_free(&indents);')
|
||||
g.auto_str_funcs.writeln('\tstring_free(&tmp_ds);')
|
||||
g.auto_str_funcs.writeln('\treturn res;')
|
||||
g.auto_str_funcs.writeln('}')
|
||||
}
|
||||
|
||||
|
|
|
@ -81,86 +81,86 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
|
|||
}
|
||||
clean_struct_v_type_name = util.strip_main_name(clean_struct_v_type_name)
|
||||
// generate ident / indent length = 4 spaces
|
||||
g.auto_str_funcs.writeln('\tstring indents = _SLIT("");')
|
||||
g.auto_str_funcs.writeln('\tfor (int i = 0; i < indent_count; ++i) {')
|
||||
g.auto_str_funcs.writeln('\t\tindents = string__plus(indents, _SLIT(" "));')
|
||||
g.auto_str_funcs.writeln('\t}')
|
||||
if info.fields.len == 0 {
|
||||
g.auto_str_funcs.write_string('\treturn _SLIT("$clean_struct_v_type_name{}");')
|
||||
} else {
|
||||
g.auto_str_funcs.write_string('\treturn str_intp( ${info.fields.len * 4 + 3}, _MOV((StrIntpData[]){\n')
|
||||
g.auto_str_funcs.write_string('\t\t{_SLIT("$clean_struct_v_type_name{\\n"), 0, {.d_c=0}},\n')
|
||||
|
||||
for i, field in info.fields {
|
||||
mut ptr_amp := if field.typ.is_ptr() { '&' } else { '' }
|
||||
base_fmt := g.type_to_fmt1(g.unwrap_generic(field.typ))
|
||||
|
||||
// manage prefix and quote symbol for the filed
|
||||
mut quote_str := ''
|
||||
mut prefix := ''
|
||||
sym := g.table.get_type_symbol(g.unwrap_generic(field.typ))
|
||||
if sym.kind == .string {
|
||||
quote_str = "'"
|
||||
} else if field.typ in ast.charptr_types {
|
||||
quote_str = '\\"'
|
||||
prefix = 'C'
|
||||
}
|
||||
|
||||
// first fields doesn't need \n
|
||||
if i == 0 {
|
||||
g.auto_str_funcs.write_string('\t\t{_SLIT0, $si_s_code, {.d_s=indents}}, {_SLIT(" $field.name: $ptr_amp$prefix"), 0, {.d_c=0}}, ')
|
||||
} else {
|
||||
g.auto_str_funcs.write_string('\t\t{_SLIT("\\n"), $si_s_code, {.d_s=indents}}, {_SLIT(" $field.name: $ptr_amp$prefix"), 0, {.d_c=0}}, ')
|
||||
}
|
||||
|
||||
// custom methods management
|
||||
has_custom_str := sym.has_method('str')
|
||||
mut field_styp := g.typ(field.typ).replace('*', '')
|
||||
field_styp_fn_name := if has_custom_str {
|
||||
'${field_styp}_str'
|
||||
} else {
|
||||
fnames2strfunc[field_styp]
|
||||
}
|
||||
|
||||
// manage the fact hat with float we use always the g representation
|
||||
if sym.kind !in [.f32, .f64] {
|
||||
g.auto_str_funcs.write_string('{_SLIT("$quote_str"), ${int(base_fmt)}, {.${data_str(base_fmt)}=')
|
||||
} else {
|
||||
g_fmt := '0x' + (u32(base_fmt) | u32(0x7F) << 9).hex()
|
||||
g.auto_str_funcs.write_string('{_SLIT("$quote_str"), $g_fmt, {.${data_str(base_fmt)}=')
|
||||
}
|
||||
|
||||
mut func := struct_auto_str_func1(sym, field.typ, field_styp_fn_name, field.name)
|
||||
|
||||
// manage reference types can be "nil"
|
||||
if field.typ.is_ptr() && !(field.typ in ast.charptr_types
|
||||
|| field.typ in ast.byteptr_types
|
||||
|| field.typ == ast.voidptr_type_idx) {
|
||||
g.auto_str_funcs.write_string('isnil(it.${c_name(field.name)})')
|
||||
g.auto_str_funcs.write_string(' ? _SLIT("nil") : ')
|
||||
// struct, floats and ints have a special case through the _str function
|
||||
if sym.kind != .struct_ && !field.typ.is_int_valptr()
|
||||
&& !field.typ.is_float_valptr() {
|
||||
g.auto_str_funcs.write_string('*')
|
||||
}
|
||||
}
|
||||
// handle circular ref type of struct to the struct itself
|
||||
if styp == field_styp {
|
||||
g.auto_str_funcs.write_string('_SLIT("<circular>")')
|
||||
} else {
|
||||
// manage C charptr
|
||||
if field.typ in ast.charptr_types {
|
||||
g.auto_str_funcs.write_string('tos2((byteptr)$func)')
|
||||
} else {
|
||||
g.auto_str_funcs.write_string(func)
|
||||
}
|
||||
}
|
||||
|
||||
g.auto_str_funcs.write_string('}}, {_SLIT("$quote_str"), 0, {.d_c=0}},\n')
|
||||
}
|
||||
g.auto_str_funcs.write_string('\t\t{_SLIT("\\n"), $si_s_code, {.d_s=indents}}, {_SLIT("}"), 0, {.d_c=0}},\n')
|
||||
g.auto_str_funcs.write_string('\t}));\n')
|
||||
g.auto_str_funcs.writeln('\treturn _SLIT("$clean_struct_v_type_name{}");')
|
||||
g.auto_str_funcs.writeln('}')
|
||||
g.auto_str_funcs.writeln('')
|
||||
return
|
||||
}
|
||||
|
||||
g.auto_str_funcs.writeln('\tstring indents = string_repeat(_SLIT(" "), indent_count);')
|
||||
g.auto_str_funcs.writeln('\tstring res = str_intp( ${info.fields.len * 4 + 3}, _MOV((StrIntpData[]){')
|
||||
g.auto_str_funcs.writeln('\t\t{_SLIT("$clean_struct_v_type_name{\\n"), 0, {.d_c=0}},')
|
||||
|
||||
for i, field in info.fields {
|
||||
mut ptr_amp := if field.typ.is_ptr() { '&' } else { '' }
|
||||
base_fmt := g.type_to_fmt1(g.unwrap_generic(field.typ))
|
||||
|
||||
// manage prefix and quote symbol for the filed
|
||||
mut quote_str := ''
|
||||
mut prefix := ''
|
||||
sym := g.table.get_type_symbol(g.unwrap_generic(field.typ))
|
||||
if sym.kind == .string {
|
||||
quote_str = "'"
|
||||
} else if field.typ in ast.charptr_types {
|
||||
quote_str = '\\"'
|
||||
prefix = 'C'
|
||||
}
|
||||
|
||||
// first fields doesn't need \n
|
||||
if i == 0 {
|
||||
g.auto_str_funcs.write_string('\t\t{_SLIT0, $si_s_code, {.d_s=indents}}, {_SLIT(" $field.name: $ptr_amp$prefix"), 0, {.d_c=0}}, ')
|
||||
} else {
|
||||
g.auto_str_funcs.write_string('\t\t{_SLIT("\\n"), $si_s_code, {.d_s=indents}}, {_SLIT(" $field.name: $ptr_amp$prefix"), 0, {.d_c=0}}, ')
|
||||
}
|
||||
|
||||
// custom methods management
|
||||
has_custom_str := sym.has_method('str')
|
||||
mut field_styp := g.typ(field.typ).replace('*', '')
|
||||
field_styp_fn_name := if has_custom_str {
|
||||
'${field_styp}_str'
|
||||
} else {
|
||||
fnames2strfunc[field_styp]
|
||||
}
|
||||
|
||||
// manage the fact hat with float we use always the g representation
|
||||
if sym.kind !in [.f32, .f64] {
|
||||
g.auto_str_funcs.write_string('{_SLIT("$quote_str"), ${int(base_fmt)}, {.${data_str(base_fmt)}=')
|
||||
} else {
|
||||
g_fmt := '0x' + (u32(base_fmt) | u32(0x7F) << 9).hex()
|
||||
g.auto_str_funcs.write_string('{_SLIT("$quote_str"), $g_fmt, {.${data_str(base_fmt)}=')
|
||||
}
|
||||
|
||||
mut func := struct_auto_str_func1(sym, field.typ, field_styp_fn_name, field.name)
|
||||
|
||||
// manage reference types can be "nil"
|
||||
if field.typ.is_ptr() && !(field.typ in ast.charptr_types
|
||||
|| field.typ in ast.byteptr_types || field.typ == ast.voidptr_type_idx) {
|
||||
g.auto_str_funcs.write_string('isnil(it.${c_name(field.name)})')
|
||||
g.auto_str_funcs.write_string(' ? _SLIT("nil") : ')
|
||||
// struct, floats and ints have a special case through the _str function
|
||||
if sym.kind != .struct_ && !field.typ.is_int_valptr() && !field.typ.is_float_valptr() {
|
||||
g.auto_str_funcs.write_string('*')
|
||||
}
|
||||
}
|
||||
// handle circular ref type of struct to the struct itself
|
||||
if styp == field_styp {
|
||||
g.auto_str_funcs.write_string('_SLIT("<circular>")')
|
||||
} else {
|
||||
// manage C charptr
|
||||
if field.typ in ast.charptr_types {
|
||||
g.auto_str_funcs.write_string('tos2((byteptr)$func)')
|
||||
} else {
|
||||
g.auto_str_funcs.write_string(func)
|
||||
}
|
||||
}
|
||||
|
||||
g.auto_str_funcs.writeln('}}, {_SLIT("$quote_str"), 0, {.d_c=0}},')
|
||||
}
|
||||
g.auto_str_funcs.writeln('\t\t{_SLIT("\\n"), $si_s_code, {.d_s=indents}}, {_SLIT("}"), 0, {.d_c=0}},')
|
||||
g.auto_str_funcs.writeln('\t}));')
|
||||
g.auto_str_funcs.writeln('\tstring_free(&indents);')
|
||||
g.auto_str_funcs.writeln('\treturn res;')
|
||||
g.auto_str_funcs.writeln('}')
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue