4coder/custom/4coder_stringf.cpp

318 lines
11 KiB
C++

/*
* Printf style operations for strings and what-not
*/
// TOP
#if !defined(FCODER_STRINGF_CPP)
#define FCODER_STRINGF_CPP
#include <stdarg.h>
#include <stdio.h>
function String_Const_u8
push_stringfv(Arena *arena, char *format, va_list args){
va_list args2;
va_copy(args2, args);
i32 size = vsnprintf(0, 0, format, args);
String_Const_u8 result = string_const_u8_push(arena, size + 1);
vsnprintf((char*)result.str, (size_t)result.size, format, args2);
result.size -= 1;
result.str[result.size] = 0;
return(result);
}
function String_Const_u8
push_stringf(Arena *arena, char *format, ...){
va_list args;
va_start(args, format);
String_Const_u8 result = push_stringfv(arena, format, args);
va_end(args);
return(result);
}
function String_Const_u8
push_u8_stringfv(Arena *arena, char *format, va_list args){
return(push_stringfv(arena, format, args));
}
function String_Const_u8
push_u8_stringf(Arena *arena, char *format, ...){
va_list args;
va_start(args, format);
String_Const_u8 result = push_stringfv(arena, format, args);
va_end(args);
return(result);
}
function void
string_list_pushfv(Arena *arena, List_String_Const_char *list, char *format, va_list args){
String_Const_u8 string = push_stringfv(arena, format, args);
if (arena->alignment < sizeof(u64)){
push_align(arena, sizeof(u64));
}
string_list_push(arena, list, SCchar(string));
}
function void
string_list_pushf(Arena *arena, List_String_Const_char *list, char *format, ...){
va_list args;
va_start(args, format);
string_list_pushfv(arena, list, format, args);
va_end(args);
}
function void
string_list_pushfv(Arena *arena, List_String_Const_u8 *list, char *format, va_list args){
String_Const_u8 string = push_u8_stringfv(arena, format, args);
if (arena->alignment < sizeof(u64)){
push_align(arena, sizeof(u64));
}
string_list_push(arena, list, string);
}
function void
string_list_pushf(Arena *arena, List_String_Const_u8 *list, char *format, ...){
va_list args;
va_start(args, format);
string_list_pushfv(arena, list, format, args);
va_end(args);
}
////////////////////////////////
// yyyy
function void
push_year_full(Arena *arena, List_String_Const_u8 *list, u32 year){
string_list_pushf(arena, list, "%u", year);
}
// yy
function void
push_year_abrev(Arena *arena, List_String_Const_u8 *list, u32 year){
string_list_pushf(arena, list, "%u", year % 100);
}
// m
function void
push_month_num(Arena *arena, List_String_Const_u8 *list, u8 mon){
string_list_pushf(arena, list, "%u", mon + 1);
}
// mm
function void
push_month_num_zeros(Arena *arena, List_String_Const_u8 *list, u8 mon){
string_list_pushf(arena, list, "%02u", mon + 1);
}
// month
function void
push_month_name(Arena *arena, List_String_Const_u8 *list, u8 mon){
string_list_push(arena, list, month_full_name[mon%12]);
}
// mon
function void
push_month_abrev(Arena *arena, List_String_Const_u8 *list, u8 mon){
string_list_push(arena, list, month_abrev_name[mon%12]);
}
// d
function void
push_day_num(Arena *arena, List_String_Const_u8 *list, u8 day){
string_list_pushf(arena, list, "%u", day + 1);
}
// dd
function void
push_day_num_zeroes(Arena *arena, List_String_Const_u8 *list, u8 day){
string_list_pushf(arena, list, "%02u", day + 1);
}
// day
function void
push_day_ord(Arena *arena, List_String_Const_u8 *list, u8 day){
string_list_push(arena, list, ordinal_numeric_name[day%100]);
}
// h24
function void
push_hour_24(Arena *arena, List_String_Const_u8 *list, u8 hour){
string_list_pushf(arena, list, "%u", hour);
}
// hh24
function void
push_hour_24_zeroes(Arena *arena, List_String_Const_u8 *list, u8 hour){
string_list_pushf(arena, list, "%02u", hour);
}
// h
function void
push_hour_12(Arena *arena, List_String_Const_u8 *list, u8 hour){
string_list_pushf(arena, list, "%u", hour%12);
}
// hh
function void
push_hour_12_zeroes(Arena *arena, List_String_Const_u8 *list, u8 hour){
string_list_pushf(arena, list, "%02u", hour%12);
}
// ampm
function void
push_hour_am_pm(Arena *arena, List_String_Const_u8 *list, u8 hour){
if (hour >= 12){
string_list_push(arena, list, string_u8_litexpr("pm"));
}
else{
string_list_push(arena, list, string_u8_litexpr("am"));
}
}
// mi
function void
push_minute(Arena *arena, List_String_Const_u8 *list, u8 min){
string_list_pushf(arena, list, "%u", min);
}
// mimi
function void
push_minute_zeroes(Arena *arena, List_String_Const_u8 *list, u8 min){
string_list_pushf(arena, list, "%02u", min);
}
// s
function void
push_second(Arena *arena, List_String_Const_u8 *list, u8 sec){
string_list_pushf(arena, list, "%u", sec);
}
// ss
function void
push_second_zeroes(Arena *arena, List_String_Const_u8 *list, u8 sec){
string_list_pushf(arena, list, "%02u", sec);
}
// ms
function void
push_millisecond_zeroes(Arena *arena, List_String_Const_u8 *list, u16 msec){
string_list_pushf(arena, list, "%03u", msec);
}
function void
date_time_format(Arena *arena, List_String_Const_u8 *list, String_Const_u8 format, Date_Time *date_time){
u8 *ptr = format.str;
u8 *end = format.str + format.size;
for (;ptr < end;){
if (character_is_alpha_numeric(*ptr)){
u8 *start = ptr;
for (;ptr < end; ptr += 1){
if (!character_is_alpha_numeric(*ptr)){
break;
}
}
String_Const_u8 field = SCu8(start, ptr);
for (; field.size > 0;){
if (string_match(string_prefix(field, 5), string_u8_litexpr("month"))){
field = string_skip(field, 5);
push_month_name(arena, list, date_time->mon);
}
else if (string_match(string_prefix(field, 4), string_u8_litexpr("yyyy"))){
field = string_skip(field, 4);
push_year_full(arena, list, date_time->year);
}
else if (string_match(string_prefix(field, 4), string_u8_litexpr("hh24"))){
field = string_skip(field, 4);
push_hour_24_zeroes(arena, list, date_time->hour);
}
else if (string_match(string_prefix(field, 4), string_u8_litexpr("ampm"))){
field = string_skip(field, 4);
push_hour_am_pm(arena, list, date_time->hour);
}
else if (string_match(string_prefix(field, 4), string_u8_litexpr("mimi"))){
field = string_skip(field, 4);
push_minute_zeroes(arena, list, date_time->min);
}
else if (string_match(string_prefix(field, 3), string_u8_litexpr("mon"))){
field = string_skip(field, 3);
push_month_abrev(arena, list, date_time->mon);
}
else if (string_match(string_prefix(field, 3), string_u8_litexpr("day"))){
field = string_skip(field, 3);
push_day_ord(arena, list, date_time->day);
}
else if (string_match(string_prefix(field, 3), string_u8_litexpr("h24"))){
field = string_skip(field, 3);
push_hour_24(arena, list, date_time->hour);
}
else if (string_match(string_prefix(field, 2), string_u8_litexpr("yy"))){
field = string_skip(field, 2);
push_year_abrev(arena, list, date_time->year);
}
else if (string_match(string_prefix(field, 2), string_u8_litexpr("mm"))){
field = string_skip(field, 2);
push_month_num_zeros(arena, list, date_time->mon);
}
else if (string_match(string_prefix(field, 2), string_u8_litexpr("dd"))){
field = string_skip(field, 2);
push_day_num_zeroes(arena, list, date_time->day);
}
else if (string_match(string_prefix(field, 2), string_u8_litexpr("hh"))){
field = string_skip(field, 2);
push_hour_12_zeroes(arena, list, date_time->hour);
}
else if (string_match(string_prefix(field, 2), string_u8_litexpr("mi"))){
field = string_skip(field, 2);
push_minute(arena, list, date_time->min);
}
else if (string_match(string_prefix(field, 2), string_u8_litexpr("ss"))){
field = string_skip(field, 2);
push_second_zeroes(arena, list, date_time->sec);
}
else if (string_match(string_prefix(field, 2), string_u8_litexpr("ms"))){
field = string_skip(field, 2);
push_millisecond_zeroes(arena, list, date_time->msec);
}
else if (string_match(string_prefix(field, 1), string_u8_litexpr("m"))){
field = string_skip(field, 1);
push_month_num(arena, list, date_time->mon);
}
else if (string_match(string_prefix(field, 1), string_u8_litexpr("d"))){
field = string_skip(field, 1);
push_day_num(arena, list, date_time->day);
}
else if (string_match(string_prefix(field, 1), string_u8_litexpr("h"))){
field = string_skip(field, 1);
push_hour_12(arena, list, date_time->hour);
}
else if (string_match(string_prefix(field, 1), string_u8_litexpr("s"))){
field = string_skip(field, 1);
push_second(arena, list, date_time->sec);
}
else{
string_list_push(arena, list, SCu8(start, ptr));
break;
}
}
}
else{
u8 *start = ptr;
for (;ptr < end; ptr += 1){
if (character_is_alpha_numeric(*ptr)){
break;
}
}
string_list_push(arena, list, SCu8(start, ptr));
}
}
}
function void
date_time_format(Arena *arena, List_String_Const_u8 *list, char *format, Date_Time *date_time){
date_time_format(arena, list, SCu8(format), date_time);
}
function String_Const_u8
date_time_format(Arena *arena, String_Const_u8 format, Date_Time *date_time){
List_String_Const_u8 list = {};
date_time_format(arena, &list, format, date_time);
return(string_list_flatten(arena, list));
}
function String_Const_u8
date_time_format(Arena *arena, char *format, Date_Time *date_time){
return(date_time_format(arena, SCu8(format), date_time));
}
#endif
// BOTTOM