view mm7text_ru.cpp @ 2414:0673a59ec9e5

Слияние
author Ritor1
date Wed, 16 Jul 2014 18:28:23 +0600
parents aff7a7b072b7
children f4af3b203f65
line wrap: on
line source

#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "Log.h"
#include "ErrorHandling.h"


struct GenderTableEntry
{
  const char *name;
  int         gender;
} gender_table_caps[] =
{
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 2},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"-", 0},
  {"-", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 2},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 2},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 2},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 2},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 2},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 1},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 1},
  {"", 2},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 1},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0},
  {"", 0}
},
  gender_table[] =
{
  {"", 0},       {"", 1},    {"", 0},      {"", 1},      {"", 0}, {"", 0},   {"", 1},      {"", 1},   {"", 0}, {"", 0},  {"", 1},
  {"", 0},     {"", 0},      {"", 1},     {"", 0},       {"", 0},   {"", 1},     {"", 1},   {"", 0},    {"", 1},  {"", 0},     {"", 0},
  {"", 0},   {"", 0},      {"", 0},    {"", 1}, {"", 0},     {"", 0}, {"", 1},      {"", 0}, {"", 0},     {"", 1}, {"", 1},
  {"", 0}, {"", 1},    {"", 0}, {"", 1},       {"", 0},  {"", 0},    {"", 0},        {"", 0},   {"", 0},  {"", 1},     {"", 0},
  {"", 1}, {"", 0},    {"", 0},       {"", 0},       {"", 1},  {"", 1},   {"", 0}, {"", 0},   {"", 0},   {"", 0},    {"", 1},
  {"", 0},   {"", 0}, {"", 0},       {"", 0},   {"", 0},     {"", 0},  {"", 0},     {"", 0},    {"", 0},   {"", 0},   {"", 0},
  {"", 0},     {"", 2},  {"", 1},     {"", 0}
};



#include <mbstring.h>

int GetGender(char *ansi_name, int name_len)
{
  auto name = (unsigned char *)ansi_name;

  GenderTableEntry *table = nullptr;
  unsigned int      table_size = 0;
  if (name[0] >= (unsigned char)'' && name[0] <= (unsigned char)'')
  {
    table = gender_table;
    table_size = sizeof(gender_table) / sizeof(*gender_table);
  }
  else if (name[0] >= (unsigned char)'' && name[0] <= (unsigned char)'')
  {
    table = gender_table_caps;
    table_size = sizeof(gender_table_caps) / sizeof(*gender_table_caps);
  }
  else return 0;

  int left = 0,
      right = table_size - 1,
      match = 0;
  while (left < right - 1)
  {
    match = left + (right - left) / 2;
    int rval = _mbsncmp(name, (unsigned char *)table[match].name, name_len);
    if (rval < 0)
      right = match;
    else if (!rval)
      return table[match].gender;
    else
      left = match;
  }

  Log::Warning(L"sprintfex: unknown gender: %S", name);
  return 0;
}


