all: string interpolation code cleaning (#10204)

pull/10215/head
penguindark 2021-05-26 08:30:08 +02:00 committed by GitHub
parent 5e26273529
commit 2dd1d3fcbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 17 additions and 491 deletions

View File

@ -637,13 +637,11 @@ pub const (
si_g64_code = '0xfe0f'
)
// replace _STR("\'%.*s\\000\'", 2, in_str)
[inline]
pub fn str_intp_sq(in_str string) string {
return 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("\'"), $si_s_code, {.d_s = $in_str}},{_SLIT("\'"), 0, {.d_c = 0 }}}))'
}
// replace _STR("\`%.*s\\000\`", 2, in_str)
[inline]
pub fn str_intp_rune(in_str string) string {
return 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("\`"), $si_s_code, {.d_s = $in_str}},{_SLIT("\`"), 0, {.d_c = 0 }}}))'
@ -660,15 +658,25 @@ pub fn str_intp_g64(in_str string) string {
}
// replace %% with the in_str
[manualfree]
pub fn str_intp_sub(base_str string, in_str string) string {
index := base_str.index('%%') or {
eprintln('No strin interpolation %% parameteres')
exit(1)
}
// return base_str[..index] + in_str + base_str[index+2..]
if index + 2 < base_str.len {
return 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("${base_str[..index]}"), $si_s_code, {.d_s = $in_str }},{_SLIT("${base_str[
index + 2..]}"), 0, {.d_c = 0}}}))'
unsafe {
st_str := base_str[..index]
if index + 2 < base_str.len {
en_str := base_str[index + 2..]
res_str := 'str_intp(2, _MOV((StrIntpData[]){{_SLIT("$st_str"), $si_s_code, {.d_s = $in_str }},{_SLIT("$en_str"), 0, {.d_c = 0}}}))'
st_str.free()
en_str.free()
return res_str
}
res2_str := 'str_intp(1, _MOV((StrIntpData[]){{_SLIT("$st_str"), $si_s_code, {.d_s = $in_str }}}))'
st_str.free()
return res2_str
}
return 'str_intp(1, _MOV((StrIntpData[]){{_SLIT("${base_str[..index]}"), $si_s_code, {.d_s = $in_str }}}))'
}

View File

@ -59,17 +59,11 @@ fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string
} else {
g.auto_str_funcs.writeln('\t\tstring x = ${str_intp_g64('it')};')
}
// g.auto_str_funcs.writeln('\t\tstring x = _STR("%g", 1, it);')
} else if sym.kind == .rune {
// Rune are managed at this level as strings
g.auto_str_funcs.writeln('\t\tstring x = str_intp(2, _MOV((StrIntpData[]){{_SLIT("\`"), $si_s_code, {.d_s = ${elem_str_fn_name}(it) }}, {_SLIT("\`"), 0, {.d_c = 0 }}}));\n')
// g.auto_str_funcs.writeln('\t\tstring x = _STR("`%.*s\\000`", 2, ${elem_str_fn_name}(it));')
} else if sym.kind == .string {
g.auto_str_funcs.writeln('\t\tstring x = str_intp(2, _MOV((StrIntpData[]){{_SLIT("\'"), $si_s_code, {.d_s = it }}, {_SLIT("\'"), 0, {.d_c = 0 }}}));\n')
// g.auto_str_funcs.writeln('\t\tstring x = _STR("\'%.*s\\000\'", 2, it);')
} else {
// There is a custom .str() method, so use it.
// NB: we need to take account of whether the user has defined
@ -146,14 +140,11 @@ fn (mut g Gen) gen_str_for_array_fixed(info ast.ArrayFixed, styp string, str_fn_
} else {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${str_intp_g64('a[i]')} );')
}
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("%g", 1, a[i]));')
} else if sym.kind == .string {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${str_intp_sq('a[i]')});')
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("\'%.*s\\000\'", 2, a[i]));')
} else if sym.kind == .rune {
tmp_str := str_intp_rune('${elem_str_fn_name}( $deref a[i])')
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, $tmp_str);')
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("`%.*s\\000`", 2, ${elem_str_fn_name}(a[i])));')
} else {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${elem_str_fn_name}( $deref a[i]));')
}

