bool parse_format_string( const exprt &format_arg, format_token_listt &token_list) { token_list.clear(); if(format_arg.id()==ID_string_constant) { const std::string &arg_string = id2string(format_arg.get(ID_value)); std::string::const_iterator it=arg_string.begin(); while(it!=arg_string.end()) { if(*it=='%') { token_list.push_back(format_tokent()); format_tokent &curtok=token_list.back(); it++; parse_flags(it, curtok); parse_field_width(it, curtok); parse_precision(it, curtok); parse_length_modifier(it, curtok); parse_conversion_specifier(arg_string, it, curtok); } else { if(token_list.back().type!=format_tokent::TEXT) token_list.push_back(format_tokent(format_tokent::TEXT)); std::string tmp; for(;it!=arg_string.end() && *it!='%';it++) tmp+=*it; token_list.back().value=tmp; } } return true; } return false; // non-const format string }
format_token_listt parse_format_string(const std::string &arg_string) { format_token_listt token_list; std::string::const_iterator it=arg_string.begin(); while(it!=arg_string.end()) { if(*it=='%') { token_list.push_back(format_tokent()); format_tokent &curtok=token_list.back(); it++; parse_flags(it, curtok); parse_field_width(it, curtok); parse_precision(it, curtok); parse_length_modifier(it, curtok); parse_conversion_specifier(arg_string, it, curtok); } else { if(token_list.empty() || token_list.back().type!=format_tokent::TEXT) token_list.push_back(format_tokent(format_tokent::TEXT)); std::string tmp; for(;it!=arg_string.end() && *it!='%';it++) tmp+=*it; assert(!token_list.empty()); token_list.back().value=tmp; } } return token_list; }
/** * Signal-safe snprintf, with some limitations over snprintf. Be careful * which directives you use. */ static int vpnprintf(char *string, int size_in, const char *f, va_list args) { int f_idx = 0; int s_idx = 0; int f_len = strlen_sigsafe(f); char *string_arg; char number[21]; int p_len; int i; uint64_t ui; int64_t si; size_t size = size_in; for (; f_idx < f_len && s_idx < size - 1; f_idx++) { int length_modifier = 0; if (f[f_idx] != '%') { string[s_idx++] = f[f_idx]; continue; } f_idx++; /* silently swallow digit length modifiers */ while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.')) f_idx++; /* non-digit length modifiers */ if (f_idx < f_len) { int parsed_bytes = parse_length_modifier(&f[f_idx], f_len - f_idx, &length_modifier); if (parsed_bytes < 0) return 0; f_idx += parsed_bytes; } if (f_idx >= f_len) break; switch (f[f_idx]) { case 's': string_arg = va_arg(args, char*); p_len = strlen_sigsafe(string_arg); for (i = 0; i < p_len && s_idx < size - 1; i++) string[s_idx++] = string_arg[i]; break; case 'u': if (length_modifier & LMOD_LONGLONG) ui = va_arg(args, unsigned long long); else if (length_modifier & LMOD_LONG) ui = va_arg(args, unsigned long); else if (length_modifier & LMOD_SIZET) ui = va_arg(args, size_t); else ui = va_arg(args, unsigned); FormatUInt64(ui, number); p_len = strlen_sigsafe(number); for (i = 0; i < p_len && s_idx < size - 1; i++) string[s_idx++] = number[i]; break; case 'i': case 'd': if (length_modifier & LMOD_LONGLONG) si = va_arg(args, long long); else if (length_modifier & LMOD_LONG)