bool IsSpecialName(const char *ansi_name)
{
  auto name = (unsigned char *)ansi_name;
  return !_mbsncmp(name, (unsigned char *)" ", 8)        || !_mbsncmp(name, (unsigned char *)" ", 6) ||
         !_mbsncmp(name, (unsigned char *)"  ", 14) || !_mbsncmp(name, (unsigned char *)" ", 12);
}
int GetSpecialGender(const char *ansi_name)
{
  auto name = (unsigned char *)ansi_name;
  if (!_mbsncmp(name, (unsigned char *)" ", 8))
    return 1;
  if (!_mbsncmp(name, (unsigned char *)" ", 6))
    return 1;
  if (!_mbsncmp(name, (unsigned char *)"  ", 14))
    return 1;
  if (!!_mbsncmp(name, (unsigned char *)" ", 12))
    return 0;
  return 0;
}
const char *GetSpecialCase(const char *ansi_name, char c)
{
  auto name = (unsigned char *)ansi_name;

  if (!_mbsncmp(name, (unsigned char *)" ", 8))
    return " ";
  if (!_mbsncmp(name, (unsigned char *)" ", 6))
    return " ";

  if (!_mbsncmp(name, (unsigned char *)"  ", 14))
    switch (c)
    {
      case 'I': case 'i': return "  ";
      case 'R': case 'r': return "  ";
      case 'D': case 'd': return "  ";
      case 'V': case 'v': return "  ";
      case 'T': case 't': return "  ";
      case 'P': case 'p': return "  ";
    }

  if (!_mbsncmp(name, (unsigned char *)" ", 12))
    switch (c)
    {
      case 'I': case 'i': return " ";
      case 'R': case 'r': return " ";
      case 'D': case 'd': return " ";
      case 'V': case 'v': return " ";
      case 'T': case 't': return " ";
      case 'P': case 'p': return " ";
    }

  return nullptr;
}