View File

@ -46,11 +46,9 @@ fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) {
}
if key_sym.kind == .string {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${str_intp_sq('key')});')
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("\'%.*s\\000\'", 2, key));')
} else if key_sym.kind == .rune {
tmp_str := str_intp_rune('${key_str_fn_name}(key)')
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, $tmp_str);')
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("`%.*s\\000`", 2, ${key_str_fn_name}(key)));')
} else {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${key_str_fn_name}(key));')
}
@ -60,7 +58,6 @@ fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) {
} else if val_sym.kind == .string {
tmp_str := str_intp_sq('*($val_styp*)DenseArray_value(&m.key_values, i)')
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, $tmp_str);')
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("\'%.*s\\000\'", 2, *($val_styp*)DenseArray_value(&m.key_values, i)));')
} else if should_use_indent_func(val_sym.kind) && !val_sym.has_method('str') {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, indent_${elem_str_fn_name}(*($val_styp*)DenseArray_value(&m.key_values, i), indent_count));')
} else if val_sym.kind in [.f32, .f64] {
@ -70,11 +67,9 @@ fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) {
} else {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${str_intp_g64(tmp_val)});')
}
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("%g", 1, *($val_styp*)DenseArray_value(&m.key_values, i)));')
} else if val_sym.kind == .rune {
tmp_str := str_intp_rune('${elem_str_fn_name}(*($val_styp*)DenseArray_value(&m.key_values, i))')
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, $tmp_str);')
// g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _STR("`%.*s\\000`", 2, ${elem_str_fn_name}(*($val_styp*)DenseArray_value(&m.key_values, i))));')
} else {
g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, ${elem_str_fn_name}(*($val_styp*)DenseArray_value(&m.key_values, i)));')
}

View File

@ -201,7 +201,6 @@ fn (mut g Gen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string)
if sym.kind == .string {
tmp_res := '${parent_str_fn_name}(*($sym.cname*)it.data)'
g.auto_str_funcs.writeln('\t\tres = ${str_intp_sq(tmp_res)};')
// g.auto_str_funcs.writeln('\t\tres = _STR("\'%.*s\\000\'", 2, ${parent_str_fn_name}(*($sym.cname*)it.data));')
} else if should_use_indent_func(sym.kind) && !sym_has_str_method {
g.auto_str_funcs.writeln('\t\tres = indent_${parent_str_fn_name}(*($sym.cname*)it.data, indent_count);')
} else {
@ -211,12 +210,9 @@ fn (mut g Gen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string)
tmp_str := str_intp_sub('error: %%', 'IError_str(it.err)')
g.auto_str_funcs.writeln('\t\tres = $tmp_str;')
// g.auto_str_funcs.writeln('\t\tres = _STR("error: %.*s\\000", 2, IError_str(it.err));')
g.auto_str_funcs.writeln('\t}')
g.auto_str_funcs.writeln('\treturn ${str_intp_sub('Option(%%)', 'res')};')
// g.auto_str_funcs.writeln('\treturn _STR("Option(%.*s\\000)", 2, res);')
g.auto_str_funcs.writeln('}')
}
@ -243,8 +239,6 @@ fn (mut g Gen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string
{_SLIT(")"), 0, {.d_c = 0 }}
}));\n')
// g.auto_str_funcs.writeln('\treturn _STR("%.*s\\000${clean_type_v_type_name}(%.*s\\000)", 3, indents, ${parent_str_fn_name}(it));')
g.auto_str_funcs.writeln('}')
}
@ -284,11 +278,9 @@ fn (mut g Gen) gen_str_for_multi_return(info ast.MultiReturn, styp string, str_f
tmp_val := str_intp_g64('a.arg$i')
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, $tmp_val);')
}
// g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, _STR("%g", 1, a.arg$i));')
} else if sym.kind == .string {
tmp_str := str_intp_sq('a.arg$i')
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, $tmp_str);')
// g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, _STR("\'%.*s\\000\'", 2, a.arg$i));')
} else if sym.kind == .function {
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, ${arg_str_fn_name}());')
} else {
@ -402,21 +394,6 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, str_fn_nam
g.auto_str_funcs.write_string('\tif (x._typ == _${styp}_${subtype.cname}_index)')
g.auto_str_funcs.write_string(' return $res;\n')
}
//------------------------------------------
/*
deref := if sym_has_str_method && str_method_expects_ptr { ' ' } else { '*' }
value_fmt := if typ == ast.string_type { "'%.*s\\000'" } else { '%.*s\\000' }
g.auto_str_funcs.write_string('\tif (x._typ == _${styp}_${subtype.cname}_index)')
g.auto_str_funcs.write_string(' return _STR("${clean_interface_v_type_name}($value_fmt)", 2, ')
g.auto_str_funcs.write_string('${func_name}(${deref}($subtype.cname*)x._$subtype.cname')
if should_use_indent_func(subtype.kind) && !sym_has_str_method {
g.auto_str_funcs.write_string(', indent_count')
}
g.auto_str_funcs.writeln('));\n')
*/
//------------------------------------------
}
g.auto_str_funcs.writeln('\treturn _SLIT("unknown interface value");')
g.auto_str_funcs.writeln('}')
@ -482,20 +459,6 @@ fn (mut g Gen) gen_str_for_union_sum_type(info ast.SumType, styp string, str_fn_
}))'
g.auto_str_funcs.write_string('\t\tcase $typ: return $res;')
}
//------------------------------------------
/*
mut value_fmt := '%.*s\\000'
if typ == ast.string_type {
value_fmt = "'$value_fmt'"
}
g.auto_str_funcs.write_string('\t\tcase $typ: return _STR("${clean_sum_type_v_type_name}($value_fmt)", 2, ${func_name}(${deref}($typ_str*)x._$sym.cname')
if should_use_indent_func(sym.kind) && !sym_has_str_method {
g.auto_str_funcs.write_string(', indent_count')
}
g.auto_str_funcs.writeln('));')
*/
//------------------------------------------
}
g.auto_str_funcs.writeln('\t\tdefault: return _SLIT("unknown sum type value");')
g.auto_str_funcs.writeln('\t}')

