char out_val[160];
concptr p;
COMMAND_CODE code;
-#ifdef JP
- char jverb_buf[128];
-#endif
int menu_line = (use_menu ? 1 : 0);
/* Get the spell, if available */
/* Build a prompt (accept all spells) */
#ifdef JP
- jverb(prompt, jverb_buf, JVERB_AND);
- (void)strnfmt(out_val, 78, "(%s^:%c-%c, '*'で一覧, ESCで中断) どの%sを%s^ますか? ", p, I2A(0), I2A(num - 1), p, jverb_buf);
+ const auto verb = conjugate_jverb(prompt, JVerbConjugationType::AND);
+ (void)strnfmt(out_val, 78, "(%s^:%c-%c, '*'で一覧, ESCで中断) どの%sを%s^ますか? ", p, I2A(0), I2A(num - 1), p, verb.data());
#else
(void)strnfmt(out_val, 78, "(%s^s %c-%c, *=List, ESC=exit) %s^ which %s? ", p, I2A(0), I2A(num - 1), prompt, p);
#endif
#include "locale/japanese.h"
#include "locale/utf-8.h"
+#include "util/enum-converter.h"
#include "util/string-processor.h"
#include "view/display-messages.h"
#include <set>
+#include <sstream>
#ifdef JP
return kana;
}
-/*! 日本語動詞活用 (打つ>打って,打ち etc)
- * JVERB_AND: 殴る,蹴る > 殴り,蹴る
- * JVERB_TO: 殴る,蹴る > 殴って蹴る
- * JVERB_OR: 殴る,蹴る > 殴ったり蹴ったり */
-static const struct jverb_table_t {
- const char *from;
- const char *to[3];
+/*!
+ * 日本語動詞活用 (打つ>打って,打ち etc)
+ * AND : 殴る,蹴る > 殴り,蹴る
+ * TO : 殴る,蹴る > 殴って蹴る
+ * OR : 殴る,蹴る > 殴ったり蹴ったり
+ */
+static constexpr struct jverb_table_t {
+ std::string_view from;
+ std::string_view to_list[3];
} jverb_table[] = {
{ "する", { "し", "して", "した" } },
{ "いる", { "いて", "いて", "いた" } },
{ "ぶ", { "び", "んで", "んだ" } },
{ "む", { "み", "んで", "んだ" } },
{ "る", { "り", "って", "った" } },
- { nullptr, { "そして", "ことにより", "ことや" } },
};
/*!
* @brief jverb_table_tに従って動詞を活用する
- * @param in 変換元文字列ポインタ
- * @param out 変換先文字列ポインタ
- * @param flag 変換種類を指定(JVERB_AND/JVERB_TO/JVERB_OR)
- * @details
+ * @param in 変換元となる原形動詞
+ * @param type 変換種類を指定(AND/TO/OR)
+ * @return 活用形の動詞
*/
-void jverb(concptr in, char *out, int flag)
+std::string conjugate_jverb(std::string_view in, JVerbConjugationType type)
{
- const struct jverb_table_t *p;
- int in_len = strlen(in);
+ std::stringstream ss;
- strcpy(out, in);
-
- for (p = jverb_table; p->from; p++) {
- int from_len = strlen(p->from);
- if (strncmp(&in[in_len - from_len], p->from, from_len) == 0) {
- strcpy(&out[in_len - from_len], p->to[flag - 1]);
- break;
+ for (const auto &[from, to_list] : jverb_table) {
+ const auto stem_length = in.length() - from.length();
+ if (in.substr(stem_length) == from) {
+ ss << in.substr(0, stem_length) << to_list[enum2i(type)];
+ return ss.str();
}
}
- if (p->from == nullptr) {
- strcpy(&out[in_len], p->to[flag - 1]);
- }
+ constexpr std::string_view conjuctions[3] = {
+ "そして",
+ "ことにより",
+ "ことや",
+ };
+
+ ss << in << conjuctions[enum2i(type)];
+ return ss.str();
}
static const std::set<std::string_view> kinsoku_list{
#ifdef JP
-constexpr int JVERB_AND = 1;
-constexpr int JVERB_TO = 2;
-constexpr int JVERB_OR = 3;
-void jverb(concptr in, char *out, int flag);
+enum class JVerbConjugationType {
+ AND = 0,
+ TO = 1,
+ OR = 2,
+};
+std::string conjugate_jverb(std::string_view in, JVerbConjugationType type);
std::string sindarin_to_kana(std::string_view sindarin);
bool is_kinsoku(std::string_view ch);
class MonsterRaceInfo;
struct lore_type {
-#ifdef JP
- char jverb_buf[64];
-#else
+#ifndef JP
bool sin;
#endif
bool nightmare;
/* XXしてYYし/XXしてYYする/XXし/XXする */
if (lore_ptr->q != nullptr) {
- jverb(lore_ptr->p, lore_ptr->jverb_buf, JVERB_TO);
+ const auto verb = conjugate_jverb(lore_ptr->p, JVerbConjugationType::TO);
+ hook_c_roff(lore_ptr->pc, verb);
} else if (attack_numbers != lore_ptr->count - 1) {
- jverb(lore_ptr->p, lore_ptr->jverb_buf, JVERB_AND);
+ const auto verb = conjugate_jverb(lore_ptr->p, JVerbConjugationType::AND);
+ hook_c_roff(lore_ptr->pc, verb);
} else {
- strcpy(lore_ptr->jverb_buf, lore_ptr->p);
+ hook_c_roff(lore_ptr->pc, lore_ptr->p);
}
- hook_c_roff(lore_ptr->pc, lore_ptr->jverb_buf);
-
if (lore_ptr->q) {
if (attack_numbers != lore_ptr->count - 1) {
- jverb(lore_ptr->q, lore_ptr->jverb_buf, JVERB_AND);
+ const auto verb = conjugate_jverb(lore_ptr->q, JVerbConjugationType::AND);
+ hook_c_roff(lore_ptr->qc, verb);
} else {
- strcpy(lore_ptr->jverb_buf, lore_ptr->q);
+ hook_c_roff(lore_ptr->qc, lore_ptr->q);
}
-
- hook_c_roff(lore_ptr->qc, lore_ptr->jverb_buf);
}
if (attack_numbers != lore_ptr->count - 1) {
for (int n = 0; n < lore_ptr->vn; n++) {
#ifdef JP
if (n != lore_ptr->vn - 1) {
- jverb(lore_ptr->vp[n], lore_ptr->jverb_buf, JVERB_AND);
- hook_c_roff(lore_ptr->color[n], lore_ptr->jverb_buf);
+ const auto verb = conjugate_jverb(lore_ptr->vp[n], JVerbConjugationType::AND);
+ hook_c_roff(lore_ptr->color[n], verb);
hooked_roff("、");
} else {
hook_c_roff(lore_ptr->color[n], lore_ptr->vp[n]);
for (int n = 0; n < lore_ptr->vn; n++) {
#ifdef JP
if (n != lore_ptr->vn - 1) {
- jverb(lore_ptr->vp[n], lore_ptr->jverb_buf, JVERB_OR);
- hook_c_roff(lore_ptr->color[n], lore_ptr->jverb_buf);
+ const auto verb = conjugate_jverb(lore_ptr->vp[n], JVerbConjugationType::OR);
+ hook_c_roff(lore_ptr->color[n], verb);
hook_c_roff(lore_ptr->color[n], "り");
hooked_roff("、");
} else {