int sprintfex_internal(char *str)
{
  auto p = strstr(str, "^");
  if (!p)
    return strlen(str);

  char buf[8192];
  Assert(strlen(str) < sizeof(buf));

  int next_integer_token = 0;
  bool integer_tokens_defined[10] = {false, false, false, false, false, false, false, false, false, false};
  int integer_tokens[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

  bool gender_token_defined = false;
  int gender_token = 0;
  
  auto src = buf,
       dst = p;
  strcpy(buf, str + (p - str));
  while (true)
  {
    switch (src[1])
    {
      case 'I':
      {
        if (src[2] != '[')
          goto _invalid_token;
        src += 3;  // ^I[
        
        Assert(next_integer_token < 10);
        if (sscanf(src, "%d", &integer_tokens[next_integer_token]))
          integer_tokens_defined[next_integer_token++] = true;

        auto int_begin = src;
        while (*src++ != ']');

        int int_len = src - int_begin - 1;
        strncpy(dst, int_begin, int_len);
        dst += int_len;
      }
      break;

      case 'L':
      {
        int integer_token_idx = 0;
        if (src[2] >= '1' && src[2] <= '9')
        {
          if (src[3] != '[')
            goto _invalid_token;
          integer_token_idx = src[2] - '1';

          src += 1;
        }
        else if (src[2] != '[')
          goto _invalid_token;

        Assert(integer_tokens_defined[integer_token_idx]);
        src += 3; // ^L[

        auto ending1 = src;
        while (*src++ != ';');
        auto ending2 = src;
        while (*src++ != ';');
        auto ending3 = src;
        while (*src++ != ']');

        char *actual_ending = nullptr;
        int   actual_ending_len = 0;

        int modulo = abs(integer_tokens[integer_token_idx]) % 10;
        if (modulo == 1)
        {
          actual_ending = ending1;
          actual_ending_len = ending2 - ending1 - 1;
        }
        else if (modulo >= 2 && modulo <= 4)
        {
          actual_ending = ending2;
          actual_ending_len = ending3 - ending2 - 1;
        }
        else
        {
          actual_ending = ending3;
          actual_ending_len = src - ending3 - 1;
        }

        strncpy(dst, actual_ending, actual_ending_len);
        dst += actual_ending_len;
      }
      break;

      case 'R':
      {
        if (src[2] != '[')
          goto _invalid_token;
        Assert(gender_token_defined);

        src += 3; // ^R[

        auto ending1 = src;
        while (*src++ != ';');
        auto ending2 = src;
        while (*src++ != ';');
        auto ending3 = src;
        while (*src++ != ']');

        char *actual_ending = nullptr;
        int   actual_ending_len = 0;

        if (gender_token == 0)
        {
          actual_ending = ending1;
          actual_ending_len = ending2 - ending1 - 1;
        }
        else if (gender_token == 1)
        {
          actual_ending = ending2;
          actual_ending_len = ending3 - ending2 - 1;
        }
        else if (gender_token == 2)
        {
          actual_ending = ending3;
          actual_ending_len = src - ending3 - 1;
        }
        else Error("Invalid gender token");

        strncpy(dst, actual_ending, actual_ending_len);
        dst += actual_ending_len;
      }
      break;

      case 'P':
      {
        if (src[3] != '[')
          goto _invalid_token;
        switch (src[2])
        {
          case 'I': case 'i':
          case 'R': case 'r':
          case 'D': case 'd':
          case 'V': case 'v':
          case 'T': case 't':
          case 'P': case 'p': break;
          default:
            goto _invalid_token;
        }

        if (IsSpecialName(src + 4))
        {
          auto name = GetSpecialCase(src + 4, src[2]);
          int name_len = strlen(name);

          gender_token = GetSpecialGender(src + 4);
          gender_token_defined = true;

          strncpy(dst, name, name_len);
          dst += name_len;
          while (*src++ != ']');
          break;
        }
        
        auto name_begin = src + 4;
        int name_len = 0;
        for (int i = 0; name_begin[i] != ']'; ++i)
          name_len++;
        gender_token = GetGender(name_begin, name_len);
        gender_token_defined = true;

        switch (src[2])
        {
          case 'I': case 'i':
          case 'V': case 'v':
          case 'R': case 'r':
          case 'D': case 'd':
          case 'T': case 't':
          {
            strncpy(dst, name_begin, name_len);
            dst += name_len;
          }
          break;

          case 'P': case 'p':
          {
            auto token_begin = src;
            int token_len = 1;
            for (int i = 0; token_begin[i] != ']'; ++i)
              token_len++;
            strncpy(dst, token_begin, token_len);
            dst += token_len;
          }
        }
        while (*src++ != ']');
      }
      break;

      default:
      {
_invalid_token:
        auto token_begin = src;
        while (*src++ != ']');

        int token_len = src - token_begin;
        char token[1024];
        strncpy(token, token_begin, token_len);
        token[token_len] = 0;

        Error("Invalid format token: %s", token);
      }
      break;
    }
    
    *dst = 0;

    auto copy_begin = src;
    src = strstr(src, "^");
    if (!src)
    {
      strcpy(dst, copy_begin); // just copy the rest
      break;
    }

    int copy_len = src - copy_begin;
    strncpy(dst, copy_begin, copy_len);
    dst += copy_len;
  }

  return dst - str;
}






//mm6text.non -> c structure array
  /*FILE *f = fopen("_1.txt", "w+t");
  FILE *in = fopen("mm6text.non", "rt");
  fscanf(in, "%*[^\n]\n");

  int idx = 0;
  auto pairs = new NameGender[8000];

  char line[1024];
  while (fscanf(in, "%[^\n]\n", line) && !feof(in))
  {
    char name1[100], name2[100], name3[100];
    int e = sscanf(line, "%s\t%s\t%s", pairs[idx].name, pairs[idx + 1].name, pairs[idx + 2].name);
    pairs[idx].gender = 0;
    pairs[idx+1].gender = 1;
    pairs[idx+2].gender = 2;
    idx += e;
  }

  for (int i = 0; i < idx; ++i)
    for (int j = 0; j < i; ++j)
    {
      if (_mbsicmp(pairs[i].name, pairs[j].name) < 0)
      {
        char n[1024];
        strcpy(n, (char *)pairs[j].name);
        auto g = pairs[j].gender;

        strcpy((char *)pairs[j].name, (char *)pairs[i].name);
        pairs[j].gender = pairs[i].gender;

        strcpy((char *)pairs[i].name, n);
        pairs[i].gender = g;
      }
    }
    
  for (int i = 0; i < idx; ++i)
  {
    fprintf(f, "  {\"%s\", %u},\n", pairs[i].name, pairs[i].gender);
  }
  fclose(f);*/