View File

@ -212,176 +212,3 @@ fn struct_auto_str_func1(sym &ast.TypeSymbol, field_type ast.Type, fn_name strin
return method_str
}
}
//=============================================================================
// OLD CODE
//=============================================================================
/*
fn (g &Gen) type_to_fmt(typ ast.Type) string {
if typ == ast.byte_type_idx {
return '%hhx\\000'
}
if typ == ast.char_type_idx {
return '%c\\000'
}
if typ == ast.voidptr_type_idx || typ in ast.byteptr_types {
return '%p\\000'
}
if typ in ast.charptr_types {
return '%C\\000' // a C string
}
sym := g.table.get_type_symbol(typ)
if typ.is_ptr() && (typ.is_int_valptr() || typ.is_float_valptr()) {
return '%.*s\\000'
} else if sym.kind in [.struct_, .array, .array_fixed, .map, .bool, .enum_, .interface_,
.sum_type, .function, .alias] {
return '%.*s\\000'
} else if sym.kind == .string {
return "'%.*s\\000'"
} else if sym.kind in [.f32, .f64] {
return '%g\\000' // g removes trailing zeros unlike %f
} else if sym.kind == .int {
return '%d\\000'
} else if sym.kind == .u32 {
return '%u\\000'
} else if sym.kind == .u64 {
return '%llu\\000'
} else if sym.kind == .i64 {
return '%lld\\000'
}
return '%d\\000'
}
fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name string) {
//g.gen_str_for_struct1(info, styp, str_fn_name)
// TODO: short it if possible
// generates all definitions of substructs
mut fnames2strfunc := map{
'': ''
}
for field in info.fields {
sym := g.table.get_type_symbol(field.typ)
if !sym.has_method('str') {
mut typ := field.typ
if typ.is_ptr() {
typ = typ.deref()
}
field_styp := g.typ(typ)
field_fn_name := g.gen_str_for_type(field.typ)
fnames2strfunc[field_styp] = field_fn_name
}
}
// _str() functions should have a single argument, the indenting ones take 2:
g.type_definitions.writeln('static string ${str_fn_name}($styp it); // auto')
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) {')
mut clean_struct_v_type_name := styp.replace('__', '.')
if clean_struct_v_type_name.contains('_T_') {
// TODO: this is a bit hacky. styp shouldn't be even parsed with _T_
// use something different than g.typ for styp
clean_struct_v_type_name =
clean_struct_v_type_name.replace('Array_', '[]').replace('_T_', '<').replace('_', ', ') +
'>'
}
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("$clean_struct_v_type_name{\\n"')
for field in info.fields {
mut fmt := if field.typ.is_ptr() { '&' } else { '' }
fmt += g.type_to_fmt(field.typ)
g.auto_str_funcs.writeln('\t\t"%.*s\\000 $field.name: $fmt\\n"')
}
g.auto_str_funcs.write_string('\t\t"%.*s\\000}", ${2 * (info.fields.len + 1)}')
if info.fields.len > 0 {
g.auto_str_funcs.write_string(',\n\t\t')
for i, field in info.fields {
sym := g.table.get_type_symbol(field.typ)
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]
}
g.auto_str_funcs.write_string('indents, ')
mut func := struct_auto_str_func(sym, field.typ, field_styp_fn_name, field.name)
// 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 {
g.auto_str_funcs.write_string(func)
}
if i < info.fields.len - 1 {
g.auto_str_funcs.write_string(',\n\t\t')
}
}
}
g.auto_str_funcs.writeln(',')
g.auto_str_funcs.writeln('\t\tindents);')
}
g.auto_str_funcs.writeln('}')
}
fn struct_auto_str_func(sym &ast.TypeSymbol, field_type ast.Type, fn_name string, field_name string) string {
has_custom_str, expects_ptr, _ := sym.str_method_info()
if sym.kind == .enum_ {
return '${fn_name}(it.${c_name(field_name)})'
} else if should_use_indent_func(sym.kind) {
mut obj := 'it.${c_name(field_name)}'
if field_type.is_ptr() && !expects_ptr {
obj = '*$obj'
}
if has_custom_str {
return '${fn_name}($obj)'
}
return 'indent_${fn_name}($obj, indent_count + 1)'
} else if sym.kind in [.array, .array_fixed, .map, .sum_type] {
if has_custom_str {
return '${fn_name}(it.${c_name(field_name)})'
}
return 'indent_${fn_name}(it.${c_name(field_name)}, indent_count + 1)'
} else if sym.kind == .function {
return '${fn_name}()'
} else {
mut method_str := 'it.${c_name(field_name)}'
if sym.kind == .bool {
method_str += ' ? _SLIT("true") : _SLIT("false")'
} else if (field_type.is_int_valptr() || field_type.is_float_valptr())
&& field_type.is_ptr() && !expects_ptr {
// ptr int can be "nil", so this needs to be castet to a string
fmt := if sym.kind in [.f32, .f64] {
'%g\\000'
} else if sym.kind == .u64 {
'%lld\\000'
} else {
'%d\\000'
}
method_str = '_STR("$fmt", 2, *$method_str)'
}
return method_str
}
}
*/

View File

@ -408,8 +408,6 @@ pub fn (mut g Gen) init() {
} else {
g.cheaders.writeln(c_headers)
}
// g.definitions.writeln('string _STR(const char*, int, ...);')
// g.definitions.writeln('string _STR_TMP(const char*, ...);')
}
if g.pref.os == .ios {
g.cheaders.writeln('#define __TARGET_IOS__ 1')
@ -2196,7 +2194,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
// here, not in call_expr().
// `pos := s.index('x') or { return }`
// ==========>
// Option_int _t190 = string_index(s, _STR("x"));
// Option_int _t190 = string_index(s, _STR("x")); // _STR() no more used!!
// if (_t190.state != 2) {
// Error err = _t190.err;
// return;

View File

@ -47,130 +47,9 @@ static inline void __sort_ptr(uintptr_t a[], bool b[], int l)
}
}
'
c_str_fn_defs = '' // NO _STR() test
/*
c_str_fn_defs = '
void _STR_PRINT_ARG(const char *fmt, char** refbufp, int *nbytes, int *memsize, int guess, ...) {
va_list args;
va_start(args, guess);
// NB: (*memsize - *nbytes) === how much free space is left at the end of the current buffer refbufp
// *memsize === total length of the buffer refbufp
// *nbytes === already occupied bytes of buffer refbufp
// guess === how many bytes were taken during the current vsnprintf run
for(;;) {
int remaining_space = *memsize - *nbytes;
if (guess < remaining_space) {
guess = vsnprintf(*refbufp + *nbytes, *memsize - *nbytes, fmt, args);
if (guess < remaining_space) { // result did fit into buffer
*nbytes += guess;
break;
}
}
// increase buffer (somewhat exponentially)
*memsize += guess + 3 * (*memsize) / 2;
*refbufp = (char*)v_realloc((void*)*refbufp, *memsize);
}
va_end(args);
}
// TODO: must be romved in future, no more mof use for it.
c_str_fn_defs = ''
string _STR(const char *fmt, int nfmts, ...) {
va_list argptr;
int memsize = 128;
int nbytes = 0;
char* buf = (char*)v_malloc(memsize);
va_start(argptr, nfmts);
for (int i=0; i<nfmts; ++i) {
int k = strlen(fmt);
bool is_fspec = false;
for (int j=0; j<k; ++j) {
if (fmt[j] == \'%\') {
j++;
if (fmt[j] != \'%\') {
is_fspec = true;
break;
}
}
}
if (is_fspec) {
char f = fmt[k-1];
char fup = f & 0xdf; // toupper
bool l = fmt[k-2] == \'l\';
bool ll = l && fmt[k-3] == \'l\';
if (f == \'u\' || fup == \'X\' || f == \'o\' || f == \'d\' || f == \'c\') { // int...
if (ll) _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+16, va_arg(argptr, long long));
else if (l) _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+10, va_arg(argptr, long));
else _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+8, va_arg(argptr, int));
} else if (fup >= \'E\' && fup <= \'G\') { // floating point
_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+10, va_arg(argptr, double));
} else if (f == \'p\') {
_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+14, va_arg(argptr, void*));
} else if (f == \'C\') { // a C string
char* sptr = va_arg(argptr, char*);
char* fmt_no_c = (char*)v_malloc(k+4);
memcpy(fmt_no_c, fmt, k);
fmt_no_c[k-2]=\'C\';
fmt_no_c[k-1]=\'"\';
fmt_no_c[k]=\'%\';
fmt_no_c[k+1]=\'s\';
fmt_no_c[k+2]=\'"\';
fmt_no_c[k+3]=0;
_STR_PRINT_ARG(fmt_no_c, &buf, &nbytes, &memsize, k + 4 + 100, sptr);
v_free(fmt_no_c);
} else if (f == \'s\') { // v string
string s = va_arg(argptr, string);
if (fmt[k-4] == \'*\') { // %*.*s
int fwidth = va_arg(argptr, int);
if (fwidth < 0)
fwidth -= (s.len - utf8_str_visible_length(s));
else
fwidth += (s.len - utf8_str_visible_length(s));
_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+s.len-4, fwidth, s.len, s.str);
} else { // %.*s
_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+s.len-4, s.len, s.str);
}
} else {
//v_panic(tos3(\'Invaid format specifier\'));
}
} else {
_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k);
}
fmt += k+1;
}
va_end(argptr);
buf[nbytes] = 0;
#ifdef DEBUG_ALLOC
//puts(\'_STR:\');
puts(buf);
#endif
#if _VAUTOFREE
//g_cur_str = (byteptr)buf;
#endif
return tos2((byteptr)buf);
}
string _STR_TMP(const char *fmt, ...) {
va_list argptr;
va_start(argptr, fmt);
size_t len = vsnprintf(0, 0, fmt, argptr) + 1;
va_end(argptr);
va_start(argptr, fmt);
vsprintf((char *)g_str_buf, fmt, argptr);
va_end(argptr);
#ifdef DEBUG_ALLOC
//puts(\'_STR_TMP:\');
//puts(g_str_buf);
#endif
string res = tos(g_str_buf, len);
res.is_lit = 1;
return res;
} // endof _STR_TMP
'
*/
c_common_macros = '
#define EMPTY_VARG_INITIALIZATION 0
#define EMPTY_STRUCT_DECLARATION

View File

@ -74,140 +74,6 @@ fn (mut g Gen) string_inter_literal_sb_optimized(call_expr ast.CallExpr) {
return
}
/*
fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
g.write('_STR("')
// Build the string with %
mut end_string := false
for i, val in node.vals {
mut escaped_val := val.replace_each(['%', '%%'])
escaped_val = util.smart_quote(escaped_val, false)
if i >= node.exprs.len {
if escaped_val.len > 0 {
end_string = true
g.write('\\000')
g.write(escaped_val)
}
break
}
g.write(escaped_val)
mut typ := g.unwrap_generic(node.expr_types[i])
sym := g.table.get_type_symbol(typ)
if sym.kind == .alias {
typ = (sym.info as ast.Alias).parent_type
}
// write correct format specifier to intermediate string
g.write('%')
fspec := node.fmts[i]
mut fmt := if node.pluss[i] { '+' } else { '' }
if node.fills[i] && node.fwidths[i] >= 0 {
fmt = '${fmt}0'
}
if node.fwidths[i] != 0 {
fmt = '$fmt${node.fwidths[i]}'
}
if node.precisions[i] != 987698 {
fmt = '${fmt}.${node.precisions[i]}'
}
if fspec == `s` {
if node.fwidths[i] == 0 {
g.write('.*s')
} else {
g.write('*.*s')
}
} else if typ.is_float() {
g.write('$fmt${fspec:c}')
} else if typ.is_pointer() {
if fspec == `p` {
g.write('${fmt}p')
} else {
g.write('$fmt"PRI${fspec:c}PTR"')
}
} else if typ.is_int() {
if fspec == `c` {
g.write('${fmt}c')
} else {
g.write('$fmt"PRI${fspec:c}')
if typ in [ast.i8_type, ast.byte_type] {
g.write('8')
} else if typ in [ast.i16_type, ast.u16_type] {
g.write('16')
} else if typ in [ast.i64_type, ast.u64_type] {
g.write('64')
} else {
g.write('32')
}
g.write('"')
}
} else {
// TODO: better check this case
g.write('$fmt"PRId32"')
}
if i < node.exprs.len - 1 {
g.write('\\000')
}
}
num_string_parts := if end_string { node.exprs.len + 1 } else { node.exprs.len }
g.write('", $num_string_parts, ')
// Build args
for i, expr in node.exprs {
typ := g.unwrap_generic(node.expr_types[i])
if typ == ast.string_type {
if g.inside_vweb_tmpl {
g.write('vweb__filter(')
if expr.is_auto_deref_var() {
g.write('*')
}
g.expr(expr)
g.write(')')
} else {
if expr.is_auto_deref_var() {
g.write('*')
}
g.expr(expr)
}
} else if node.fmts[i] == `s` || typ.has_flag(.variadic) {
g.gen_expr_to_string(expr, typ)
} else if typ.is_number() || typ.is_pointer() || node.fmts[i] == `d` {
if typ.is_signed() && node.fmts[i] in [`x`, `X`, `o`] {
// convert to unsigned first befors C's integer propagation strikes
if typ == ast.i8_type {
g.write('(byte)(')
} else if typ == ast.i16_type {
g.write('(u16)(')
} else if typ == ast.int_type {
g.write('(u32)(')
} else {
g.write('(u64)(')
}
if expr.is_auto_deref_var() {
g.write('*')
}
g.expr(expr)
g.write(')')
} else {
if expr.is_auto_deref_var() {
g.write('*')
}
g.expr(expr)
}
} else {
if expr.is_auto_deref_var() {
g.write('*')
}
g.expr(expr)
}
if node.fmts[i] == `s` && node.fwidths[i] != 0 {
g.write(', ${node.fwidths[i]}')
}
if i < node.exprs.len - 1 {
g.write(', ')
}
}
g.write(')')
}
*/
fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
is_shared := etype.has_flag(.shared_f)
mut typ := etype
@ -258,7 +124,6 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
str_fn_name := g.gen_str_for_type(typ)
if is_ptr && !is_var_mut {
g.write('str_intp(1, _MOV((StrIntpData[]){_SLIT("&"), $si_s_code ,{.d_s=')
// g.write('_STR("&%.*s\\000", 2, ')
}
g.write('${str_fn_name}(')
if str_method_expects_ptr && !is_ptr {